1 /*
2 * Copyright (c) 2021-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 #include "napi_common_util.h"
16
17 #include <cstring>
18
19 #include "hilog_tag_wrapper.h"
20 #include "napi_common_data.h"
21 #include "napi_common_error.h"
22 #include "securec.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
IsTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)26 bool IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
27 {
28 TAG_LOGD(AAFwkTag::JSNAPI, "called");
29 napi_valuetype valueType = napi_undefined;
30
31 if (param == nullptr) {
32 TAG_LOGD(AAFwkTag::JSNAPI, "param is nullptr");
33 return false;
34 }
35
36 if (napi_typeof(env, param, &valueType) != napi_ok) {
37 return false;
38 }
39
40 return valueType == expectType;
41 }
42
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)43 bool IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
44 {
45 TAG_LOGD(AAFwkTag::JSNAPI, "called");
46 bool isArray = false;
47 arraySize = 0;
48
49 if (napi_is_array(env, param, &isArray) != napi_ok || isArray == false) {
50 return false;
51 }
52
53 if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
54 TAG_LOGD(AAFwkTag::JSNAPI, "napi_get_array_length is 0");
55 return false;
56 }
57 return true;
58 }
59
WrapVoidToJS(napi_env env)60 napi_value WrapVoidToJS(napi_env env)
61 {
62 napi_value result = nullptr;
63 NAPI_CALL(env, napi_get_null(env, &result));
64 return result;
65 }
66
WrapUndefinedToJS(napi_env env)67 napi_value WrapUndefinedToJS(napi_env env)
68 {
69 napi_value result = nullptr;
70 NAPI_CALL(env, napi_get_undefined(env, &result));
71 return result;
72 }
73
CreateJSObject(napi_env env)74 napi_value CreateJSObject(napi_env env)
75 {
76 napi_value result = nullptr;
77 NAPI_CALL(env, napi_create_object(env, &result));
78 return result;
79 }
80
WrapInt32ToJS(napi_env env,int32_t value)81 napi_value WrapInt32ToJS(napi_env env, int32_t value)
82 {
83 napi_value result = nullptr;
84 NAPI_CALL(env, napi_create_int32(env, value, &result));
85 return result;
86 }
87
UnwrapInt32FromJS(napi_env env,napi_value param,int defaultValue)88 int UnwrapInt32FromJS(napi_env env, napi_value param, int defaultValue)
89 {
90 int value = defaultValue;
91 if (napi_get_value_int32(env, param, &value) == napi_ok) {
92 return value;
93 } else {
94 return defaultValue;
95 }
96 }
97
UnwrapInt32FromJS2(napi_env env,napi_value param,int & value)98 bool UnwrapInt32FromJS2(napi_env env, napi_value param, int &value)
99 {
100 bool result = false;
101 if (napi_get_value_int32(env, param, &value) == napi_ok) {
102 result = true;
103 }
104 return result;
105 }
106
WrapLongToJS(napi_env env,long value)107 napi_value WrapLongToJS(napi_env env, long value)
108 {
109 napi_value result = nullptr;
110 NAPI_CALL(env, napi_create_int32(env, value, &result));
111 return result;
112 }
113
UnwrapLongFromJS(napi_env env,napi_value param,long defaultValue)114 long UnwrapLongFromJS(napi_env env, napi_value param, long defaultValue)
115 {
116 int value = 0;
117 if (napi_get_value_int32(env, param, &value) == napi_ok) {
118 return value;
119 } else {
120 return defaultValue;
121 }
122 }
123
UnwrapLongFromJS2(napi_env env,napi_value param,long & value)124 bool UnwrapLongFromJS2(napi_env env, napi_value param, long &value)
125 {
126 bool result = false;
127 int natValue = 0;
128 if (napi_get_value_int32(env, param, &natValue) == napi_ok) {
129 value = natValue;
130 result = true;
131 }
132 return result;
133 }
134
WrapInt64ToJS(napi_env env,int64_t value)135 napi_value WrapInt64ToJS(napi_env env, int64_t value)
136 {
137 napi_value result = nullptr;
138 NAPI_CALL(env, napi_create_int64(env, value, &result));
139 return result;
140 }
141
UnwrapInt64FromJS(napi_env env,napi_value param,int64_t defaultValue)142 int64_t UnwrapInt64FromJS(napi_env env, napi_value param, int64_t defaultValue)
143 {
144 int64_t value = defaultValue;
145 if (napi_get_value_int64(env, param, &value) == napi_ok) {
146 return value;
147 } else {
148 return defaultValue;
149 }
150 }
151
UnwrapInt64FromJS2(napi_env env,napi_value param,int64_t & value)152 bool UnwrapInt64FromJS2(napi_env env, napi_value param, int64_t &value)
153 {
154 bool result = false;
155 if (napi_get_value_int64(env, param, &value) == napi_ok) {
156 result = true;
157 }
158 return result;
159 }
160
WrapBoolToJS(napi_env env,bool value)161 napi_value WrapBoolToJS(napi_env env, bool value)
162 {
163 napi_value result = nullptr;
164 NAPI_CALL(env, napi_get_boolean(env, value, &result));
165 return result;
166 }
167
UnwrapBoolFromJS(napi_env env,napi_value param,bool defaultValue)168 bool UnwrapBoolFromJS(napi_env env, napi_value param, bool defaultValue)
169 {
170 bool value = defaultValue;
171 if (napi_get_value_bool(env, param, &value) == napi_ok) {
172 return value;
173 } else {
174 return defaultValue;
175 }
176 }
177
UnwrapBoolFromJS2(napi_env env,napi_value param,bool & value)178 bool UnwrapBoolFromJS2(napi_env env, napi_value param, bool &value)
179 {
180 bool result = false;
181 if (napi_get_value_bool(env, param, &value) == napi_ok) {
182 result = true;
183 }
184 return result;
185 }
186
WrapDoubleToJS(napi_env env,double value)187 napi_value WrapDoubleToJS(napi_env env, double value)
188 {
189 napi_value result = nullptr;
190 NAPI_CALL(env, napi_create_double(env, value, &result));
191 return result;
192 }
193
UnwrapDoubleFromJS(napi_env env,napi_value param,double defaultValue)194 double UnwrapDoubleFromJS(napi_env env, napi_value param, double defaultValue)
195 {
196 double value = defaultValue;
197 if (napi_get_value_double(env, param, &value) == napi_ok) {
198 return value;
199 } else {
200 return defaultValue;
201 }
202 }
203
UnwrapDoubleFromJS2(napi_env env,napi_value param,double & value)204 bool UnwrapDoubleFromJS2(napi_env env, napi_value param, double &value)
205 {
206 bool result = false;
207 if (napi_get_value_double(env, param, &value) == napi_ok) {
208 result = true;
209 }
210 return result;
211 }
212
WrapStringToJS(napi_env env,const std::string & value)213 napi_value WrapStringToJS(napi_env env, const std::string &value)
214 {
215 napi_value result = nullptr;
216 NAPI_CALL(env, napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result));
217 return result;
218 }
219
UnwrapStringFromJS(napi_env env,napi_value param,const std::string & defaultValue)220 std::string UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue)
221 {
222 TAG_LOGD(AAFwkTag::JSNAPI, "UnwrapStringFromJS enter");
223 size_t size = 0;
224 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
225 return defaultValue;
226 }
227
228 std::string value("");
229 if (size == 0) {
230 TAG_LOGD(AAFwkTag::JSNAPI, "size is 0");
231 return defaultValue;
232 }
233
234 char *buf = new (std::nothrow) char[size + 1];
235 if (buf == nullptr) {
236 TAG_LOGD(AAFwkTag::JSNAPI, "buf is nullptr");
237 return value;
238 }
239 (void)memset_s(buf, size + 1, 0, size + 1);
240
241 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
242 if (rev) {
243 value = buf;
244 } else {
245 value = defaultValue;
246 }
247
248 delete[] buf;
249 buf = nullptr;
250 return value;
251 }
252
UnwrapStringFromJS2(napi_env env,napi_value param,std::string & value)253 bool UnwrapStringFromJS2(napi_env env, napi_value param, std::string &value)
254 {
255 value = "";
256 size_t size = 0;
257 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
258 return false;
259 }
260
261 if (size == 0) {
262 return true;
263 }
264
265 char *buf = new (std::nothrow) char[size + 1];
266 if (buf == nullptr) {
267 return false;
268 }
269 (void)memset_s(buf, (size + 1), 0, (size + 1));
270
271 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
272 if (rev) {
273 value = buf;
274 }
275 delete[] buf;
276 buf = nullptr;
277 return rev;
278 }
279
WrapArrayInt32ToJS(napi_env env,const std::vector<int> & value)280 napi_value WrapArrayInt32ToJS(napi_env env, const std::vector<int> &value)
281 {
282 TAG_LOGD(AAFwkTag::JSNAPI, "called");
283 napi_value jsArray = nullptr;
284 napi_value jsValue = nullptr;
285 uint32_t index = 0;
286
287 NAPI_CALL(env, napi_create_array(env, &jsArray));
288 for (uint32_t i = 0; i < value.size(); i++) {
289 jsValue = nullptr;
290 if (napi_create_int32(env, value[i], &jsValue) == napi_ok) {
291 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
292 index++;
293 }
294 }
295 }
296 return jsArray;
297 }
298
UnwrapArrayInt32FromJS(napi_env env,napi_value param,std::vector<int> & value)299 bool UnwrapArrayInt32FromJS(napi_env env, napi_value param, std::vector<int> &value)
300 {
301 uint32_t arraySize = 0;
302 napi_value jsValue = nullptr;
303 int natValue = 0;
304
305 if (!IsArrayForNapiValue(env, param, arraySize)) {
306 TAG_LOGD(AAFwkTag::JSNAPI, "arraySize Expanding ArrayInt32 from JS failed");
307 return false;
308 }
309
310 value.clear();
311 for (uint32_t i = 0; i < arraySize; i++) {
312 jsValue = nullptr;
313 natValue = 0;
314 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
315 TAG_LOGD(AAFwkTag::JSNAPI, "array item Expanding ArrayInt32 from JS failed");
316 return false;
317 }
318
319 if (!UnwrapInt32FromJS2(env, jsValue, natValue)) {
320 return false;
321 }
322
323 value.push_back(natValue);
324 }
325 return true;
326 }
327
WrapArrayLongToJS(napi_env env,const std::vector<long> & value)328 napi_value WrapArrayLongToJS(napi_env env, const std::vector<long> &value)
329 {
330 napi_value jsArray = nullptr;
331 napi_value jsValue = nullptr;
332 uint32_t index = 0;
333
334 NAPI_CALL(env, napi_create_array(env, &jsArray));
335 for (uint32_t i = 0; i < value.size(); i++) {
336 jsValue = nullptr;
337 if (napi_create_int32(env, (int)(value[i]), &jsValue) == napi_ok) {
338 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
339 index++;
340 }
341 }
342 }
343 return jsArray;
344 }
345
UnwrapArrayLongFromJS(napi_env env,napi_value param,std::vector<long> & value)346 bool UnwrapArrayLongFromJS(napi_env env, napi_value param, std::vector<long> &value)
347 {
348 uint32_t arraySize = 0;
349 napi_value jsValue = nullptr;
350 long natValue = 0;
351
352 if (!IsArrayForNapiValue(env, param, arraySize)) {
353 TAG_LOGD(AAFwkTag::JSNAPI, "arraySize Expanding ArrayInt32 from JS failed.");
354 return false;
355 }
356
357 value.clear();
358 for (uint32_t i = 0; i < arraySize; i++) {
359 jsValue = nullptr;
360 natValue = 0;
361 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
362 TAG_LOGD(AAFwkTag::JSNAPI, "array item Expanding ArrayInt32 from JS failed.");
363 return false;
364 }
365
366 if (!UnwrapLongFromJS2(env, jsValue, natValue)) {
367 return false;
368 }
369
370 value.push_back(natValue);
371 }
372 return true;
373 }
374
WrapArrayInt64ToJS(napi_env env,const std::vector<int64_t> & value)375 napi_value WrapArrayInt64ToJS(napi_env env, const std::vector<int64_t> &value)
376 {
377 napi_value jsArray = nullptr;
378 napi_value jsValue = nullptr;
379 uint32_t index = 0;
380
381 NAPI_CALL(env, napi_create_array(env, &jsArray));
382 for (uint32_t i = 0; i < value.size(); i++) {
383 jsValue = nullptr;
384 if (napi_create_int64(env, value[i], &jsValue) == napi_ok) {
385 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
386 index++;
387 }
388 }
389 }
390 return jsArray;
391 }
392
UnwrapArrayInt64FromJS(napi_env env,napi_value param,std::vector<int64_t> & value)393 bool UnwrapArrayInt64FromJS(napi_env env, napi_value param, std::vector<int64_t> &value)
394 {
395 uint32_t arraySize = 0;
396 napi_value jsValue = nullptr;
397 int64_t natValue = 0;
398
399 if (!IsArrayForNapiValue(env, param, arraySize)) {
400 TAG_LOGD(AAFwkTag::JSNAPI, "arraySize Expanding ArrayInt32 from JS error");
401 return false;
402 }
403
404 value.clear();
405 for (uint32_t i = 0; i < arraySize; i++) {
406 jsValue = nullptr;
407 natValue = 0;
408 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
409 TAG_LOGD(AAFwkTag::JSNAPI, "array item Expanding ArrayInt32 from JS error");
410 return false;
411 }
412
413 if (!UnwrapInt64FromJS2(env, jsValue, natValue)) {
414 return false;
415 }
416
417 value.push_back(natValue);
418 }
419 return true;
420 }
421
WrapArrayDoubleToJS(napi_env env,const std::vector<double> & value)422 napi_value WrapArrayDoubleToJS(napi_env env, const std::vector<double> &value)
423 {
424 napi_value jsArray = nullptr;
425 napi_value jsValue = nullptr;
426 uint32_t index = 0;
427
428 NAPI_CALL(env, napi_create_array(env, &jsArray));
429 for (uint32_t i = 0; i < value.size(); i++) {
430 jsValue = nullptr;
431 if (napi_create_double(env, value[i], &jsValue) == napi_ok) {
432 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
433 index++;
434 }
435 }
436 }
437 return jsArray;
438 }
439
UnwrapArrayDoubleFromJS(napi_env env,napi_value param,std::vector<double> & value)440 bool UnwrapArrayDoubleFromJS(napi_env env, napi_value param, std::vector<double> &value)
441 {
442 uint32_t arraySize = 0;
443 napi_value jsValue = nullptr;
444 double natValue = 0;
445
446 if (!IsArrayForNapiValue(env, param, arraySize)) {
447 TAG_LOGD(AAFwkTag::JSNAPI, "arraySize Expanding ArrayInt32 from JS error");
448 return false;
449 }
450
451 value.clear();
452 for (uint32_t i = 0; i < arraySize; i++) {
453 jsValue = nullptr;
454 natValue = 0;
455 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
456 TAG_LOGD(AAFwkTag::JSNAPI, "array item Expanding ArrayInt32 from JS error");
457 return false;
458 }
459
460 if (!UnwrapDoubleFromJS2(env, jsValue, natValue)) {
461 return false;
462 }
463
464 value.push_back(natValue);
465 }
466 return true;
467 }
468
WrapArrayBoolToJS(napi_env env,const std::vector<bool> & value)469 napi_value WrapArrayBoolToJS(napi_env env, const std::vector<bool> &value)
470 {
471 napi_value jsArray = nullptr;
472 napi_value jsValue = nullptr;
473 uint32_t index = 0;
474
475 NAPI_CALL(env, napi_create_array(env, &jsArray));
476 for (uint32_t i = 0; i < value.size(); i++) {
477 jsValue = nullptr;
478 if (napi_get_boolean(env, value[i], &jsValue) == napi_ok) {
479 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
480 index++;
481 }
482 }
483 }
484 return jsArray;
485 }
486
UnwrapArrayBoolFromJS(napi_env env,napi_value param,std::vector<bool> & value)487 bool UnwrapArrayBoolFromJS(napi_env env, napi_value param, std::vector<bool> &value)
488 {
489 uint32_t arraySize = 0;
490 napi_value jsValue = nullptr;
491 bool natValue = 0;
492
493 if (!IsArrayForNapiValue(env, param, arraySize)) {
494 return false;
495 }
496
497 value.clear();
498 for (uint32_t i = 0; i < arraySize; i++) {
499 jsValue = nullptr;
500 natValue = 0;
501 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
502 return false;
503 }
504
505 if (!UnwrapBoolFromJS2(env, jsValue, natValue)) {
506 return false;
507 }
508
509 value.push_back(natValue);
510 }
511 return true;
512 }
513
WrapArrayStringToJS(napi_env env,const std::vector<std::string> & value)514 napi_value WrapArrayStringToJS(napi_env env, const std::vector<std::string> &value)
515 {
516 napi_value jsArray = nullptr;
517 napi_value jsValue = nullptr;
518 uint32_t index = 0;
519
520 NAPI_CALL(env, napi_create_array(env, &jsArray));
521 for (uint32_t i = 0; i < value.size(); i++) {
522 jsValue = nullptr;
523 if (napi_create_string_utf8(env, value[i].c_str(), NAPI_AUTO_LENGTH, &jsValue) == napi_ok) {
524 if (napi_set_element(env, jsArray, index, jsValue) == napi_ok) {
525 index++;
526 }
527 }
528 }
529 return jsArray;
530 }
531
UnwrapArrayStringFromJS(napi_env env,napi_value param,std::vector<std::string> & value)532 bool UnwrapArrayStringFromJS(napi_env env, napi_value param, std::vector<std::string> &value)
533 {
534 uint32_t arraySize = 0;
535 napi_value jsValue = nullptr;
536 std::string natValue("");
537
538 if (!IsArrayForNapiValue(env, param, arraySize)) {
539 return false;
540 }
541
542 value.clear();
543 for (uint32_t i = 0; i < arraySize; i++) {
544 jsValue = nullptr;
545 natValue = "";
546 if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
547 return false;
548 }
549
550 if (!UnwrapStringFromJS2(env, jsValue, natValue)) {
551 return false;
552 }
553
554 value.push_back(natValue);
555 }
556 return true;
557 }
558
UnwrapArrayComplexFromJSNumber(napi_env env,ComplexArrayData & value,bool isDouble,napi_value jsValue)559 bool UnwrapArrayComplexFromJSNumber(napi_env env, ComplexArrayData &value, bool isDouble, napi_value jsValue)
560 {
561 int32_t elementInt32 = 0;
562 double elementDouble = 0.0;
563 if (isDouble) {
564 if (napi_get_value_double(env, jsValue, &elementDouble) == napi_ok) {
565 value.doubleList.push_back(elementDouble);
566 }
567 return isDouble;
568 }
569
570 bool isReadValue32 = napi_get_value_int32(env, jsValue, &elementInt32) == napi_ok;
571 bool isReadDouble = napi_get_value_double(env, jsValue, &elementDouble) == napi_ok;
572 if (isReadValue32 && isReadDouble) {
573 if (abs(elementDouble - elementInt32 * 1.0) > 0.0) {
574 isDouble = true;
575 if (value.intList.size() > 0) {
576 for (size_t j = 0; j < value.intList.size(); j++) {
577 value.doubleList.push_back(value.intList[j]);
578 }
579 value.intList.clear();
580 }
581 value.doubleList.push_back(elementDouble);
582 } else {
583 value.intList.push_back(elementInt32);
584 }
585 } else if (isReadValue32) {
586 value.intList.push_back(elementInt32);
587 } else if (isReadDouble) {
588 isDouble = true;
589 if (value.intList.size() > 0) {
590 for (size_t j = 0; j < value.intList.size(); j++) {
591 value.doubleList.push_back(value.intList[j]);
592 }
593 value.intList.clear();
594 }
595 value.doubleList.push_back(elementDouble);
596 }
597 return isDouble;
598 }
599
UnwrapArrayComplexFromJS(napi_env env,napi_value param,ComplexArrayData & value)600 bool UnwrapArrayComplexFromJS(napi_env env, napi_value param, ComplexArrayData &value)
601 {
602 uint32_t arraySize = 0;
603 if (!IsArrayForNapiValue(env, param, arraySize)) {
604 return false;
605 }
606
607 napi_valuetype valueType = napi_undefined;
608 napi_value jsValue = nullptr;
609 bool isDouble = false;
610
611 value.intList.clear();
612 value.longList.clear();
613 value.boolList.clear();
614 value.doubleList.clear();
615 value.stringList.clear();
616 value.objectList.clear();
617
618 for (uint32_t i = 0; i < arraySize; i++) {
619 jsValue = nullptr;
620 valueType = napi_undefined;
621 NAPI_CALL_BASE(env, napi_get_element(env, param, i, &jsValue), false);
622 NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &valueType), false);
623 switch (valueType) {
624 case napi_string: {
625 std::string elementValue("");
626 if (UnwrapStringFromJS2(env, jsValue, elementValue)) {
627 value.stringList.push_back(elementValue);
628 } else {
629 return false;
630 }
631 break;
632 }
633 case napi_boolean: {
634 bool elementValue = false;
635 NAPI_CALL_BASE(env, napi_get_value_bool(env, jsValue, &elementValue), false);
636 value.boolList.push_back(elementValue);
637 break;
638 }
639 case napi_number: {
640 isDouble = UnwrapArrayComplexFromJSNumber(env, value, isDouble, jsValue);
641 break;
642 }
643 case napi_object: {
644 value.objectList.push_back(jsValue);
645 break;
646 }
647 default:
648 break;
649 }
650 }
651 return true;
652 }
653
654 /**
655 * @brief Indicates the specified attribute exists in the object passed by JS.
656 *
657 * @param env The environment that the Node-API call is invoked under.
658 * @param jsObject Indicates object passed by JS.
659 * @param propertyName Indicates the name of the property.
660 *
661 * @return Returns true if the attribute exists, else returns false.
662 */
IsExistsByPropertyName(napi_env env,napi_value jsObject,const char * propertyName)663 bool IsExistsByPropertyName(napi_env env, napi_value jsObject, const char *propertyName)
664 {
665 bool result = false;
666 if (napi_has_named_property(env, jsObject, propertyName, &result) == napi_ok) {
667 return result;
668 } else {
669 return false;
670 }
671 }
672
673 /**
674 * @brief Get the JSValue of the specified name from the JS object.
675 *
676 * @param env The environment that the Node-API call is invoked under.
677 * @param jsObject Indicates object passed by JS.
678 * @param propertyName Indicates the name of the property.
679 * @param expectType Indicates expected JS data type.
680 *
681 * @return Return the property value of the specified property name int jsObject on success, otherwise return nullptr.
682 */
GetPropertyValueByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,napi_valuetype expectType)683 napi_value GetPropertyValueByPropertyName(
684 napi_env env, napi_value jsObject, const char *propertyName, napi_valuetype expectType)
685 {
686 napi_value value = nullptr;
687 if (IsExistsByPropertyName(env, jsObject, propertyName) == false) {
688 return nullptr;
689 }
690
691 if (napi_get_named_property(env, jsObject, propertyName, &value) != napi_ok) {
692 return nullptr;
693 }
694
695 if (!IsTypeForNapiValue(env, value, expectType)) {
696 return nullptr;
697 }
698
699 return value;
700 }
701
SetPropertyValueByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,napi_value value)702 bool SetPropertyValueByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, napi_value value)
703 {
704 if (value != nullptr && propertyName != nullptr) {
705 NAPI_CALL_BASE(env, napi_set_named_property(env, jsObject, propertyName, value), false);
706 return true;
707 }
708 return false;
709 }
710
711 /**
712 * @brief Get the native number(int32) from the JSObject of the given property name.
713 *
714 * @param env The environment that the Node-API call is invoked under.
715 * @param jsObject Indicates object passed by JS.
716 * @param propertyName Indicates the name of the property.
717 * @param value Indicates the returned native value.
718 *
719 * @return Return true if successful, else return false.
720 */
UnwrapInt32ByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,int32_t & value)721 bool UnwrapInt32ByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, int32_t &value)
722 {
723 napi_value jsValue = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_number);
724 if (jsValue != nullptr) {
725 return UnwrapInt32FromJS2(env, jsValue, value);
726 } else {
727 return false;
728 }
729 }
730
731 /**
732 * @brief Get the native number(double) from the JSObject of the given property name.
733 *
734 * @param env The environment that the Node-API call is invoked under.
735 * @param jsObject Indicates object passed by JS.
736 * @param propertyName Indicates the name of the property.
737 * @param value Indicates the returned native value.
738 *
739 * @return Return true if successful, else return false.
740 */
UnwrapDoubleByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,double & value)741 bool UnwrapDoubleByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, double &value)
742 {
743 napi_value jsValue = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_number);
744 if (jsValue != nullptr) {
745 return UnwrapDoubleFromJS2(env, jsValue, value);
746 } else {
747 return false;
748 }
749 }
750
751 /**
752 * @brief Get the native boolean from the JSObject of the given property name.
753 *
754 * @param env The environment that the Node-API call is invoked under.
755 * @param jsObject Indicates object passed by JS.
756 * @param propertyName Indicates the name of the property.
757 * @param value Indicates the returned native value.
758 *
759 * @return Return true if successful, else return false.
760 */
UnwrapBooleanByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,bool & value)761 bool UnwrapBooleanByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, bool &value)
762 {
763 napi_value jsValue = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_boolean);
764 if (jsValue != nullptr) {
765 return UnwrapBoolFromJS2(env, jsValue, value);
766 } else {
767 return false;
768 }
769 }
770
UnwrapBooleanArrayByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,std::vector<bool> & value)771 bool UnwrapBooleanArrayByPropertyName(
772 napi_env env, napi_value jsObject, const char *propertyName, std::vector<bool> &value)
773 {
774 napi_value jsArray = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_object);
775 if (jsArray == nullptr) {
776 return false;
777 }
778
779 return UnwrapArrayBoolFromJS(env, jsArray, value);
780 }
781
782 /**
783 * @brief Get the native string from the JSObject of the given property name.
784 *
785 * @param env The environment that the Node-API call is invoked under.
786 * @param jsObject Indicates object passed by JS.
787 * @param propertyName Indicates the name of the property.
788 * @param value Indicates the returned native value.
789 *
790 * @return Return true if successful, else return false.
791 */
UnwrapStringByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,std::string & value)792 bool UnwrapStringByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, std::string &value)
793 {
794 napi_value jsValue = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_string);
795 if (jsValue != nullptr) {
796 return UnwrapStringFromJS2(env, jsValue, value);
797 } else {
798 return false;
799 }
800 }
801
UnwrapStringArrayByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,std::vector<std::string> & value)802 bool UnwrapStringArrayByPropertyName(
803 napi_env env, napi_value jsObject, const char *propertyName, std::vector<std::string> &value)
804 {
805 napi_value jsArray = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_object);
806 if (jsArray == nullptr) {
807 return false;
808 }
809
810 return UnwrapArrayStringFromJS(env, jsArray, value);
811 }
812
UnwrapComplexArrayByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,ComplexArrayData & value)813 bool UnwrapComplexArrayByPropertyName(
814 napi_env env, napi_value jsObject, const char *propertyName, ComplexArrayData &value)
815 {
816 napi_value jsArray = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_object);
817 if (jsArray == nullptr) {
818 return false;
819 }
820
821 return UnwrapArrayComplexFromJS(env, jsArray, value);
822 }
823
ClearThreadReturnData(ThreadReturnData * data)824 void ClearThreadReturnData(ThreadReturnData *data)
825 {
826 if (data != nullptr) {
827 data->data_type = NVT_NONE;
828 data->int32_value = 0;
829 data->bool_value = false;
830 data->str_value = "";
831 data->double_value = 0.0;
832 }
833 }
834
GetCallbackErrorValue(napi_env env,int errCode)835 napi_value GetCallbackErrorValue(napi_env env, int errCode)
836 {
837 napi_value jsObject = nullptr;
838 napi_value jsValue = nullptr;
839 NAPI_CALL(env, napi_create_int32(env, errCode, &jsValue));
840 NAPI_CALL(env, napi_create_object(env, &jsObject));
841 NAPI_CALL(env, napi_set_named_property(env, jsObject, "code", jsValue));
842 return jsObject;
843 }
844
845 /**
846 * @brief Create asynchronous data.
847 *
848 * @param env The environment that the Node-API call is invoked under.
849 *
850 * @return Return a pointer to AsyncPermissionCallbackInfo on success, nullptr on failure
851 */
CreateAsyncJSCallbackInfo(napi_env env)852 AsyncJSCallbackInfo *CreateAsyncJSCallbackInfo(napi_env env)
853 {
854 TAG_LOGI(AAFwkTag::JSNAPI, "called");
855
856 napi_value global = nullptr;
857 NAPI_CALL(env, napi_get_global(env, &global));
858
859 napi_value abilityObj = nullptr;
860 NAPI_CALL(env, napi_get_named_property(env, global, "ability", &abilityObj));
861
862 Ability *ability = nullptr;
863 NAPI_CALL(env, napi_get_value_external(env, abilityObj, reinterpret_cast<void **>(&ability)));
864
865 AsyncJSCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncJSCallbackInfo;
866 if (asyncCallbackInfo == nullptr) {
867 TAG_LOGE(AAFwkTag::JSNAPI, "null asyncCallbackInfo");
868 return nullptr;
869 }
870 asyncCallbackInfo->cbInfo.env = env;
871 asyncCallbackInfo->cbInfo.callback = nullptr;
872 asyncCallbackInfo->asyncWork = nullptr;
873 asyncCallbackInfo->deferred = nullptr;
874 asyncCallbackInfo->ability = ability;
875 asyncCallbackInfo->abilityType = AbilityType::UNKNOWN;
876 asyncCallbackInfo->aceCallback = nullptr;
877
878 if (asyncCallbackInfo != nullptr) {
879 ClearThreadReturnData(&asyncCallbackInfo->native_data);
880 }
881 return asyncCallbackInfo;
882 }
883
FreeAsyncJSCallbackInfo(AsyncJSCallbackInfo ** asyncCallbackInfo)884 void FreeAsyncJSCallbackInfo(AsyncJSCallbackInfo **asyncCallbackInfo)
885 {
886 if (asyncCallbackInfo == nullptr) {
887 return;
888 }
889 if (*asyncCallbackInfo == nullptr) {
890 return;
891 }
892
893 if ((*asyncCallbackInfo)->cbInfo.callback != nullptr && (*asyncCallbackInfo)->cbInfo.env != nullptr) {
894 napi_delete_reference((*asyncCallbackInfo)->cbInfo.env, (*asyncCallbackInfo)->cbInfo.callback);
895 (*asyncCallbackInfo)->cbInfo.callback = nullptr;
896 (*asyncCallbackInfo)->cbInfo.env = nullptr;
897 }
898
899 delete (*asyncCallbackInfo);
900 *asyncCallbackInfo = nullptr;
901 }
902
903 /**
904 * @brief Convert local data to JS data.
905 *
906 * @param env The environment that the Node-API call is invoked under.
907 * @param data The local data.
908 * @param value the JS data.
909 *
910 * @return The return value from NAPI C++ to JS for the module.
911 */
WrapThreadReturnData(napi_env env,const ThreadReturnData * data,napi_value * value)912 bool WrapThreadReturnData(napi_env env, const ThreadReturnData *data, napi_value *value)
913 {
914 if (data == nullptr || value == nullptr) {
915 return false;
916 }
917
918 switch (data->data_type) {
919 case NVT_UNDEFINED:
920 NAPI_CALL_BASE(env, napi_get_undefined(env, value), false);
921 break;
922 case NVT_INT32:
923 NAPI_CALL_BASE(env, napi_create_int32(env, data->int32_value, value), false);
924 break;
925 case NVT_BOOL:
926 NAPI_CALL_BASE(env, napi_get_boolean(env, data->bool_value, value), false);
927 break;
928 case NVT_STRING:
929 NAPI_CALL_BASE(env, napi_create_string_utf8(env, data->str_value.c_str(), NAPI_AUTO_LENGTH, value), false);
930 break;
931 default:
932 NAPI_CALL_BASE(env, napi_get_null(env, value), false);
933 break;
934 }
935 return true;
936 }
937
938 /**
939 * @brief Create asynchronous data.
940 *
941 * @param env The environment that the Node-API call is invoked under.
942 * @param param Parameter list.
943 * @param callback Point to asynchronous processing of data.
944 *
945 * @return Return true successfully, otherwise return false.
946 */
CreateAsyncCallback(napi_env env,napi_value param,AsyncJSCallbackInfo * callback)947 bool CreateAsyncCallback(napi_env env, napi_value param, AsyncJSCallbackInfo *callback)
948 {
949 TAG_LOGI(AAFwkTag::JSNAPI, "called");
950
951 if (param == nullptr || callback == nullptr) {
952 TAG_LOGI(AAFwkTag::JSNAPI, "null param or callback");
953 return false;
954 }
955
956 callback->cbInfo.callback = CreateCallbackRefFromJS(env, param);
957 if (callback->cbInfo.callback == nullptr) {
958 TAG_LOGI(AAFwkTag::JSNAPI, "create ref failed");
959 return false;
960 }
961
962 return true;
963 }
964
CreateCallbackRefFromJS(napi_env env,napi_value param)965 napi_ref CreateCallbackRefFromJS(napi_env env, napi_value param)
966 {
967 if (env == nullptr || param == nullptr) {
968 TAG_LOGI(AAFwkTag::JSNAPI, "null env or param");
969 return nullptr;
970 }
971
972 napi_valuetype valueType = napi_undefined;
973 NAPI_CALL(env, napi_typeof(env, param, &valueType));
974
975 if (valueType != napi_function) {
976 TAG_LOGI(AAFwkTag::JSNAPI, "invalid param");
977 return nullptr;
978 }
979
980 napi_ref callbackRef = nullptr;
981 NAPI_CALL(env, napi_create_reference(env, param, 1, &callbackRef));
982 return callbackRef;
983 }
984
985 /**
986 * @brief Asynchronous callback processing.
987 *
988 * @param env The environment that the Node-API call is invoked under.
989 * @param asyncCallbackInfo Process data asynchronously.
990 * @param param other param.
991 *
992 * @return Return JS data successfully, otherwise return nullptr.
993 */
ExecuteAsyncCallbackWork(napi_env env,AsyncJSCallbackInfo * asyncCallbackInfo,const AsyncParamEx * param)994 napi_value ExecuteAsyncCallbackWork(napi_env env, AsyncJSCallbackInfo *asyncCallbackInfo, const AsyncParamEx *param)
995 {
996 TAG_LOGI(AAFwkTag::JSNAPI, "called");
997 if (asyncCallbackInfo == nullptr || param == nullptr) {
998 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo or param");
999 return nullptr;
1000 }
1001
1002 napi_value resourceName = nullptr;
1003 NAPI_CALL(env, napi_create_string_latin1(env, param->resource.c_str(), NAPI_AUTO_LENGTH, &resourceName));
1004
1005 NAPI_CALL(env,
1006 napi_create_async_work(env,
1007 nullptr,
1008 resourceName,
1009 param->execute,
1010 param->complete,
1011 static_cast<void *>(asyncCallbackInfo),
1012 &asyncCallbackInfo->asyncWork));
1013
1014 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1015
1016 return WrapVoidToJS(env);
1017 }
1018
1019 /**
1020 * @brief Asynchronous promise processing.
1021 *
1022 * @param env The environment that the Node-API call is invoked under.
1023 * @param asyncCallbackInfo Process data asynchronously.
1024 * @param param other param.
1025 *
1026 * @return Return JS data successfully, otherwise return nullptr.
1027 */
ExecutePromiseCallbackWork(napi_env env,AsyncJSCallbackInfo * asyncCallbackInfo,const AsyncParamEx * param)1028 napi_value ExecutePromiseCallbackWork(napi_env env, AsyncJSCallbackInfo *asyncCallbackInfo, const AsyncParamEx *param)
1029 {
1030 TAG_LOGI(AAFwkTag::JSNAPI, "called");
1031 if (asyncCallbackInfo == nullptr || param == nullptr) {
1032 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo or param");
1033 return nullptr;
1034 }
1035
1036 napi_value resourceName = nullptr;
1037 NAPI_CALL(env, napi_create_string_latin1(env, param->resource.c_str(), NAPI_AUTO_LENGTH, &resourceName));
1038
1039 napi_deferred deferred = nullptr;
1040 napi_value promise = nullptr;
1041 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1042
1043 asyncCallbackInfo->deferred = deferred;
1044 NAPI_CALL(env,
1045 napi_create_async_work(env,
1046 nullptr,
1047 resourceName,
1048 param->execute,
1049 param->complete,
1050 static_cast<void *>(asyncCallbackInfo),
1051 &asyncCallbackInfo->asyncWork));
1052
1053 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
1054 return promise;
1055 }
1056
1057 /**
1058 * @brief The callback at the end of the asynchronous callback.
1059 *
1060 * @param env The environment that the Node-API call is invoked under.
1061 * @param data Point to asynchronous processing of data.
1062 */
CompleteAsyncCallbackWork(napi_env env,napi_status status,void * data)1063 void CompleteAsyncCallbackWork(napi_env env, napi_status status, void *data)
1064 {
1065 TAG_LOGI(AAFwkTag::JSNAPI, "called");
1066
1067 AsyncJSCallbackInfo *asyncCallbackInfo = static_cast<AsyncJSCallbackInfo *>(data);
1068 if (asyncCallbackInfo == nullptr) {
1069 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo");
1070 return;
1071 }
1072
1073 napi_value callback = nullptr;
1074 napi_value undefined = nullptr;
1075 napi_get_undefined(env, &undefined);
1076 napi_value callResult = nullptr;
1077 napi_value revParam[ARGS_TWO] = {nullptr};
1078
1079 revParam[PARAM0] = GetCallbackErrorValue(env, asyncCallbackInfo->error_code);
1080 WrapThreadReturnData(env, &asyncCallbackInfo->native_data, &revParam[PARAM1]);
1081
1082 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
1083 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
1084 napi_call_function(env, undefined, callback, ARGS_TWO, revParam, &callResult);
1085 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
1086 }
1087
1088 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1089 delete asyncCallbackInfo;
1090 asyncCallbackInfo = nullptr;
1091 }
1092
CompleteAsyncVoidCallbackWork(napi_env env,napi_status status,void * data)1093 void CompleteAsyncVoidCallbackWork(napi_env env, napi_status status, void *data)
1094 {
1095 TAG_LOGI(AAFwkTag::JSNAPI, "called");
1096 AsyncJSCallbackInfo *asyncCallbackInfo = static_cast<AsyncJSCallbackInfo *>(data);
1097 if (asyncCallbackInfo == nullptr) {
1098 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo");
1099 return;
1100 }
1101 napi_value callback = nullptr;
1102 napi_value undefined = nullptr;
1103 napi_get_undefined(env, &undefined);
1104 napi_value callResult = nullptr;
1105 napi_value result[ARGS_TWO] = {nullptr};
1106
1107 if (asyncCallbackInfo->error_code) {
1108 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncCallbackInfo->error_code, &result[PARAM0]));
1109 }
1110
1111 if (asyncCallbackInfo->error_code == NAPI_ERR_NO_ERROR) {
1112 result[PARAM1] = WrapVoidToJS(env);
1113 } else {
1114 result[PARAM1] = WrapUndefinedToJS(env);
1115 }
1116 if (asyncCallbackInfo->cbInfo.callback != nullptr) {
1117 napi_get_reference_value(env, asyncCallbackInfo->cbInfo.callback, &callback);
1118 napi_call_function(env, undefined, callback, ARGS_TWO, result, &callResult);
1119 napi_delete_reference(env, asyncCallbackInfo->cbInfo.callback);
1120 }
1121
1122 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1123 delete asyncCallbackInfo;
1124 asyncCallbackInfo = nullptr;
1125 }
1126
1127 /**
1128 * @brief The callback at the end of the Promise callback.
1129 *
1130 * @param env The environment that the Node-API call is invoked under.
1131 * @param data Point to asynchronous processing of data.
1132 */
CompletePromiseCallbackWork(napi_env env,napi_status status,void * data)1133 void CompletePromiseCallbackWork(napi_env env, napi_status status, void *data)
1134 {
1135 TAG_LOGI(AAFwkTag::JSNAPI, "called");
1136
1137 AsyncJSCallbackInfo *asyncCallbackInfo = static_cast<AsyncJSCallbackInfo *>(data);
1138 if (asyncCallbackInfo == nullptr) {
1139 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo");
1140 return;
1141 }
1142
1143 napi_value result = nullptr;
1144 if (asyncCallbackInfo->error_code == NAPI_ERR_NO_ERROR) {
1145 WrapThreadReturnData(env, &asyncCallbackInfo->native_data, &result);
1146 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1147 } else {
1148 result = GetCallbackErrorValue(env, asyncCallbackInfo->error_code);
1149 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1150 }
1151 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1152 delete asyncCallbackInfo;
1153 asyncCallbackInfo = nullptr;
1154 }
1155
CompletePromiseVoidCallbackWork(napi_env env,napi_status status,void * data)1156 void CompletePromiseVoidCallbackWork(napi_env env, napi_status status, void *data)
1157 {
1158 TAG_LOGI(AAFwkTag::JSNAPI, "called");
1159
1160 AsyncJSCallbackInfo *asyncCallbackInfo = static_cast<AsyncJSCallbackInfo *>(data);
1161 if (asyncCallbackInfo == nullptr) {
1162 TAG_LOGI(AAFwkTag::JSNAPI, "null asyncCallbackInfo");
1163 return;
1164 }
1165 napi_value result = nullptr;
1166 if (asyncCallbackInfo->error_code == NAPI_ERR_NO_ERROR) {
1167 result = WrapVoidToJS(env);
1168 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
1169 } else {
1170 result = GetCallbackErrorValue(env, asyncCallbackInfo->error_code);
1171 napi_reject_deferred(env, asyncCallbackInfo->deferred, result);
1172 }
1173 napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
1174 delete asyncCallbackInfo;
1175 asyncCallbackInfo = nullptr;
1176 }
1177
ConvertU8Vector(napi_env env,napi_value jsValue)1178 std::vector<uint8_t> ConvertU8Vector(napi_env env, napi_value jsValue)
1179 {
1180 bool isTypedArray = false;
1181 if (napi_is_typedarray(env, jsValue, &isTypedArray) != napi_ok || !isTypedArray) {
1182 return {};
1183 }
1184
1185 napi_typedarray_type type;
1186 size_t length = 0;
1187 napi_value buffer = nullptr;
1188 size_t offset = 0;
1189 NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
1190 if (type != napi_uint8_array) {
1191 return {};
1192 }
1193 uint8_t *data = nullptr;
1194 size_t total = 0;
1195 NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
1196 length = std::min<size_t>(length, total - offset);
1197 std::vector<uint8_t> result(sizeof(uint8_t) + length);
1198 int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
1199 if (retCode != 0) {
1200 return {};
1201 }
1202 return result;
1203 }
1204
ConvertStringVector(napi_env env,napi_value jsValue)1205 std::vector<std::string> ConvertStringVector(napi_env env, napi_value jsValue)
1206 {
1207 bool isTypedArray = false;
1208 napi_status status = napi_is_typedarray(env, jsValue, &isTypedArray);
1209 if (status != napi_ok || !isTypedArray) {
1210 TAG_LOGE(AAFwkTag::JSNAPI, "napi_is_typedarray error");
1211 return {};
1212 }
1213
1214 napi_typedarray_type type;
1215 size_t length = 0;
1216 napi_value buffer = nullptr;
1217 size_t offset = 0;
1218 NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
1219 if (type != napi_uint8_array) {
1220 TAG_LOGE(AAFwkTag::JSNAPI, "null napi_uint8_array");
1221 return {};
1222 }
1223 std::string *data = nullptr;
1224 size_t total = 0;
1225 NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
1226 length = std::min<size_t>(length, total - offset);
1227 std::vector<std::string> result(sizeof(std::string) + length);
1228 int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
1229 if (retCode != 0) {
1230 return {};
1231 }
1232 return result;
1233 }
1234 } // namespace AppExecFwk
1235 } // namespace OHOS
1236