1 /*
2  * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CAMERA_NAPI_CALLBACK_PARAM_PARSER_H
17 #define CAMERA_NAPI_CALLBACK_PARAM_PARSER_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include "camera_error_code.h"
23 #include "camera_napi_const.h"
24 #include "js_native_api.h"
25 #include "napi/native_api.h"
26 
27 namespace OHOS {
28 namespace CameraStandard {
29 
30 class CameraNapiCallbackParamParser {
31 public:
32     template<typename T>
CameraNapiCallbackParamParser(napi_env env,napi_callback_info info,T * & nativeObjPointer)33     explicit CameraNapiCallbackParamParser(napi_env env, napi_callback_info info, T*& nativeObjPointer) : env_(env)
34     {
35         static const size_t CALLBACK_ARGS_MIN = 1;
36         napi_value thisVar;
37         size_t paramSize = ARGS_MAX_SIZE;
38         std::vector<napi_value> paramValue(paramSize, nullptr);
39         napiError = napi_get_cb_info(env_, info, &paramSize, paramValue.data(), &thisVar, nullptr);
40         if (napiError != napi_ok) {
41             return;
42         }
43         UnwrapThisVarToAddr(thisVar, nativeObjPointer);
44         if (napiError != napi_ok) {
45             return;
46         }
47         if (paramSize > ARGS_MAX_SIZE || paramSize < CALLBACK_ARGS_MIN) {
48             napiError = napi_status::napi_invalid_arg;
49             return;
50         }
51 
52         napi_valuetype valueNapiType = napi_undefined;
53         napi_typeof(env_, paramValue[ARGS_ZERO], &valueNapiType);
54         if (valueNapiType != napi_string) {
55             napiError = napi_status::napi_invalid_arg;
56             return;
57         }
58         if (paramSize > 1) {
59             napi_typeof(env_, paramValue[paramSize - 1], &valueNapiType);
60             if (valueNapiType != napi_function) {
61                 napiError = napi_status::napi_invalid_arg;
62                 return;
63             }
64             callbackFunction_ = paramValue[paramSize - 1];
65             if (paramSize > CALLBACK_ARGS_MIN + 1) {
66                 callbackFunctionParameters_ =
67                     std::vector<napi_value>(paramValue.begin() + 1, paramValue.begin() + paramSize - 1);
68             }
69         }
70         size_t stringSize = 0;
71         napiError = napi_get_value_string_utf8(env_, paramValue[ARGS_ZERO], nullptr, 0, &stringSize);
72         if (napiError != napi_ok) {
73             return;
74         }
75         callbackName_.resize(stringSize);
76         napiError =
77             napi_get_value_string_utf8(env_, paramValue[ARGS_ZERO], callbackName_.data(), stringSize + 1, &stringSize);
78     }
79 
AssertStatus(CameraErrorCode errorCode,const char * message)80     inline bool AssertStatus(CameraErrorCode errorCode, const char* message)
81     {
82         if (napiError != napi_ok) {
83             napi_throw_error(env_, std::to_string(errorCode).c_str(), message);
84         }
85         return napiError == napi_ok;
86     }
87 
GetCallbackName()88     inline const std::string& GetCallbackName()
89     {
90         return callbackName_;
91     }
92 
GetCallbackArgs()93     inline const std::vector<napi_value>& GetCallbackArgs()
94     {
95         return callbackFunctionParameters_;
96     }
97 
GetCallbackFunction()98     inline napi_value GetCallbackFunction()
99     {
100         return callbackFunction_;
101     }
102 
103 private:
104     template<typename T>
UnwrapThisVarToAddr(napi_value thisVar,T * & dataPointAddr)105     void UnwrapThisVarToAddr(napi_value thisVar, T*& dataPointAddr)
106     {
107         if (napiError != napi_ok) {
108             return;
109         }
110         if (thisVar == nullptr) {
111             napiError = napi_invalid_arg;
112             return;
113         }
114         napiError = napi_unwrap(env_, thisVar, reinterpret_cast<void**>(&dataPointAddr));
115         if (napiError == napi_ok && dataPointAddr == nullptr) {
116             napiError = napi_invalid_arg;
117         }
118     }
119 
120     napi_env env_ = nullptr;
121 
122     napi_status napiError = napi_status::napi_invalid_arg;
123 
124     std::string callbackName_ = "";
125     napi_value callbackFunction_ = nullptr;
126     std::vector<napi_value> callbackFunctionParameters_ {};
127 };
128 } // namespace CameraStandard
129 } // namespace OHOS
130 #endif