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