1 /*
2 * Copyright (C) 2021 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 CORE_SERVICE_COMMON_NAPI_NAPI_PARAMETER_UTIL_H
17 #define CORE_SERVICE_COMMON_NAPI_NAPI_PARAMETER_UTIL_H
18
19 #include <tuple>
20 #include <type_traits>
21
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24
25 namespace OHOS {
26 namespace Telephony {
27 template<typename T, std::enable_if_t<std::is_same_v<T, int32_t>, int32_t> = 0>
GetInputArgvType(T *)28 napi_valuetype GetInputArgvType(T *)
29 {
30 return napi_number;
31 }
32
33 template<typename T, std::enable_if_t<std::is_same_v<T, napi_ref>, int32_t> = 0>
GetInputArgvType(T *)34 napi_valuetype GetInputArgvType(T *)
35 {
36 return napi_function;
37 }
38
39 template<typename T, std::enable_if_t<std::is_same_v<T, char>, int32_t> = 0>
GetInputArgvType(T *)40 napi_valuetype GetInputArgvType(T *)
41 {
42 return napi_string;
43 }
44
45 template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int32_t> = 0>
GetInputArgvType(T *)46 napi_valuetype GetInputArgvType(T *)
47 {
48 return napi_string;
49 }
50
51 template<typename T, std::enable_if_t<std::is_same_v<T, napi_value>, int32_t> = 0>
GetInputArgvType(T *)52 napi_valuetype GetInputArgvType(T *)
53 {
54 return napi_object;
55 }
56
57 template<typename T, std::enable_if_t<std::is_same_v<T, int32_t>, int32_t> = 0>
NapiValueConverted(napi_env env,napi_value arg,T * val)58 napi_status NapiValueConverted(napi_env env, napi_value arg, T *val)
59 {
60 return napi_get_value_int32(env, arg, val);
61 }
62
63 template<typename T, std::enable_if_t<std::is_same_v<T, napi_ref>, int32_t> = 0>
NapiValueConverted(napi_env env,napi_value arg,T * ref)64 napi_status NapiValueConverted(napi_env env, napi_value arg, T *ref)
65 {
66 return napi_create_reference(env, arg, 1, ref);
67 }
68
69 template<typename T, std::enable_if_t<std::is_same_v<T, bool>, int32_t> = 0>
NapiValueConverted(napi_env env,napi_value arg,T * res)70 napi_status NapiValueConverted(napi_env env, napi_value arg, T *res)
71 {
72 return napi_get_value_bool(env, arg, res);
73 }
74
75 template<typename T, std::enable_if_t<std::is_same_v<T, char>, int32_t> = 0>
NapiValueConverted(napi_env env,napi_value arg,T * buf)76 napi_status NapiValueConverted(napi_env env, napi_value arg, T *buf)
77 {
78 size_t result {0};
79 constexpr size_t bufSize { 1024 };
80 return napi_get_value_string_utf8(env, arg, buf, bufSize, &result);
81 }
82
83 template<typename T, std::enable_if_t<std::is_same_v<T, napi_value>, int32_t> = 0>
NapiValueConverted(napi_env env,napi_value arg,T * npaiValue)84 napi_status NapiValueConverted(napi_env env, napi_value arg, T *npaiValue)
85 {
86 *npaiValue = arg;
87 return napi_ok;
88 }
89
90 template<typename T, std::enable_if_t<std::is_same_v<T, bool>, int32_t> = 0>
GetNapiValue(napi_env env,T val)91 napi_value GetNapiValue(napi_env env, T val)
92 {
93 napi_value result = nullptr;
94 NAPI_CALL(env, napi_get_boolean(env, val, &result));
95 return result;
96 }
97
98 template<typename T, std::enable_if_t<std::is_same_v<T, int32_t>, int32_t> = 0>
GetNapiValue(napi_env env,T val)99 napi_value GetNapiValue(napi_env env, T val)
100 {
101 napi_value result = nullptr;
102 NAPI_CALL(env, napi_create_int32(env, val, &result));
103 return result;
104 }
105
106 template<typename T, std::enable_if_t<std::is_same_v<T, int64_t>, int64_t> = 0>
GetNapiValue(napi_env env,T val)107 napi_value GetNapiValue(napi_env env, T val)
108 {
109 napi_value result = nullptr;
110 NAPI_CALL(env, napi_create_int64(env, val, &result));
111 return result;
112 }
113
114 template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int32_t> = 0>
GetNapiValue(napi_env env,const T & val)115 napi_value GetNapiValue(napi_env env, const T &val)
116 {
117 napi_value result = nullptr;
118 NAPI_CALL(env, napi_create_string_utf8(env, val.c_str(), val.length(), &result));
119 return result;
120 }
121
122 template<typename T, std::enable_if_t<std::is_same_v<T, char>, int32_t> = 0>
GetNapiValue(napi_env env,const T * val)123 napi_value GetNapiValue(napi_env env, const T *val)
124 {
125 napi_value result = nullptr;
126 NAPI_CALL(env, napi_create_string_utf8(env, val, NAPI_AUTO_LENGTH, &result));
127 return result;
128 }
129
130 template<typename T, std::enable_if_t<std::is_same_v<T, napi_value>, int32_t> = 0>
GetNapiValue(napi_env env,T val)131 napi_value GetNapiValue(napi_env env, T val)
132 {
133 return val;
134 }
135
136 template<typename T>
SetPropertyToNapiObject(napi_env env,napi_value object,std::string_view name,T value)137 void SetPropertyToNapiObject(napi_env env, napi_value object, std::string_view name, T value)
138 {
139 napi_value propertyValue = GetNapiValue(env, value);
140 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.data(), propertyValue));
141 }
142
143 template<typename T>
NapiValueToCppValue(napi_env env,napi_value arg,napi_valuetype argType,T * val)144 napi_status NapiValueToCppValue(napi_env env, napi_value arg, napi_valuetype argType, T *val)
145 {
146 napi_valuetype valueType = napi_undefined;
147 napi_typeof(env, arg, &valueType);
148 if (valueType == argType) {
149 return NapiValueConverted(env, arg, val);
150 }
151 return napi_invalid_arg;
152 }
153
154 template<typename... Ts, size_t N>
MatchParameters(napi_env env,const napi_value (& argv)[N],size_t argc,std::tuple<Ts...> & theTuple)155 std::optional<NapiError> MatchParameters(
156 napi_env env, const napi_value (&argv)[N], size_t argc, std::tuple<Ts...> &theTuple)
157 {
158 int32_t typeSize = sizeof...(Ts);
159 napi_valuetype valueType = napi_undefined;
160 napi_typeof(env, argv[typeSize - 1], &valueType);
161 if (valueType != napi_function) {
162 typeSize--;
163 }
164 std::vector<napi_valuetype> typeStd(typeSize, napi_undefined);
165
166 if (argc != typeStd.size()) {
167 return std::optional<NapiError>(ERROR_PARAMETER_COUNTS_INVALID);
168 }
169 bool typeMatched = true;
170 std::apply(
171 [argc, &argv, &typeStd](Ts &... tupleArgs) {
172 size_t index { 0 };
173 ((index < argc ? (typeStd[index++] = GetInputArgvType(tupleArgs)) : true), ...);
174 },
175 theTuple);
176 for (size_t i = 0; i < argc; i++) {
177 napi_valuetype valueType = napi_undefined;
178 napi_typeof(env, argv[i], &valueType);
179 if (valueType != typeStd[i]) {
180 typeMatched = false;
181 break;
182 }
183 }
184 if (typeMatched) {
185 std::apply(
186 [env, argc, &argv](Ts &... tupleArgs) {
187 size_t index { 0 };
188 ((index < argc ? NapiValueConverted(env, argv[index++], tupleArgs) : napi_ok), ...);
189 },
190 theTuple);
191 return std::nullopt;
192 }
193 return std::optional<NapiError>(ERROR_PARAMETER_TYPE_INVALID);
194 }
195 } // namespace Telephony
196 } // namespace OHOS
197 #endif
198