• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include "netmanager_base_napi_utils.h"
17 
18 #include <cstring>
19 #include <initializer_list>
20 #include <memory>
21 
22 #include "securec.h"
23 
24 namespace OHOS::NetManagerStandard::NapiUtils {
25 static constexpr const int MAX_STRING_LENGTH = 65536;
26 
GetValueType(napi_env env,napi_value value)27 napi_valuetype GetValueType(napi_env env, napi_value value)
28 {
29     if (value == nullptr) {
30         return napi_undefined;
31     }
32 
33     napi_valuetype valueType = napi_undefined;
34     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
35     return valueType;
36 }
37 
38 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)39 bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
40 {
41     bool hasProperty = false;
42     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
43     return hasProperty;
44 }
45 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)46 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
47 {
48     napi_value value = nullptr;
49     NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
50     return value;
51 }
52 
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)53 void SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
54 {
55     (void)napi_set_named_property(env, object, name.c_str(), value);
56 }
57 
GetPropertyNames(napi_env env,napi_value object)58 std::vector<std::string> GetPropertyNames(napi_env env, napi_value object)
59 {
60     std::vector<std::string> ret;
61     napi_value names = nullptr;
62     NAPI_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
63     uint32_t length = 0;
64     NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
65     for (uint32_t index = 0; index < length; ++index) {
66         napi_value name = nullptr;
67         if (napi_get_element(env, names, index, &name) != napi_ok) {
68             continue;
69         }
70         if (GetValueType(env, name) != napi_string) {
71             continue;
72         }
73         ret.emplace_back(GetStringFromValueUtf8(env, name));
74     }
75     return ret;
76 }
77 
78 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)79 napi_value CreateUint32(napi_env env, uint32_t code)
80 {
81     napi_value value = nullptr;
82     if (napi_create_uint32(env, code, &value) != napi_ok) {
83         return nullptr;
84     }
85     return value;
86 }
87 
GetUint32FromValue(napi_env env,napi_value value)88 uint32_t GetUint32FromValue(napi_env env, napi_value value)
89 {
90     uint32_t ret = 0;
91     NAPI_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
92     return ret;
93 }
94 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)95 uint32_t GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
96 {
97     if (!HasNamedProperty(env, object, propertyName)) {
98         return 0;
99     }
100     napi_value value = GetNamedProperty(env, object, propertyName);
101     return GetUint32FromValue(env, value);
102 }
103 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)104 void SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
105 {
106     napi_value jsValue = CreateUint32(env, value);
107     if (GetValueType(env, jsValue) != napi_number) {
108         return;
109     }
110 
111     napi_set_named_property(env, object, name.c_str(), jsValue);
112 }
113 
114 /* INT32 */
CreateInt32(napi_env env,int32_t code)115 napi_value CreateInt32(napi_env env, int32_t code)
116 {
117     napi_value value = nullptr;
118     if (napi_create_int32(env, code, &value) != napi_ok) {
119         return nullptr;
120     }
121     return value;
122 }
123 
GetInt32FromValue(napi_env env,napi_value value)124 int32_t GetInt32FromValue(napi_env env, napi_value value)
125 {
126     int32_t ret = 0;
127     NAPI_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
128     return ret;
129 }
130 
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)131 int32_t GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
132 {
133     if (!HasNamedProperty(env, object, propertyName)) {
134         return 0;
135     }
136     napi_value value = GetNamedProperty(env, object, propertyName);
137     return GetInt32FromValue(env, value);
138 }
139 
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)140 void SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
141 {
142     napi_value jsValue = CreateInt32(env, value);
143     if (GetValueType(env, jsValue) != napi_number) {
144         return;
145     }
146 
147     napi_set_named_property(env, object, name.c_str(), jsValue);
148 }
149 
150 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)151 napi_value CreateStringUtf8(napi_env env, const std::string &str)
152 {
153     napi_value value = nullptr;
154     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
155         return nullptr;
156     }
157     return value;
158 }
159 
GetStringFromValueUtf8(napi_env env,napi_value value)160 std::string GetStringFromValueUtf8(napi_env env, napi_value value)
161 {
162     std::string result;
163     auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
164     std::unique_ptr<char, decltype(deleter)> str(static_cast<char *>(malloc(MAX_STRING_LENGTH)), deleter);
165     (void)memset_s(str.get(), MAX_STRING_LENGTH, 0, MAX_STRING_LENGTH);
166     size_t length = 0;
167     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str.get(), MAX_STRING_LENGTH, &length), result);
168     if (length > 0) {
169         return result.append(str.get(), length);
170     }
171     return result;
172 }
173 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)174 std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
175 {
176     if (!HasNamedProperty(env, object, propertyName)) {
177         return "";
178     }
179     napi_value value = GetNamedProperty(env, object, propertyName);
180     return GetStringFromValueUtf8(env, value);
181 }
182 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)183 void SetStringPropertyUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
184 {
185     napi_value jsValue = CreateStringUtf8(env, value);
186     if (GetValueType(env, jsValue) != napi_string) {
187         return;
188     }
189     napi_set_named_property(env, object, name.c_str(), jsValue);
190 }
191 
192 /* array buffer */
ValueIsArrayBuffer(napi_env env,napi_value value)193 bool ValueIsArrayBuffer(napi_env env, napi_value value)
194 {
195     bool isArrayBuffer = false;
196     NAPI_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
197     return isArrayBuffer;
198 }
199 
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)200 void *GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
201 {
202     if (length == nullptr) {
203         return nullptr;
204     }
205 
206     void *data = nullptr;
207     NAPI_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
208     return data;
209 }
210 
CreateArrayBuffer(napi_env env,size_t length,void ** data)211 napi_value CreateArrayBuffer(napi_env env, size_t length, void **data)
212 {
213     if (length == 0) {
214         return nullptr;
215     }
216     napi_value result = nullptr;
217     NAPI_CALL(env, napi_create_arraybuffer(env, length, data, &result));
218     return result;
219 }
220 
221 /* object */
CreateObject(napi_env env)222 napi_value CreateObject(napi_env env)
223 {
224     napi_value object = nullptr;
225     NAPI_CALL(env, napi_create_object(env, &object));
226     return object;
227 }
228 
229 /* undefined */
GetUndefined(napi_env env)230 napi_value GetUndefined(napi_env env)
231 {
232     napi_value undefined = nullptr;
233     NAPI_CALL(env, napi_get_undefined(env, &undefined));
234     return undefined;
235 }
236 
237 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)238 napi_value CallFunction(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
239 {
240     napi_value res = nullptr;
241     NAPI_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
242     return res;
243 }
244 
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)245 napi_value CreateFunction(napi_env env, const std::string &name, napi_callback func, void *arg)
246 {
247     napi_value res = nullptr;
248     NAPI_CALL(env, napi_create_function(env, name.c_str(), strlen(name.c_str()), func, arg, &res));
249     return res;
250 }
251 
252 /* reference */
CreateReference(napi_env env,napi_value callback)253 napi_ref CreateReference(napi_env env, napi_value callback)
254 {
255     napi_ref callbackRef = nullptr;
256     NAPI_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
257     return callbackRef;
258 }
259 
GetReference(napi_env env,napi_ref callbackRef)260 napi_value GetReference(napi_env env, napi_ref callbackRef)
261 {
262     napi_value callback = nullptr;
263     NAPI_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
264     return callback;
265 }
266 
DeleteReference(napi_env env,napi_ref callbackRef)267 void DeleteReference(napi_env env, napi_ref callbackRef)
268 {
269     (void)napi_delete_reference(env, callbackRef);
270 }
271 
272 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)273 bool GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
274 {
275     if (!HasNamedProperty(env, object, propertyName)) {
276         return false;
277     }
278     napi_value value = GetNamedProperty(env, object, propertyName);
279     bool ret = false;
280     NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
281     return ret;
282 }
283 
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)284 void SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
285 {
286     napi_value jsValue = nullptr;
287     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
288     if (GetValueType(env, jsValue) != napi_boolean) {
289         return;
290     }
291 
292     napi_set_named_property(env, object, name.c_str(), jsValue);
293 }
294 
GetBoolean(napi_env env,bool value)295 napi_value GetBoolean(napi_env env, bool value)
296 {
297     napi_value jsValue = nullptr;
298     NAPI_CALL(env, napi_get_boolean(env, value, &jsValue));
299     return jsValue;
300 }
301 
302 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)303 void DefineProperties(napi_env env,
304                       napi_value object,
305                       const std::initializer_list<napi_property_descriptor> &properties)
306 {
307     napi_property_descriptor descriptors[properties.size()];
308     std::copy(properties.begin(), properties.end(), descriptors);
309 
310     (void)napi_define_properties(env, object, properties.size(), descriptors);
311 }
312 
313 /* array */
CreateArray(napi_env env,size_t length)314 napi_value CreateArray(napi_env env, size_t length)
315 {
316     if (length == 0) {
317         napi_value res = nullptr;
318         NAPI_CALL(env, napi_create_array(env, &res));
319         return res;
320     }
321     napi_value res = nullptr;
322     NAPI_CALL(env, napi_create_array_with_length(env, length, &res));
323     return res;
324 }
325 
SetArrayElement(napi_env env,napi_value array,uint32_t index,napi_value value)326 void SetArrayElement(napi_env env, napi_value array, uint32_t index, napi_value value)
327 {
328     (void)napi_set_element(env, array, index, value);
329 }
330 
IsArray(napi_env env,napi_value value)331 bool IsArray(napi_env env, napi_value value)
332 {
333     bool result = false;
334     NAPI_CALL_BASE(env, napi_is_array(env, value, &result), false);
335     return result;
336 }
337 
GetArrayLength(napi_env env,napi_value arr)338 uint32_t GetArrayLength(napi_env env, napi_value arr)
339 {
340     uint32_t arrayLength = 0;
341     NAPI_CALL_BASE(env, napi_get_array_length(env, arr, &arrayLength), 0);
342     return arrayLength;
343 }
344 
GetArrayElement(napi_env env,napi_value arr,uint32_t index)345 napi_value GetArrayElement(napi_env env, napi_value arr, uint32_t index)
346 {
347     napi_value elementValue = nullptr;
348     NAPI_CALL(env, napi_get_element(env, arr, index, &elementValue));
349     return elementValue;
350 }
351 
352 /* libuv */
CreateUvQueueWork(napi_env env,void * data,void (Handler)(uv_work_t *,int status))353 void CreateUvQueueWork(napi_env env, void *data, void(Handler)(uv_work_t *, int status))
354 {
355     uv_loop_s *loop = nullptr;
356     NAPI_CALL_RETURN_VOID(env, napi_get_uv_event_loop(env, &loop));
357 
358     auto work = new uv_work_t;
359     work->data = data;
360 
361     (void)uv_queue_work(
362         loop, work, [](uv_work_t *) {}, Handler);
363 }
364 
365 /* scope */
OpenScope(napi_env env)366 napi_handle_scope OpenScope(napi_env env)
367 {
368     napi_handle_scope scope = nullptr;
369     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
370     return scope;
371 }
372 
CloseScope(napi_env env,napi_handle_scope scope)373 void CloseScope(napi_env env, napi_handle_scope scope)
374 {
375     (void)napi_close_handle_scope(env, scope);
376 }
377 } // namespace OHOS::NetManagerStandard::NapiUtils