1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "js_utils.h"
17
18 #include "js_logger.h"
19
20 #ifndef MAC_PLATFORM
21 #include "securec.h"
22 #endif
23
24 namespace OHOS {
25 namespace AppDataMgrJsKit {
Convert2String(napi_env env,napi_value jsStr,bool useDefaultBufSize)26 std::string JSUtils::Convert2String(napi_env env, napi_value jsStr, bool useDefaultBufSize)
27 {
28 size_t str_buffer_size = 0;
29 napi_get_value_string_utf8(env, jsStr, nullptr, 0, &str_buffer_size);
30 str_buffer_size = (useDefaultBufSize && (str_buffer_size > DEFAULT_BUF_SIZE))
31 ? (DEFAULT_BUF_SIZE + BUF_CACHE_MARGIN)
32 : (str_buffer_size + BUF_CACHE_MARGIN);
33 char *buf = new char[str_buffer_size + 1];
34 size_t len = 0;
35 napi_get_value_string_utf8(env, jsStr, buf, str_buffer_size, &len);
36 buf[len] = 0;
37 std::string value(buf);
38 delete[] buf;
39 return value;
40 }
41
Convert2String(napi_env env,napi_value jsStr,std::string & output)42 int32_t JSUtils::Convert2String(napi_env env, napi_value jsStr, std::string &output)
43 {
44 char *str = new char[MAX_VALUE_LENGTH + 1];
45 size_t valueSize = 0;
46 napi_status status = napi_get_value_string_utf8(env, jsStr, str, MAX_VALUE_LENGTH, &valueSize);
47 if (status != napi_ok) {
48 LOG_ERROR("JSUtils::Convert2String get jsVal failed, status = %{public}d", status);
49 return ERR;
50 }
51 output = (std::string)str;
52 delete[] str;
53 return OK;
54 }
55
Convert2Bool(napi_env env,napi_value jsBool,bool & output)56 int32_t JSUtils::Convert2Bool(napi_env env, napi_value jsBool, bool &output)
57 {
58 bool bValue = false;
59 napi_status status = napi_get_value_bool(env, jsBool, &bValue);
60 if (status != napi_ok) {
61 LOG_ERROR("JSUtils::Convert2Bool get jsVal failed, status = %{public}d", status);
62 return ERR;
63 }
64 output = bValue;
65 return OK;
66 }
67
Convert2Double(napi_env env,napi_value jsNum,double & output)68 int32_t JSUtils::Convert2Double(napi_env env, napi_value jsNum, double &output)
69 {
70 double number = 0.0;
71 napi_status status = napi_get_value_double(env, jsNum, &number);
72 if (status != napi_ok) {
73 LOG_ERROR("JSUtils::Convert2Double get jsVal failed, status = %{public}d", status);
74 return ERR;
75 }
76 output = number;
77 return OK;
78 }
79
Convert2StrVector(napi_env env,napi_value value)80 std::vector<std::string> JSUtils::Convert2StrVector(napi_env env, napi_value value)
81 {
82 uint32_t arrLen = 0;
83 napi_get_array_length(env, value, &arrLen);
84 if (arrLen == 0) {
85 return {};
86 }
87 std::vector<std::string> result;
88 for (size_t i = 0; i < arrLen; ++i) {
89 napi_value element;
90 napi_get_element(env, value, i, &element);
91 result.push_back(ConvertAny2String(env, element));
92 }
93 return result;
94 }
95
Convert2StrVector(napi_env env,napi_value value,std::vector<std::string> & output)96 int32_t JSUtils::Convert2StrVector(napi_env env, napi_value value, std::vector<std::string> &output)
97 {
98 uint32_t arrLen = 0;
99 napi_status status = napi_get_array_length(env, value, &arrLen);
100 if (status != napi_ok) {
101 LOG_ERROR("JSUtils::Convert2StrVector get arrLength failed, status = %{public}d", status);
102 output = {};
103 return ERR;
104 }
105 if (arrLen == 0) {
106 output = {};
107 return OK;
108 }
109 napi_value element = nullptr;
110 for (size_t i = 0; i < arrLen; ++i) {
111 status = napi_get_element(env, value, i, &element);
112 if (status != napi_ok) {
113 LOG_ERROR("JSUtils::Convert2StrVector get element failed, status = %{public}d", status);
114 return ERR;
115 }
116 std::string str;
117 if (Convert2String(env, element, str) != OK) {
118 LOG_ERROR("JSUtils::Convert2StrVector convert element failed");
119 return ERR;
120 }
121 output.push_back(str);
122 }
123 return OK;
124 }
125
Convert2BoolVector(napi_env env,napi_value value,std::vector<bool> & output)126 int32_t JSUtils::Convert2BoolVector(napi_env env, napi_value value, std::vector<bool> &output)
127 {
128 uint32_t arrLen = 0;
129 napi_status status = napi_get_array_length(env, value, &arrLen);
130 if (status != napi_ok) {
131 LOG_ERROR("JSUtils::Convert2BoolVector get arrLength failed, status = %{public}d", status);
132 output = {};
133 return ERR;
134 }
135 napi_value element = nullptr;
136 for (size_t i = 0; i < arrLen; ++i) {
137 status = napi_get_element(env, value, i, &element);
138 if (status != napi_ok) {
139 LOG_ERROR("JSUtils::Convert2BoolVector get element failed, status = %{public}d", status);
140 return ERR;
141 }
142 bool bVal = false;
143 if (Convert2Bool(env, element, bVal) != OK) {
144 LOG_ERROR("JSUtils::Convert2BoolVector convert element failed");
145 return ERR;
146 }
147 output.push_back(bVal);
148 }
149 return OK;
150 }
151
Convert2DoubleVector(napi_env env,napi_value value,std::vector<double> & output)152 int32_t JSUtils::Convert2DoubleVector(napi_env env, napi_value value, std::vector<double> &output)
153 {
154 uint32_t arrLen = 0;
155 napi_status status = napi_get_array_length(env, value, &arrLen);
156 if (status != napi_ok) {
157 LOG_ERROR("JSUtils::Convert2DoubleVector get arrLength failed, status = %{public}d", status);
158 output = {};
159 return ERR;
160 }
161 napi_value element = nullptr;
162 for (size_t i = 0; i < arrLen; ++i) {
163 status = napi_get_element(env, value, i, &element);
164 if (status != napi_ok) {
165 LOG_ERROR("JSUtils::Convert2DoubleVector get element failed, status = %{public}d", status);
166 return ERR;
167 }
168 double number = 0.0;
169 if (Convert2Double(env, element, number) != OK) {
170 LOG_ERROR("JSUtils::Convert2Double convert element failed");
171 return ERR;
172 }
173 output.push_back(number);
174 }
175 return OK;
176 }
177
Convert2U8Vector(napi_env env,napi_value input_array)178 std::vector<uint8_t> JSUtils::Convert2U8Vector(napi_env env, napi_value input_array)
179 {
180 bool isTypedArray = false;
181 napi_is_typedarray(env, input_array, &isTypedArray);
182 if (!isTypedArray) {
183 return {};
184 }
185
186 napi_typedarray_type type;
187 napi_value input_buffer = nullptr;
188 size_t byte_offset = 0;
189 size_t length = 0;
190 void *data = nullptr;
191 napi_get_typedarray_info(env, input_array, &type, &length, &data, &input_buffer, &byte_offset);
192 if (type != napi_uint8_array || data == nullptr) {
193 return {};
194 }
195 return std::vector<uint8_t>((uint8_t *)data, ((uint8_t *)data) + length);
196 }
197
ConvertAny2String(napi_env env,napi_value jsValue)198 std::string JSUtils::ConvertAny2String(napi_env env, napi_value jsValue)
199 {
200 napi_valuetype valueType = napi_undefined;
201 NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &valueType), "napi_typeof failed");
202 if (valueType == napi_string) {
203 return JSUtils::Convert2String(env, jsValue, false);
204 } else if (valueType == napi_number) {
205 double valueNumber;
206 napi_get_value_double(env, jsValue, &valueNumber);
207 return std::to_string(valueNumber);
208 } else if (valueType == napi_boolean) {
209 bool valueBool = false;
210 napi_get_value_bool(env, jsValue, &valueBool);
211 return std::to_string(valueBool);
212 } else if (valueType == napi_null) {
213 return "null";
214 } else if (valueType == napi_object) {
215 std::vector<uint8_t> bytes = JSUtils::Convert2U8Vector(env, jsValue);
216 std::string ret(bytes.begin(), bytes.end());
217 return ret;
218 }
219
220 return "invalid type";
221 }
222
Convert2JSValue(napi_env env,const std::vector<std::string> & value)223 napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector<std::string> &value)
224 {
225 napi_value jsValue;
226 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
227 if (status != napi_ok) {
228 return nullptr;
229 }
230
231 for (size_t i = 0; i < value.size(); ++i) {
232 napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
233 }
234 return jsValue;
235 }
236
Convert2JSValue(napi_env env,const std::string & value)237 napi_value JSUtils::Convert2JSValue(napi_env env, const std::string &value)
238 {
239 napi_value jsValue;
240 napi_status status = napi_create_string_utf8(env, value.c_str(), value.size(), &jsValue);
241 if (status != napi_ok) {
242 return nullptr;
243 }
244 return jsValue;
245 }
246
Convert2JSValue(napi_env env,const std::vector<uint8_t> & value)247 napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector<uint8_t> &value)
248 {
249 napi_value jsValue;
250 void *native = nullptr;
251 napi_value buffer = nullptr;
252 napi_status status = napi_create_arraybuffer(env, value.size(), &native, &buffer);
253 if (status != napi_ok) {
254 return nullptr;
255 }
256 #ifdef MAC_PLATFORM
257 for (int i = 0; i < value.size(); i++) {
258 *(static_cast<uint8_t *>(native) + i) = value[i];
259 }
260 #else
261 int result = memcpy_s(native, value.size(), value.data(), value.size());
262 if (result != EOK && value.size() > 0) {
263 return nullptr;
264 }
265 #endif
266
267 status = napi_create_typedarray(env, napi_uint8_array, value.size(), buffer, 0, &jsValue);
268 if (status != napi_ok) {
269 return nullptr;
270 }
271 return jsValue;
272 }
273
Convert2JSValue(napi_env env,int32_t value)274 napi_value JSUtils::Convert2JSValue(napi_env env, int32_t value)
275 {
276 napi_value jsValue;
277 napi_status status = napi_create_int32(env, value, &jsValue);
278 if (status != napi_ok) {
279 return nullptr;
280 }
281 return jsValue;
282 }
283
Convert2JSValue(napi_env env,int64_t value)284 napi_value JSUtils::Convert2JSValue(napi_env env, int64_t value)
285 {
286 napi_value jsValue;
287 napi_status status = napi_create_int64(env, value, &jsValue);
288 if (status != napi_ok) {
289 return nullptr;
290 }
291 return jsValue;
292 }
293
Convert2JSValue(napi_env env,double value)294 napi_value JSUtils::Convert2JSValue(napi_env env, double value)
295 {
296 napi_value jsValue;
297 napi_status status = napi_create_double(env, value, &jsValue);
298 if (status != napi_ok) {
299 return nullptr;
300 }
301 return jsValue;
302 }
303
Convert2JSValue(napi_env env,bool value)304 napi_value JSUtils::Convert2JSValue(napi_env env, bool value)
305 {
306 napi_value jsValue;
307 napi_status status = napi_get_boolean(env, value, &jsValue);
308 if (status != napi_ok) {
309 return nullptr;
310 }
311 return jsValue;
312 }
313
Convert2JSValue(napi_env env,const std::map<std::string,int> & value)314 napi_value JSUtils::Convert2JSValue(napi_env env, const std::map<std::string, int> &value)
315 {
316 napi_value jsValue;
317 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
318 if (status != napi_ok) {
319 return nullptr;
320 }
321
322 int index = 0;
323 for (const auto &[device, result] : value) {
324 napi_value jsElement;
325 status = napi_create_array_with_length(env, SYNC_RESULT_ELEMNT_NUM, &jsElement);
326 if (status != napi_ok) {
327 return nullptr;
328 }
329 napi_set_element(env, jsElement, 0, Convert2JSValue(env, device));
330 napi_set_element(env, jsElement, 1, Convert2JSValue(env, result));
331 napi_set_element(env, jsValue, index++, jsElement);
332 }
333
334 return jsValue;
335 }
336
Convert2JSValue(napi_env env,std::string value,napi_value & output)337 int32_t JSUtils::Convert2JSValue(napi_env env, std::string value, napi_value &output)
338 {
339 if (napi_create_string_utf8(env, value.c_str(), value.size(), &output) != napi_ok) {
340 LOG_ERROR("Convert2JSValue create JS string failed");
341 return ERR;
342 }
343 return OK;
344 }
345
Convert2JSValue(napi_env env,bool value,napi_value & output)346 int32_t JSUtils::Convert2JSValue(napi_env env, bool value, napi_value &output)
347 {
348 if (napi_get_boolean(env, value, &output) != napi_ok) {
349 LOG_ERROR("Convert2JSValue create JS bool failed");
350 return ERR;
351 }
352 return OK;
353 }
354
Convert2JSValue(napi_env env,double value,napi_value & output)355 int32_t JSUtils::Convert2JSValue(napi_env env, double value, napi_value &output)
356 {
357 if (napi_create_double(env, value, &output) != napi_ok) {
358 LOG_ERROR("Convert2JSValue create JS double failed");
359 return ERR;
360 }
361 return OK;
362 }
363
Convert2JSDoubleArr(napi_env env,std::vector<double> value,napi_value & output)364 int32_t JSUtils::Convert2JSDoubleArr(napi_env env, std::vector<double> value, napi_value &output)
365 {
366 size_t arrLen = value.size();
367 napi_status status = napi_create_array_with_length(env, arrLen, &output);
368 if (status != napi_ok) {
369 LOG_ERROR("JSUtils::Convert2JSValue get arrLength failed");
370 return ERR;
371 }
372 for (size_t i = 0; i < arrLen; i++) {
373 napi_value val = nullptr;
374 if (Convert2JSValue(env, value[i], val) != OK) {
375 LOG_ERROR("JSUtils::Convert2JSValue creat double failed");
376 return ERR;
377 }
378 status = napi_set_element(env, output, i, val);
379 if (status != napi_ok) {
380 LOG_ERROR("JSUtils::Convert2JSValue set element failed");
381 return ERR;
382 }
383 }
384 return OK;
385 }
386
Convert2JSBoolArr(napi_env env,std::vector<bool> value,napi_value & output)387 int32_t JSUtils::Convert2JSBoolArr(napi_env env, std::vector<bool> value, napi_value &output)
388 {
389 size_t arrLen = value.size();
390 napi_status status = napi_create_array_with_length(env, arrLen, &output);
391 if (status != napi_ok) {
392 LOG_ERROR("JSUtils::Convert2JSValue get arrLength failed");
393 return ERR;
394 }
395 for (size_t i = 0; i < arrLen; i++) {
396 napi_value val = nullptr;
397 if (Convert2JSValue(env, value[i], val) != OK) {
398 LOG_ERROR("JSUtils::Convert2JSValue creat bool failed");
399 return ERR;
400 }
401 status = napi_set_element(env, output, i, val);
402 if (status != napi_ok) {
403 LOG_ERROR("JSUtils::Convert2JSValue set element failed");
404 return ERR;
405 }
406 }
407 return OK;
408 }
409
Convert2JSStringArr(napi_env env,std::vector<std::string> value,napi_value & output)410 int32_t JSUtils::Convert2JSStringArr(napi_env env, std::vector<std::string> value, napi_value &output)
411 {
412 size_t arrLen = value.size();
413 napi_status status = napi_create_array_with_length(env, arrLen, &output);
414 if (status != napi_ok) {
415 LOG_ERROR("JSUtils::Convert2JSValue get arrLength failed");
416 return ERR;
417 }
418 for (size_t i = 0; i < arrLen; i++) {
419 napi_value val = nullptr;
420 if (Convert2JSValue(env, value[i], val) != OK) {
421 LOG_ERROR("JSUtils::Convert2JSValue creat string failed");
422 return ERR;
423 }
424 status = napi_set_element(env, output, i, val);
425 if (status != napi_ok) {
426 LOG_ERROR("JSUtils::Convert2JSValue set element failed");
427 return ERR;
428 }
429 }
430 return OK;
431 }
432 } // namespace AppDataMgrJsKit
433 } // namespace OHOS
434