1 /*
2 * Copyright (c) 2021-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 <cstdlib>
19 #include <cstring>
20 #include <initializer_list>
21 #include <memory>
22 #include <algorithm>
23 #include <new>
24 #include <string>
25 #include <vector>
26
27 #include "securec.h"
28 #include "napi/native_api.h"
29 #include "napi/native_common.h"
30 #include "node_api.h"
31 #include "base_context.h"
32 #include "json/json.h"
33 #include "netstack_log.h"
34
35 namespace OHOS::NetStack::NapiUtils {
36 static constexpr const char *GLOBAL_JSON = "JSON";
37
38 static constexpr const char *GLOBAL_JSON_STRINGIFY = "stringify";
39
40 static constexpr const char *GLOBAL_JSON_PARSE = "parse";
41
42 static constexpr const char *CODE = "code";
43
44 static constexpr const char *MSG = "message";
45
GetValueType(napi_env env,napi_value value)46 napi_valuetype GetValueType(napi_env env, napi_value value)
47 {
48 if (value == nullptr) {
49 return napi_undefined;
50 }
51
52 napi_valuetype valueType = napi_undefined;
53 NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
54 return valueType;
55 }
56
57 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)58 bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
59 {
60 if (GetValueType(env, object) != napi_object) {
61 return false;
62 }
63
64 bool hasProperty = false;
65 NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
66 return hasProperty;
67 }
68
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)69 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
70 {
71 if (GetValueType(env, object) != napi_object) {
72 return GetUndefined(env);
73 }
74
75 napi_value value = nullptr;
76 NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
77 return value;
78 }
79
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)80 void SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
81 {
82 if (GetValueType(env, object) != napi_object) {
83 return;
84 }
85
86 napi_set_named_property(env, object, name.c_str(), value);
87 }
88
GetPropertyNames(napi_env env,napi_value object)89 std::vector<std::string> GetPropertyNames(napi_env env, napi_value object)
90 {
91 if (GetValueType(env, object) != napi_object) {
92 return {};
93 }
94
95 std::vector<std::string> ret;
96 napi_value names = nullptr;
97 NAPI_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
98 uint32_t length = 0;
99 NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
100 for (uint32_t index = 0; index < length; ++index) {
101 napi_value name = nullptr;
102 if (napi_get_element(env, names, index, &name) != napi_ok) {
103 continue;
104 }
105 if (GetValueType(env, name) != napi_string) {
106 continue;
107 }
108 ret.emplace_back(GetStringFromValueUtf8(env, name));
109 }
110 return ret;
111 }
112
113 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)114 napi_value CreateUint32(napi_env env, uint32_t code)
115 {
116 napi_value value = nullptr;
117 if (napi_create_uint32(env, code, &value) != napi_ok) {
118 return nullptr;
119 }
120 return value;
121 }
122
123 /* UINT64 */
CreateUint64(napi_env env,uint64_t code)124 napi_value CreateUint64(napi_env env, uint64_t code)
125 {
126 napi_value value = nullptr;
127 if (napi_create_bigint_uint64(env, code, &value) != napi_ok) {
128 return nullptr;
129 }
130 return value;
131 }
132
GetInt64FromValue(napi_env env,napi_value value)133 int64_t GetInt64FromValue(napi_env env, napi_value value)
134 {
135 if (GetValueType(env, value) != napi_number) {
136 return 0;
137 }
138 int64_t ret = 0;
139 NAPI_CALL_BASE(env, napi_get_value_int64(env, value, &ret), 0);
140 return ret;
141 }
142
GetInt64Property(napi_env env,napi_value object,const std::string & propertyName)143 int64_t GetInt64Property(napi_env env, napi_value object, const std::string &propertyName)
144 {
145 if (!HasNamedProperty(env, object, propertyName)) {
146 return 0;
147 }
148 napi_value value = GetNamedProperty(env, object, propertyName);
149 return GetInt64FromValue(env, value);
150 }
151
GetUint32FromValue(napi_env env,napi_value value)152 uint32_t GetUint32FromValue(napi_env env, napi_value value)
153 {
154 if (GetValueType(env, value) != napi_number) {
155 return 0;
156 }
157
158 uint32_t ret = 0;
159 NAPI_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
160 return ret;
161 }
162
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)163 uint32_t GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
164 {
165 if (!HasNamedProperty(env, object, propertyName)) {
166 return 0;
167 }
168 napi_value value = GetNamedProperty(env, object, propertyName);
169 return GetUint32FromValue(env, value);
170 }
171
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)172 void SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
173 {
174 napi_value jsValue = CreateUint32(env, value);
175 if (GetValueType(env, jsValue) != napi_number) {
176 return;
177 }
178
179 napi_set_named_property(env, object, name.c_str(), jsValue);
180 }
181
SetUint64Property(napi_env env,napi_value object,const std::string & name,uint64_t value)182 void SetUint64Property(napi_env env, napi_value object, const std::string &name, uint64_t value)
183 {
184 napi_value jsValue = CreateUint64(env, value);
185 if (GetValueType(env, jsValue) != napi_bigint) {
186 return;
187 }
188
189 napi_set_named_property(env, object, name.c_str(), jsValue);
190 }
191
192 /* INT32 */
CreateInt32(napi_env env,int32_t code)193 napi_value CreateInt32(napi_env env, int32_t code)
194 {
195 napi_value value = nullptr;
196 if (napi_create_int32(env, code, &value) != napi_ok) {
197 return nullptr;
198 }
199 return value;
200 }
201
GetInt32FromValue(napi_env env,napi_value value)202 int32_t GetInt32FromValue(napi_env env, napi_value value)
203 {
204 if (GetValueType(env, value) != napi_number) {
205 return 0;
206 }
207
208 int32_t ret = 0;
209 NAPI_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
210 return ret;
211 }
212
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)213 int32_t GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
214 {
215 if (!HasNamedProperty(env, object, propertyName)) {
216 return 0;
217 }
218 napi_value value = GetNamedProperty(env, object, propertyName);
219 return GetInt32FromValue(env, value);
220 }
221
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)222 void SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
223 {
224 napi_value jsValue = CreateInt32(env, value);
225 if (GetValueType(env, jsValue) != napi_number) {
226 return;
227 }
228
229 napi_set_named_property(env, object, name.c_str(), jsValue);
230 }
231
SetDoubleProperty(napi_env env,napi_value object,const std::string & name,double value)232 void SetDoubleProperty(napi_env env, napi_value object, const std::string &name, double value)
233 {
234 napi_value jsValue;
235 if (napi_create_double(env, value, &jsValue) != napi_ok) {
236 return;
237 }
238 if (GetValueType(env, jsValue) != napi_number) {
239 return;
240 }
241 napi_set_named_property(env, object, name.c_str(), jsValue);
242 }
243
244 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)245 napi_value CreateStringUtf8(napi_env env, const std::string &str)
246 {
247 napi_value value = nullptr;
248 if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
249 return nullptr;
250 }
251 return value;
252 }
253
GetStringFromValueUtf8(napi_env env,napi_value value)254 std::string GetStringFromValueUtf8(napi_env env, napi_value value)
255 {
256 if (GetValueType(env, value) != napi_string) {
257 return {};
258 }
259
260 std::string result;
261 size_t stringLength = 0;
262 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, nullptr, 0, &stringLength), result);
263 if (stringLength == 0) {
264 return result;
265 }
266
267 auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
268 std::unique_ptr<char, decltype(deleter)> str(static_cast<char *>(malloc(stringLength + 1)), deleter);
269 if (memset_s(str.get(), stringLength + 1, 0, stringLength + 1) != EOK) {
270 return result;
271 }
272 size_t length = 0;
273 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str.get(), stringLength + 1, &length), result);
274 if (length > 0) {
275 result.append(str.get(), length);
276 }
277 return result;
278 }
279
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)280 std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
281 {
282 if (!HasNamedProperty(env, object, propertyName)) {
283 return "";
284 }
285 napi_value value = GetNamedProperty(env, object, propertyName);
286 return GetStringFromValueUtf8(env, value);
287 }
288
NapiValueToString(napi_env env,napi_value value)289 std::string NapiValueToString(napi_env env, napi_value value)
290 {
291 napi_status status;
292 napi_valuetype valueType;
293 status = napi_typeof(env, value, &valueType);
294 if (status != napi_ok) {
295 return "";
296 }
297 switch (valueType) {
298 case napi_undefined:
299 case napi_null:
300 break;
301 case napi_boolean:
302 bool boolValue;
303 status = napi_get_value_bool(env, value, &boolValue);
304 if (status == napi_ok) {
305 return boolValue ? "true" : "false";
306 }
307 break;
308 case napi_number:
309 double doubleValue;
310 status = napi_get_value_double(env, value, &doubleValue);
311 if (status == napi_ok) {
312 if (doubleValue == std::floor(doubleValue)) {
313 return std::to_string(static_cast<int>(doubleValue));
314 }
315 return std::to_string(doubleValue);
316 }
317 break;
318 case napi_string:
319 return GetStringFromValueUtf8(env, value);
320 default:
321 break;
322 }
323 return "";
324 }
325
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)326 void SetStringPropertyUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
327 {
328 napi_value jsValue = CreateStringUtf8(env, value);
329 if (GetValueType(env, jsValue) != napi_string) {
330 return;
331 }
332 napi_set_named_property(env, object, name.c_str(), jsValue);
333 }
334
335 /* array buffer */
ValueIsArrayBuffer(napi_env env,napi_value value)336 bool ValueIsArrayBuffer(napi_env env, napi_value value)
337 {
338 if (value == nullptr) {
339 return false;
340 }
341 bool isArrayBuffer = false;
342 NAPI_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
343 return isArrayBuffer;
344 }
345
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)346 void *GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
347 {
348 if (length == nullptr) {
349 return nullptr;
350 }
351
352 void *data = nullptr;
353 NAPI_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
354 return data;
355 }
356
CreateArrayBuffer(napi_env env,size_t length,void ** data)357 napi_value CreateArrayBuffer(napi_env env, size_t length, void **data)
358 {
359 if (length == 0) {
360 return nullptr;
361 }
362 napi_value result = nullptr;
363 NAPI_CALL(env, napi_create_arraybuffer(env, length, data, &result));
364 return result;
365 }
366
367 /* object */
CreateObject(napi_env env)368 napi_value CreateObject(napi_env env)
369 {
370 napi_value object = nullptr;
371 NAPI_CALL(env, napi_create_object(env, &object));
372 return object;
373 }
374
375 /* undefined */
GetUndefined(napi_env env)376 napi_value GetUndefined(napi_env env)
377 {
378 napi_value undefined = nullptr;
379 NAPI_CALL(env, napi_get_undefined(env, &undefined));
380 return undefined;
381 }
382
383 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)384 napi_value CallFunction(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
385 {
386 napi_value res = nullptr;
387 NAPI_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
388 return res;
389 }
390
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)391 napi_value CreateFunction(napi_env env, const std::string &name, napi_callback func, void *arg)
392 {
393 napi_value res = nullptr;
394 NAPI_CALL(env, napi_create_function(env, name.c_str(), strlen(name.c_str()), func, arg, &res));
395 return res;
396 }
397
398 /* reference */
CreateReference(napi_env env,napi_value callback)399 napi_ref CreateReference(napi_env env, napi_value callback)
400 {
401 napi_ref callbackRef = nullptr;
402 NAPI_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
403 return callbackRef;
404 }
405
GetReference(napi_env env,napi_ref callbackRef)406 napi_value GetReference(napi_env env, napi_ref callbackRef)
407 {
408 napi_value callback = nullptr;
409 NAPI_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
410 return callback;
411 }
412
DeleteReference(napi_env env,napi_ref callbackRef)413 void DeleteReference(napi_env env, napi_ref callbackRef)
414 {
415 (void)napi_delete_reference(env, callbackRef);
416 }
417
418 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)419 bool GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
420 {
421 if (!HasNamedProperty(env, object, propertyName)) {
422 return false;
423 }
424 napi_value value = GetNamedProperty(env, object, propertyName);
425 bool ret = false;
426 NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
427 return ret;
428 }
429
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)430 void SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
431 {
432 napi_value jsValue = nullptr;
433 NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
434 if (GetValueType(env, jsValue) != napi_boolean) {
435 return;
436 }
437
438 napi_set_named_property(env, object, name.c_str(), jsValue);
439 }
440
GetBoolean(napi_env env,bool value)441 napi_value GetBoolean(napi_env env, bool value)
442 {
443 napi_value jsValue = nullptr;
444 NAPI_CALL(env, napi_get_boolean(env, value, &jsValue));
445 return jsValue;
446 }
447
GetBooleanFromValue(napi_env env,napi_value value)448 bool GetBooleanFromValue(napi_env env, napi_value value)
449 {
450 if (GetValueType(env, value) != napi_boolean) {
451 return GetUndefined(env);
452 }
453
454 bool ret = false;
455 NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
456 return ret;
457 }
458
459 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)460 void DefineProperties(napi_env env, napi_value object,
461 const std::initializer_list<napi_property_descriptor> &properties)
462 {
463 napi_property_descriptor descriptors[properties.size()];
464 std::copy(properties.begin(), properties.end(), descriptors);
465
466 (void)napi_define_properties(env, object, properties.size(), descriptors);
467 }
468
469 /* array */
CreateArray(napi_env env,size_t length)470 napi_value CreateArray(napi_env env, size_t length)
471 {
472 if (length == 0) {
473 napi_value res = nullptr;
474 NAPI_CALL(env, napi_create_array(env, &res));
475 return res;
476 }
477 napi_value res = nullptr;
478 NAPI_CALL(env, napi_create_array_with_length(env, length, &res));
479 return res;
480 }
481
SetArrayElement(napi_env env,napi_value array,uint32_t index,napi_value value)482 void SetArrayElement(napi_env env, napi_value array, uint32_t index, napi_value value)
483 {
484 (void)napi_set_element(env, array, index, value);
485 }
486
IsArray(napi_env env,napi_value value)487 bool IsArray(napi_env env, napi_value value)
488 {
489 bool result = false;
490 NAPI_CALL_BASE(env, napi_is_array(env, value, &result), false);
491 return result;
492 }
493
SetArrayProperty(napi_env env,napi_value object,const std::string & name,napi_value value)494 void SetArrayProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
495 {
496 if (!IsArray(env, value)) {
497 return;
498 }
499 napi_set_named_property(env, object, name.c_str(), value);
500 }
501
GetArrayLength(napi_env env,napi_value arr)502 uint32_t GetArrayLength(napi_env env, napi_value arr)
503 {
504 uint32_t arrayLength = 0;
505 NAPI_CALL_BASE(env, napi_get_array_length(env, arr, &arrayLength), 0);
506 return arrayLength;
507 }
508
GetArrayElement(napi_env env,napi_value arr,uint32_t index)509 napi_value GetArrayElement(napi_env env, napi_value arr, uint32_t index)
510 {
511 napi_value elementValue = nullptr;
512 NAPI_CALL(env, napi_get_element(env, arr, index, &elementValue));
513 return elementValue;
514 }
515
516 /* JSON */
JsonStringify(napi_env env,napi_value object)517 napi_value JsonStringify(napi_env env, napi_value object)
518 {
519 napi_value undefined = GetUndefined(env);
520
521 if (GetValueType(env, object) != napi_object) {
522 return undefined;
523 }
524
525 napi_value global = nullptr;
526 NAPI_CALL_BASE(env, napi_get_global(env, &global), undefined);
527 napi_value json = nullptr;
528 NAPI_CALL_BASE(env, napi_get_named_property(env, global, GLOBAL_JSON, &json), undefined);
529 napi_value stringify = nullptr;
530 NAPI_CALL_BASE(env, napi_get_named_property(env, json, GLOBAL_JSON_STRINGIFY, &stringify), undefined);
531 if (GetValueType(env, stringify) != napi_function) {
532 return undefined;
533 }
534
535 napi_value res = nullptr;
536 napi_value argv[1] = {object};
537 NAPI_CALL_BASE(env, napi_call_function(env, json, stringify, 1, argv, &res), undefined);
538 return res;
539 }
540
JsonParse(napi_env env,const std::string & inStr)541 napi_value JsonParse(napi_env env, const std::string &inStr)
542 {
543 napi_value undefined = GetUndefined(env);
544 JSONCPP_STRING err;
545 Json::Value valueJson;
546 Json::CharReaderBuilder readerBuilder;
547 std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
548 bool ret = jsonReader->parse(inStr.c_str(), inStr.c_str() + inStr.length(), &valueJson, &err);
549 if (!ret || !err.empty()) {
550 return undefined;
551 }
552
553 auto str = NapiUtils::CreateStringUtf8(env, inStr);
554 if (GetValueType(env, str) != napi_string) {
555 return undefined;
556 }
557
558 napi_value global = nullptr;
559 NAPI_CALL_BASE(env, napi_get_global(env, &global), undefined);
560 napi_value json = nullptr;
561 NAPI_CALL_BASE(env, napi_get_named_property(env, global, GLOBAL_JSON, &json), undefined);
562 napi_value parse = nullptr;
563 NAPI_CALL_BASE(env, napi_get_named_property(env, json, GLOBAL_JSON_PARSE, &parse), undefined);
564 if (GetValueType(env, parse) != napi_function) {
565 return undefined;
566 }
567
568 napi_value res = nullptr;
569 napi_value argv[1] = {str};
570 NAPI_CALL_BASE(env, napi_call_function(env, json, parse, 1, argv, &res), undefined);
571 return res;
572 }
573
574 /* libuv */
CreateUvQueueWork(napi_env env,void * data,void (handler)(uv_work_t *,int status))575 void CreateUvQueueWork(napi_env env, void *data, void(handler)(uv_work_t *, int status))
576 {
577 uv_loop_s *loop = nullptr;
578 NAPI_CALL_RETURN_VOID(env, napi_get_uv_event_loop(env, &loop));
579
580 auto work = new uv_work_t;
581 work->data = data;
582
583 int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *) {}, handler, uv_qos_default);
584 if (ret != 0) {
585 NETSTACK_LOGE("uv_queue_work_with_qos error = %{public}d, manual delete", ret);
586 delete static_cast<UvWorkWrapper *>(work->data);
587 delete work;
588 }
589 }
590
591 /* scope */
OpenScope(napi_env env)592 napi_handle_scope OpenScope(napi_env env)
593 {
594 napi_handle_scope scope = nullptr;
595 NAPI_CALL(env, napi_open_handle_scope(env, &scope));
596 return scope;
597 }
598
CloseScope(napi_env env,napi_handle_scope scope)599 void CloseScope(napi_env env, napi_handle_scope scope)
600 {
601 (void)napi_close_handle_scope(env, scope);
602 }
603
CreateUvQueueWorkEnhanced(napi_env env,void * data,void (* handler)(napi_env env,napi_status status,void * data))604 void CreateUvQueueWorkEnhanced(napi_env env, void *data, void (*handler)(napi_env env, napi_status status, void *data))
605 {
606 uv_loop_s *loop = nullptr;
607 NAPI_CALL_RETURN_VOID(env, napi_get_uv_event_loop(env, &loop));
608
609 if (loop == nullptr) {
610 return;
611 }
612
613 class WorkData {
614 public:
615 WorkData() = delete;
616
617 WorkData(napi_env env, void *data, void (*handler)(napi_env env, napi_status status, void *data))
618 : env_(env), data_(data), handler_(handler)
619 {
620 }
621
622 napi_env env_;
623 void *data_;
624 void (*handler_)(napi_env env, napi_status status, void *data);
625 };
626
627 auto workData = new WorkData(env, data, handler);
628
629 auto work = new (std::nothrow) uv_work_t;
630 if (work == nullptr) {
631 return;
632 }
633 work->data = reinterpret_cast<void *>(workData);
634
635 auto callback = [](uv_work_t *work, int status) {
636 auto workData = static_cast<WorkData *>(work->data);
637 if (!workData) {
638 delete work;
639 return;
640 }
641
642 if (!workData->env_ || !workData->data_ || !workData->handler_) {
643 delete workData;
644 delete work;
645 return;
646 }
647
648 napi_env env = workData->env_;
649 auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
650 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
651
652 workData->handler_(workData->env_, static_cast<napi_status>(status), workData->data_);
653
654 delete workData;
655 delete work;
656 };
657
658 int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *) {}, callback, uv_qos_default);
659 if (ret != 0) {
660 NETSTACK_LOGE("uv_queue_work_with_qos error = %{public}d, manual release", ret);
661 delete static_cast<WorkData *>(work->data);
662 delete work;
663 }
664 }
665
666 /* error */
CreateErrorMessage(napi_env env,int32_t errorCode,const std::string & errorMessage)667 napi_value CreateErrorMessage(napi_env env, int32_t errorCode, const std::string &errorMessage)
668 {
669 napi_value result = nullptr;
670 result = CreateObject(env);
671 SetNamedProperty(env, result, CODE, CreateInt32(env, errorCode));
672 SetNamedProperty(env, result, MSG, CreateStringUtf8(env, errorMessage));
673 return result;
674 }
675
GetGlobal(napi_env env)676 napi_value GetGlobal(napi_env env)
677 {
678 napi_value undefined = GetUndefined(env);
679 napi_value global = nullptr;
680 NAPI_CALL_BASE(env, napi_get_global(env, &global), undefined);
681 return global;
682 }
683 } // namespace OHOS::NetStack::NapiUtils
684