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 "datashare_js_utils.h"
17 #include <cstdint>
18
19 #include "dataproxy_handle_common.h"
20 #include "datashare_log.h"
21 #include "datashare_predicates_proxy.h"
22 #include "datashare_string_utils.h"
23 #include "datashare_valuebucket_convert.h"
24 #include "js_native_api.h"
25 #include "js_native_api_types.h"
26 #include "napi/native_common.h"
27 #include "napi_datashare_values_bucket.h"
28 #include "securec.h"
29
30 namespace OHOS {
31 namespace DataShare {
Convert2String(napi_env env,napi_value jsStr,const size_t max)32 std::string DataShareJSUtils::Convert2String(napi_env env, napi_value jsStr, const size_t max)
33 {
34 size_t str_buffer_size = max;
35 napi_get_value_string_utf8(env, jsStr, nullptr, 0, &str_buffer_size);
36 char *buf = new (std::nothrow) char[str_buffer_size + 1];
37 if (buf == nullptr) {
38 return "";
39 }
40 size_t len = 0;
41 napi_get_value_string_utf8(env, jsStr, buf, str_buffer_size + 1, &len);
42 buf[len] = 0;
43 std::string value(buf);
44 delete[] buf;
45 return value;
46 }
47
Convert2StrVector(napi_env env,napi_value value,const size_t strMax)48 std::vector<std::string> DataShareJSUtils::Convert2StrVector(napi_env env, napi_value value, const size_t strMax)
49 {
50 NAPI_ASSERT_BASE(env, strMax > 0, "failed on strMax > 0", std::vector<std::string>());
51 uint32_t arrLen = 0;
52 napi_get_array_length(env, value, &arrLen);
53 if (arrLen == 0) {
54 return {};
55 }
56 std::vector<std::string> result;
57 for (size_t i = 0; i < arrLen; ++i) {
58 napi_value element;
59 if (napi_get_element(env, value, i, &element) != napi_ok) {
60 return {};
61 }
62 result.push_back(ConvertAny2String(env, element));
63 }
64 return result;
65 }
66
Convert2U8Vector(napi_env env,napi_value input_array)67 std::vector<uint8_t> DataShareJSUtils::Convert2U8Vector(napi_env env, napi_value input_array)
68 {
69 bool isTypedArray = false;
70 bool isArrayBuffer = false;
71 napi_is_typedarray(env, input_array, &isTypedArray);
72 if (!isTypedArray) {
73 napi_is_arraybuffer(env, input_array, &isArrayBuffer);
74 if (!isArrayBuffer) {
75 return {};
76 }
77 }
78 size_t length = 0;
79 void *data = nullptr;
80 if (isTypedArray) {
81 napi_typedarray_type type;
82 napi_value input_buffer = nullptr;
83 size_t byte_offset = 0;
84 napi_get_typedarray_info(env, input_array, &type, &length, &data, &input_buffer, &byte_offset);
85 if (type != napi_uint8_array || data == nullptr) {
86 LOG_ERROR("napi_get_typedarray_info err");
87 return {};
88 }
89 } else {
90 napi_get_arraybuffer_info(env, input_array, &data, &length);
91 if (data == nullptr || length <= 0) {
92 LOG_ERROR("napi_get_arraybuffer_info err");
93 return {};
94 }
95 }
96 return std::vector<uint8_t>((uint8_t *)data, ((uint8_t *)data) + length);
97 }
98
ConvertU8Vector(napi_env env,napi_value jsValue)99 std::vector<uint8_t> DataShareJSUtils::ConvertU8Vector(napi_env env, napi_value jsValue)
100 {
101 bool isTypedArray = false;
102 if (napi_is_typedarray(env, jsValue, &isTypedArray) != napi_ok || !isTypedArray) {
103 return {};
104 }
105
106 napi_typedarray_type type;
107 size_t length = 0;
108 napi_value buffer = nullptr;
109 size_t offset = 0;
110 NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
111 if (type != napi_uint8_array) {
112 return {};
113 }
114 uint8_t *data = nullptr;
115 size_t total = 0;
116 NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
117 length = std::min<size_t>(length, total - offset);
118 std::vector<uint8_t> result(sizeof(uint8_t) + length);
119 int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
120 if (retCode != 0) {
121 return {};
122 }
123 return result;
124 }
125
ConvertAny2String(napi_env env,napi_value jsValue)126 std::string DataShareJSUtils::ConvertAny2String(napi_env env, napi_value jsValue)
127 {
128 napi_valuetype valueType = napi_undefined;
129 NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &valueType), "napi_typeof failed");
130 if (valueType == napi_string) {
131 return DataShareJSUtils::Convert2String(env, jsValue, DataShareJSUtils::DEFAULT_BUF_SIZE);
132 } else if (valueType == napi_number) {
133 double valueNumber;
134 napi_get_value_double(env, jsValue, &valueNumber);
135 return std::to_string(valueNumber);
136 } else if (valueType == napi_boolean) {
137 bool valueBool = false;
138 napi_get_value_bool(env, jsValue, &valueBool);
139 return std::to_string(valueBool);
140 } else if (valueType == napi_null) {
141 return "null";
142 } else if (valueType == napi_object) {
143 std::vector<uint8_t> bytes = DataShareJSUtils::Convert2U8Vector(env, jsValue);
144 std::string ret(bytes.begin(), bytes.end());
145 return ret;
146 }
147
148 return "invalid type";
149 }
150
Convert2JSValue(napi_env env,const std::monostate & value)151 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::monostate &value)
152 {
153 return nullptr;
154 }
155
Convert2JSValue(napi_env env,const std::vector<std::string> & value)156 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<std::string> &value)
157 {
158 napi_value jsValue;
159 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
160 if (status != napi_ok) {
161 return nullptr;
162 }
163
164 for (size_t i = 0; i < value.size(); ++i) {
165 napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
166 }
167 return jsValue;
168 }
169
Convert2JSValue(napi_env env,const std::string & value)170 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::string &value)
171 {
172 napi_value jsValue;
173 napi_status status = napi_create_string_utf8(env, value.c_str(), value.size(), &jsValue);
174 if (status != napi_ok) {
175 return nullptr;
176 }
177 return jsValue;
178 }
179
Convert2JSValue(napi_env env,const std::vector<uint8_t> & value,bool isTypedArray)180 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<uint8_t> &value, bool isTypedArray)
181 {
182 void *native = nullptr;
183 napi_value buffer = nullptr;
184 if (value.empty()) {
185 LOG_DEBUG("vector is empty");
186 return nullptr;
187 }
188 napi_status status = napi_create_arraybuffer(env, value.size(), &native, &buffer);
189 if (status != napi_ok) {
190 return nullptr;
191 }
192 if (memcpy_s(native, value.size(), value.data(), value.size()) != EOK && value.size() > 0) {
193 return nullptr;
194 }
195 if (!isTypedArray) {
196 return buffer;
197 }
198 napi_value jsValue;
199 status = napi_create_typedarray(env, napi_uint8_array, value.size(), buffer, 0, &jsValue);
200 if (status != napi_ok) {
201 return nullptr;
202 }
203 return jsValue;
204 }
205
Convert2JSValue(napi_env env,int32_t value)206 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int32_t value)
207 {
208 napi_value jsValue;
209 napi_status status = napi_create_int32(env, value, &jsValue);
210 if (status != napi_ok) {
211 return nullptr;
212 }
213 return jsValue;
214 }
215
Convert2JSValue(napi_env env,int64_t value)216 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int64_t value)
217 {
218 napi_value jsValue;
219 napi_status status = napi_create_int64(env, value, &jsValue);
220 if (status != napi_ok) {
221 return nullptr;
222 }
223 return jsValue;
224 }
225
Convert2JSValue(napi_env env,uint32_t value)226 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, uint32_t value)
227 {
228 napi_value jsValue;
229 napi_status status = napi_create_uint32(env, value, &jsValue);
230 if (status != napi_ok) {
231 return nullptr;
232 }
233 return jsValue;
234 }
235
Convert2JSValue(napi_env env,double value)236 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, double value)
237 {
238 napi_value jsValue;
239 napi_status status = napi_create_double(env, value, &jsValue);
240 if (status != napi_ok) {
241 return nullptr;
242 }
243 return jsValue;
244 }
245
Convert2JSValue(napi_env env,bool value)246 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, bool value)
247 {
248 napi_value jsValue;
249 napi_status status = napi_get_boolean(env, value, &jsValue);
250 if (status != napi_ok) {
251 return nullptr;
252 }
253 return jsValue;
254 }
255
Convert2JSValue(napi_env env,const std::map<std::string,int> & value)256 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::map<std::string, int> &value)
257 {
258 napi_value jsValue;
259 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
260 if (status != napi_ok) {
261 return nullptr;
262 }
263
264 int index = 0;
265 for (const auto& [device, result] : value) {
266 napi_value jsElement;
267 status = napi_create_array_with_length(env, SYNC_RESULT_ELEMNT_NUM, &jsElement);
268 if (status != napi_ok) {
269 return nullptr;
270 }
271 napi_set_element(env, jsElement, 0, Convert2JSValue(env, device));
272 napi_set_element(env, jsElement, 1, Convert2JSValue(env, result));
273 napi_set_element(env, jsValue, index++, jsElement);
274 }
275
276 return jsValue;
277 }
UnwrapStringFromJS(napi_env env,napi_value param,const std::string & defaultValue)278 std::string DataShareJSUtils::UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue)
279 {
280 size_t size = 0;
281 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
282 return defaultValue;
283 }
284
285 std::string value("");
286 if (size == 0) {
287 return defaultValue;
288 }
289
290 char *buf = new (std::nothrow) char[size + 1];
291 if (buf == nullptr) {
292 return value;
293 }
294 (void)memset_s(buf, size + 1, 0, size + 1);
295
296 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
297 if (rev) {
298 value = buf;
299 } else {
300 value = defaultValue;
301 }
302
303 if (buf != nullptr) {
304 delete[] buf;
305 buf = nullptr;
306 }
307 return value;
308 }
309
Convert2JSValue(napi_env env,const DataShareValueObject & valueObject)310 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataShareValueObject &valueObject)
311 {
312 napi_value jsValue = nullptr;
313 switch (valueObject.value.index()) {
314 case DataShareValueObjectType::TYPE_INT: {
315 int64_t val = std::get<int64_t>(valueObject.value);
316 jsValue = Convert2JSValue(env, val);
317 break;
318 }
319 case DataShareValueObjectType::TYPE_DOUBLE: {
320 double val = std::get<double>(valueObject.value);
321 jsValue = Convert2JSValue(env, val);
322 break;
323 }
324 case DataShareValueObjectType::TYPE_STRING: {
325 std::string val = std::get<std::string>(valueObject.value);
326 jsValue = Convert2JSValue(env, val);
327 break;
328 }
329 case DataShareValueObjectType::TYPE_BOOL: {
330 bool val = std::get<bool>(valueObject.value);
331 jsValue = Convert2JSValue(env, val);
332 break;
333 }
334 default: {
335 LOG_ERROR("Marshal ValueObject: unknown typeId");
336 return nullptr;
337 }
338 }
339
340 return jsValue;
341 }
342
Convert2JSValue(napi_env env,const DataShareValuesBucket & valueBucket)343 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataShareValuesBucket &valueBucket)
344 {
345 napi_value res = NewInstance(env, valueBucket);
346 if (res == nullptr) {
347 LOG_ERROR("failed to make new instance of DataShareValueBucket.");
348 }
349 return res;
350 }
351
Convert2ValueObject(napi_env env,napi_value value,bool & status)352 DataShareValueObject DataShareJSUtils::Convert2ValueObject(napi_env env, napi_value value, bool &status)
353 {
354 napi_valuetype valueType = napi_undefined;
355 napi_typeof(env, value, &valueType);
356 status = true;
357 if (valueType == napi_string) {
358 std::string valueString = DataShareJSUtils::UnwrapStringFromJS(env, value);
359 return valueString;
360 } else if (valueType == napi_number) {
361 double valueNumber = 0;
362 napi_get_value_double(env, value, &valueNumber);
363 return valueNumber;
364 } else if (valueType == napi_boolean) {
365 bool valueBool = false;
366 napi_get_value_bool(env, value, &valueBool);
367 return valueBool;
368 } else if (valueType == napi_null) {
369 return {};
370 } else if (valueType == napi_object) {
371 std::vector<uint8_t> valueBlob = DataShareJSUtils::Convert2U8Vector(env, value);
372 return valueBlob;
373 } else {
374 LOG_ERROR("valuesBucket error");
375 status = false;
376 return {};
377 }
378 }
379
Equals(napi_env env,napi_value value,napi_ref copy)380 bool DataShareJSUtils::Equals(napi_env env, napi_value value, napi_ref copy)
381 {
382 if (copy == nullptr) {
383 return (value == nullptr);
384 }
385
386 napi_value copyValue = nullptr;
387 napi_get_reference_value(env, copy, ©Value);
388
389 bool isEqual = false;
390 napi_strict_equals(env, value, copyValue, &isEqual);
391 return isEqual;
392 }
393
Convert2JSValue(napi_env env,const TemplateId & templateId)394 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const TemplateId &templateId)
395 {
396 napi_value tplId = nullptr;
397 napi_create_object(env, &tplId);
398 napi_value subscriberId = Convert2JSValue(env, std::to_string(templateId.subscriberId_));
399 if (subscriberId == nullptr) {
400 return nullptr;
401 }
402 napi_value bundleName = nullptr;
403 bundleName = Convert2JSValue(env, templateId.bundleName_);
404 if (bundleName == nullptr) {
405 return nullptr;
406 }
407 napi_set_named_property(env, tplId, "subscriberId", subscriberId);
408 napi_set_named_property(env, tplId, "bundleName", bundleName);
409 return tplId;
410 }
411
Convert2JSValue(napi_env env,const RdbChangeNode & changeNode)412 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const RdbChangeNode &changeNode)
413 {
414 napi_value jsRdbChangeNode = nullptr;
415 napi_create_object(env, &jsRdbChangeNode);
416
417 napi_value uri = nullptr;
418 uri = Convert2JSValue(env, changeNode.uri_);
419 if (uri == nullptr) {
420 return nullptr;
421 }
422 napi_value templateId = nullptr;
423 templateId = Convert2JSValue(env, changeNode.templateId_);
424 if (templateId == nullptr) {
425 return nullptr;
426 }
427 napi_value data = Convert2JSValue(env, changeNode.data_);
428 if (data == nullptr) {
429 return nullptr;
430 }
431 napi_set_named_property(env, jsRdbChangeNode, "uri", uri);
432 napi_set_named_property(env, jsRdbChangeNode, "templateId", templateId);
433 napi_set_named_property(env, jsRdbChangeNode, "data", data);
434 return jsRdbChangeNode;
435 }
436
Convert2JSValue(napi_env env,PublishedDataItem & publishedDataItem)437 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, PublishedDataItem &publishedDataItem)
438 {
439 napi_value jsPublishedDataItem = nullptr;
440 napi_create_object(env, &jsPublishedDataItem);
441
442 napi_value key = Convert2JSValue(env, publishedDataItem.key_);
443 if (key == nullptr) {
444 return nullptr;
445 }
446
447 napi_value subscriberId = nullptr;
448 subscriberId = Convert2JSValue(env, std::to_string(publishedDataItem.subscriberId_));
449 if (subscriberId == nullptr) {
450 return nullptr;
451 }
452
453 napi_value data = nullptr;
454 if (publishedDataItem.IsAshmem()) {
455 data = Convert2JSValue(env, std::get<std::vector<uint8_t>>(publishedDataItem.GetData()), false);
456 } else {
457 data = Convert2JSValue(env, std::get<std::string>(publishedDataItem.GetData()));
458 }
459 if (data == nullptr) {
460 return nullptr;
461 }
462
463 napi_set_named_property(env, jsPublishedDataItem, "key", key);
464 napi_set_named_property(env, jsPublishedDataItem, "subscriberId", subscriberId);
465 napi_set_named_property(env, jsPublishedDataItem, "data", data);
466 return jsPublishedDataItem;
467 }
468
Convert2JSValue(napi_env env,std::vector<PublishedDataItem> & publishedDataItems)469 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, std::vector<PublishedDataItem> &publishedDataItems)
470 {
471 napi_value jsValue;
472 napi_status status = napi_create_array_with_length(env, publishedDataItems.size(), &jsValue);
473 if (status != napi_ok) {
474 return nullptr;
475 }
476
477 for (size_t i = 0; i < publishedDataItems.size(); ++i) {
478 napi_set_element(env, jsValue, i, Convert2JSValue(env, publishedDataItems[i]));
479 }
480 return jsValue;
481 }
482
Convert2JSValue(napi_env env,PublishedDataChangeNode & changeNode)483 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, PublishedDataChangeNode &changeNode)
484 {
485 napi_value jsPublishedDataChangeNode = nullptr;
486 napi_create_object(env, &jsPublishedDataChangeNode);
487
488 napi_value bundleName = nullptr;
489 bundleName = Convert2JSValue(env, changeNode.ownerBundleName_);
490 if (bundleName == nullptr) {
491 return nullptr;
492 }
493 napi_value data = nullptr;
494 data = Convert2JSValue(env, changeNode.datas_);
495 if (data == nullptr) {
496 return nullptr;
497 }
498 napi_set_named_property(env, jsPublishedDataChangeNode, "bundleName", bundleName);
499 napi_set_named_property(env, jsPublishedDataChangeNode, "data", data);
500 return jsPublishedDataChangeNode;
501 }
502
Convert2JSValue(napi_env env,const OperationResult & results)503 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const OperationResult &results)
504 {
505 napi_value jsOperationResult = nullptr;
506 napi_create_object(env, &jsOperationResult);
507
508 napi_value key = nullptr;
509 key = Convert2JSValue(env, results.key_);
510 if (key == nullptr) {
511 return nullptr;
512 }
513
514 napi_value result = nullptr;
515 result = Convert2JSValue(env, results.errCode_);
516 if (result == nullptr) {
517 return nullptr;
518 }
519 napi_set_named_property(env, jsOperationResult, "key", key);
520 napi_set_named_property(env, jsOperationResult, "result", result);
521 return jsOperationResult;
522 }
523
Convert2JSValue(napi_env env,const std::vector<OperationResult> & results)524 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<OperationResult> &results)
525 {
526 napi_value jsValue;
527 napi_status status = napi_create_array_with_length(env, results.size(), &jsValue);
528 if (status != napi_ok) {
529 return nullptr;
530 }
531
532 for (size_t i = 0; i < results.size(); ++i) {
533 napi_set_element(env, jsValue, i, Convert2JSValue(env, results[i]));
534 }
535 return jsValue;
536 }
537
Convert2JSValue(napi_env env,const DataProxyResult & result)538 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataProxyResult &result)
539 {
540 napi_value jsDataProxyResult = nullptr;
541 napi_create_object(env, &jsDataProxyResult);
542
543 napi_value uri = Convert2JSValue(env, result.uri_);
544 if (uri == nullptr) {
545 return nullptr;
546 }
547
548 napi_value errCode = Convert2JSValue(env, result.result_);
549 if (errCode == nullptr) {
550 return nullptr;
551 }
552 napi_set_named_property(env, jsDataProxyResult, "uri", uri);
553 napi_set_named_property(env, jsDataProxyResult, "result", errCode);
554 return jsDataProxyResult;
555 }
556
Convert2JSValue(napi_env env,const std::vector<DataProxyResult> & results)557 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<DataProxyResult> &results)
558 {
559 napi_value jsValue;
560 napi_status status = napi_create_array_with_length(env, results.size(), &jsValue);
561 if (status != napi_ok) {
562 return nullptr;
563 }
564
565 for (size_t i = 0; i < results.size(); ++i) {
566 napi_set_element(env, jsValue, i, Convert2JSValue(env, results[i]));
567 }
568 return jsValue;
569 }
570
Convert2JSValue(napi_env env,const DataProxyGetResult & result)571 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataProxyGetResult &result)
572 {
573 napi_value jsDataProxyGetResult = nullptr;
574 napi_create_object(env, &jsDataProxyGetResult);
575
576 napi_value uri = Convert2JSValue(env, result.uri_);
577 if (uri == nullptr) {
578 return nullptr;
579 }
580
581 napi_value errCode = Convert2JSValue(env, result.result_);
582 if (errCode == nullptr) {
583 return nullptr;
584 }
585
586 // when failed to get proxyData, value and allowList in getResult is undefined
587 napi_value value = nullptr;
588 if (result.result_ == SUCCESS) {
589 value = Convert2JSValue(env, result.value_);
590 if (value == nullptr) {
591 return nullptr;
592 }
593 }
594
595 napi_value allowList = nullptr;
596 if (result.result_ == SUCCESS) {
597 allowList = Convert2JSValue(env, result.allowList_);
598 if (allowList == nullptr) {
599 return nullptr;
600 }
601 }
602
603 napi_set_named_property(env, jsDataProxyGetResult, "uri", uri);
604 napi_set_named_property(env, jsDataProxyGetResult, "result", errCode);
605 napi_set_named_property(env, jsDataProxyGetResult, "value", value);
606 napi_set_named_property(env, jsDataProxyGetResult, "allowList", allowList);
607 return jsDataProxyGetResult;
608 }
609
Convert2JSValue(napi_env env,const std::vector<DataProxyGetResult> & results)610 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<DataProxyGetResult> &results)
611 {
612 napi_value jsValue;
613 napi_status status = napi_create_array_with_length(env, results.size(), &jsValue);
614 if (status != napi_ok) {
615 return nullptr;
616 }
617
618 for (size_t i = 0; i < results.size(); ++i) {
619 napi_set_element(env, jsValue, i, Convert2JSValue(env, results[i]));
620 }
621 return jsValue;
622 }
623
Convert2JSValue(napi_env env,const DataProxyChangeInfo & changeInfo)624 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataProxyChangeInfo &changeInfo)
625 {
626 napi_value jsDataProxyChangeInfo = nullptr;
627 napi_create_object(env, &jsDataProxyChangeInfo);
628
629 napi_value type = nullptr;
630 type = Convert2JSValue(env, changeInfo.changeType_);
631 if (type == nullptr) {
632 return nullptr;
633 }
634 napi_value uri = nullptr;
635 uri = Convert2JSValue(env, changeInfo.uri_);
636 if (uri == nullptr) {
637 return nullptr;
638 }
639 napi_value value = Convert2JSValue(env, changeInfo.value_);
640 if (value == nullptr) {
641 return nullptr;
642 }
643 napi_set_named_property(env, jsDataProxyChangeInfo, "type", type);
644 napi_set_named_property(env, jsDataProxyChangeInfo, "uri", uri);
645 napi_set_named_property(env, jsDataProxyChangeInfo, "value", value);
646 return jsDataProxyChangeInfo;
647 }
648
UnwrapTemplatePredicates(napi_env env,napi_value jsPredicates,std::vector<PredicateTemplateNode> & predicates)649 bool DataShareJSUtils::UnwrapTemplatePredicates(napi_env env, napi_value jsPredicates,
650 std::vector<PredicateTemplateNode> &predicates)
651 {
652 napi_value keys = nullptr;
653 napi_get_property_names(env, jsPredicates, &keys);
654 uint32_t arrLen = 0;
655 napi_status status = napi_get_array_length(env, keys, &arrLen);
656 if (status != napi_ok) {
657 LOG_ERROR("UnwrapTemplatePredicates error");
658 return false;
659 }
660 LOG_DEBUG("TemplatePredicates length : %{public}u", arrLen);
661 for (size_t i = 0; i < arrLen; ++i) {
662 napi_value key = nullptr;
663 status = napi_get_element(env, keys, i, &key);
664 if (status != napi_ok) {
665 LOG_ERROR("UnwrapTemplatePredicates err");
666 return false;
667 }
668 napi_value value = nullptr;
669 status = napi_get_property(env, jsPredicates, key, &value);
670 if (status != napi_ok) {
671 LOG_ERROR("UnwrapTemplatePredicates err");
672 return false;
673 }
674 std::string keyStr = UnwrapStringFromJS(env, key);
675 std::string valueStr = UnwrapStringFromJS(env, value);
676 PredicateTemplateNode node(keyStr, valueStr);
677 predicates.emplace_back(node);
678 }
679 return true;
680 }
681
Convert2Template(napi_env env,napi_value value)682 Template DataShareJSUtils::Convert2Template(napi_env env, napi_value value)
683 {
684 napi_valuetype valueType = napi_undefined;
685 napi_typeof(env, value, &valueType);
686 if (valueType != napi_object) {
687 LOG_ERROR("Convert2Template error, value is not object");
688 return {};
689 }
690 std::string update = "";
691 UnwrapStringByPropertyName(env, value, "update", update);
692
693 napi_value jsPredicates;
694 auto status = napi_get_named_property(env, value, "predicates", &jsPredicates);
695 if (status != napi_ok) {
696 LOG_ERROR("Convert predicates failed");
697 return {};
698 }
699 std::vector<PredicateTemplateNode> predicates;
700 if (!UnwrapTemplatePredicates(env, jsPredicates, predicates)) {
701 LOG_ERROR("UnwrapTemplateNodeVector failed");
702 return {};
703 }
704
705 std::string scheduler;
706 if (!UnwrapStringByPropertyName(env, value, "scheduler", scheduler)) {
707 LOG_ERROR("Convert scheduler failed");
708 return {};
709 }
710 Template tpl(update, predicates, scheduler);
711 return tpl;
712 }
713
Convert2TemplateId(napi_env env,napi_value value)714 TemplateId DataShareJSUtils::Convert2TemplateId(napi_env env, napi_value value)
715 {
716 napi_valuetype valueType = napi_undefined;
717 napi_typeof(env, value, &valueType);
718 if (valueType != napi_object) {
719 LOG_ERROR("Convert2TemplateId error, value is not object");
720 return {};
721 }
722
723 TemplateId templateId;
724 std::string strSubId;
725 if (!UnwrapStringByPropertyName(env, value, "subscriberId", strSubId)) {
726 LOG_ERROR("Convert subscriberId failed");
727 return {};
728 }
729 templateId.subscriberId_ = atoll(strSubId.c_str());
730 if (!UnwrapStringByPropertyName(env, value, "bundleNameOfOwner", templateId.bundleName_)) {
731 LOG_ERROR("Convert bundleNameOfOwner failed");
732 return {};
733 }
734 return templateId;
735 }
736
UnwrapPublishedDataItem(napi_env env,napi_value jsObject,PublishedDataItem & publishedDataItem)737 bool DataShareJSUtils::UnwrapPublishedDataItem(napi_env env, napi_value jsObject, PublishedDataItem &publishedDataItem)
738 {
739 napi_valuetype valueType = napi_undefined;
740 napi_typeof(env, jsObject, &valueType);
741 if (valueType != napi_object) {
742 LOG_ERROR("UnwrapPublishedDataItem error, value is not object");
743 return false;
744 }
745
746 if (!UnwrapStringByPropertyName(env, jsObject, "key", publishedDataItem.key_)) {
747 LOG_ERROR("Convert key failed");
748 return false;
749 }
750 std::string keyStr = "data";
751 napi_value jsDataKey = Convert2JSValue(env, keyStr);
752 napi_value jsDataValue = nullptr;
753 napi_get_property(env, jsObject, jsDataKey, &jsDataValue);
754 napi_typeof(env, jsDataValue, &valueType);
755 PublishedDataItem::DataType value;
756 if (valueType == napi_object) {
757 value = Convert2U8Vector(env, jsDataValue);
758 publishedDataItem.Set(value);
759 } else if (valueType == napi_string) {
760 value = Convert2String(env, jsDataValue);
761 publishedDataItem.Set(value);
762 } else {
763 LOG_ERROR("Convert dataValue failed, type is %{public}d", valueType);
764 return false;
765 }
766 std::string strSubId;
767 if (!UnwrapStringByPropertyName(env, jsObject, "subscriberId", strSubId)) {
768 LOG_ERROR("Convert subscriberId failed");
769 return false;
770 }
771 publishedDataItem.subscriberId_ = atoll(strSubId.c_str());
772 return true;
773 }
774
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)775 bool DataShareJSUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
776 {
777 bool isArray = false;
778 arraySize = 0;
779
780 if (napi_is_array(env, param, &isArray) != napi_ok || isArray == false) {
781 return false;
782 }
783
784 if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
785 return false;
786 }
787 return true;
788 }
789
UnwrapPublishedDataItemVector(napi_env env,napi_value value,std::vector<PublishedDataItem> & publishedDataItems)790 bool DataShareJSUtils::UnwrapPublishedDataItemVector(napi_env env, napi_value value,
791 std::vector<PublishedDataItem> &publishedDataItems)
792 {
793 uint32_t arraySize = 0;
794
795 if (!IsArrayForNapiValue(env, value, arraySize)) {
796 LOG_ERROR("IsArrayForNapiValue is false");
797 return false;
798 }
799
800 for (uint32_t i = 0; i < arraySize; i++) {
801 napi_value jsValue = nullptr;
802 if (napi_get_element(env, value, i, &jsValue) != napi_ok) {
803 LOG_ERROR("napi_get_element is false");
804 return false;
805 }
806
807 PublishedDataItem publishedDataItem;
808 if (!UnwrapPublishedDataItem(env, jsValue, publishedDataItem)) {
809 LOG_ERROR("UnwrapPublishedDataItem failed");
810 return false;
811 }
812 publishedDataItems.emplace_back(std::move(publishedDataItem));
813 }
814 return true;
815 }
816
UnwrapDataProxyValue(napi_env env,napi_value jsObject,DataProxyValue & value,bool & isValueUndefined)817 bool DataShareJSUtils::UnwrapDataProxyValue(napi_env env, napi_value jsObject,
818 DataProxyValue &value, bool &isValueUndefined)
819 {
820 napi_valuetype valueType = napi_undefined;
821 napi_typeof(env, jsObject, &valueType);
822 if (valueType != napi_object) {
823 LOG_ERROR("UnwrapDataProxyValue error, value is not object");
824 return false;
825 }
826
827 std::string keyStr = "value";
828 napi_value jsDataKey = Convert2JSValue(env, keyStr);
829 napi_value jsDataValue = nullptr;
830 napi_get_property(env, jsObject, jsDataKey, &jsDataValue);
831 napi_typeof(env, jsDataValue, &valueType);
832 switch (valueType) {
833 case napi_number: {
834 double valueNumber;
835 napi_get_value_double(env, jsDataValue, &valueNumber);
836 value = valueNumber;
837 break;
838 }
839 case napi_string: {
840 value = Convert2String(env, jsDataValue);
841 break;
842 }
843 case napi_boolean: {
844 bool valueBool;
845 napi_get_value_bool(env, jsDataValue, &valueBool);
846 value = valueBool;
847 break;
848 }
849 case napi_undefined: {
850 value = "";
851 isValueUndefined = true;
852 break;
853 }
854 case napi_null: {
855 value = "";
856 isValueUndefined = true;
857 break;
858 }
859 default: {
860 LOG_ERROR("Convert dataValue failed, type is %{public}d", valueType);
861 return false;
862 }
863 }
864 return true;
865 }
866
UnwrapProxyDataItem(napi_env env,napi_value jsObject,DataShareProxyData & proxyData)867 bool DataShareJSUtils::UnwrapProxyDataItem(napi_env env, napi_value jsObject, DataShareProxyData &proxyData)
868 {
869 napi_valuetype valueType = napi_undefined;
870 napi_typeof(env, jsObject, &valueType);
871 if (valueType != napi_object) {
872 LOG_ERROR("UnwrapPublishedDataItem error, value is not object");
873 return false;
874 }
875
876 if (!UnwrapStringByPropertyName(env, jsObject, "uri", proxyData.uri_)) {
877 LOG_ERROR("Convert uri failed");
878 return false;
879 }
880
881 bool isValueUndefined = false;
882 if (!UnwrapDataProxyValue(env, jsObject, proxyData.value_, isValueUndefined)) {
883 LOG_ERROR("Convert dataproxy value failed");
884 return false;
885 }
886 proxyData.isValueUndefined = isValueUndefined;
887
888 std::string keyStr = "allowList";
889 napi_value jsDataKey = Convert2JSValue(env, keyStr);
890 napi_value jsDataValue = nullptr;
891 napi_get_property(env, jsObject, jsDataKey, &jsDataValue);
892 napi_typeof(env, jsDataValue, &valueType);
893 if (valueType != napi_object) {
894 if (valueType == napi_undefined || valueType == napi_null) {
895 proxyData.isAllowListUndefined = true;
896 } else {
897 LOG_ERROR("Convert allowList failed");
898 return false;
899 }
900 }
901 Convert2Value(env, jsDataValue, proxyData.allowList_);
902 auto it = proxyData.allowList_.begin();
903 while (it != proxyData.allowList_.end()) {
904 if (it->size() > APPIDENTIFIER_MAX_SIZE) {
905 LOG_WARN("appIdentifier is over limit");
906 it = proxyData.allowList_.erase(it);
907 } else {
908 it++;
909 }
910 }
911 if (proxyData.allowList_.size() > ALLOW_LIST_MAX_COUNT) {
912 LOG_WARN("ProxyData's allowList is over limit, uri: %{public}s",
913 DataShareStringUtils::Anonymous(proxyData.uri_).c_str());
914 proxyData.allowList_.resize(ALLOW_LIST_MAX_COUNT);
915 }
916 return true;
917 }
918
UnwrapProxyDataItemVector(napi_env env,napi_value value,std::vector<DataShareProxyData> & proxyDatas)919 bool DataShareJSUtils::UnwrapProxyDataItemVector(napi_env env, napi_value value,
920 std::vector<DataShareProxyData> &proxyDatas)
921 {
922 uint32_t arraySize = 0;
923 if (!IsArrayForNapiValue(env, value, arraySize)) {
924 LOG_ERROR("IsArrayForNapiValue is false");
925 return false;
926 }
927
928 for (uint32_t i = 0; i < arraySize; i++) {
929 napi_value jsValue = nullptr;
930 if (napi_get_element(env, value, i, &jsValue) != napi_ok) {
931 LOG_ERROR("napi_get_element is false");
932 return false;
933 }
934
935 DataShareProxyData proxyDataItem;
936 if (!UnwrapProxyDataItem(env, jsValue, proxyDataItem)) {
937 LOG_ERROR("UnwrapPublishedDataItem failed");
938 return false;
939 }
940 proxyDatas.emplace_back(std::move(proxyDataItem));
941 }
942 return true;
943 }
944
Convert2ProxyData(napi_env env,napi_value value)945 std::vector<DataShareProxyData> DataShareJSUtils::Convert2ProxyData(napi_env env, napi_value value)
946 {
947 napi_valuetype valueType = napi_undefined;
948 napi_typeof(env, value, &valueType);
949 if (valueType != napi_object) {
950 LOG_ERROR("Convert2PublishedData error, value is not object");
951 return {};
952 }
953 std::vector<DataShareProxyData> proxyDatas;
954 if (!UnwrapProxyDataItemVector(env, value, proxyDatas)) {
955 LOG_ERROR("UnwrapPublishedDataItems failed");
956 return {};
957 }
958 return proxyDatas;
959 }
960
UnwrapDataProxyConfig(napi_env env,napi_value value,DataProxyConfig & config)961 bool DataShareJSUtils::UnwrapDataProxyConfig(napi_env env, napi_value value, DataProxyConfig &config)
962 {
963 napi_value jsResult = nullptr;
964 napi_status status = napi_get_named_property(env, value, "type", &jsResult);
965 if ((status != napi_ok) || (jsResult == nullptr)) {
966 LOG_ERROR("Convert DataProxyType failed");
967 return false;
968 }
969 napi_valuetype valueType = napi_undefined;
970 napi_typeof(env, jsResult, &valueType);
971 if (valueType != napi_number) {
972 LOG_ERROR("Convert DataProxyType error, value is not number");
973 return false;
974 }
975 if (Convert2Value(env, jsResult, config.type_) != napi_ok) {
976 LOG_ERROR("Convert DataProxyType failed");
977 return false;
978 }
979 return true;
980 }
981
Convert2PublishedData(napi_env env,napi_value value)982 Data DataShareJSUtils::Convert2PublishedData(napi_env env, napi_value value)
983 {
984 napi_valuetype valueType = napi_undefined;
985 napi_typeof(env, value, &valueType);
986 if (valueType != napi_object) {
987 LOG_ERROR("Convert2PublishedData error, value is not object");
988 return {};
989 }
990 Data data;
991 if (!UnwrapPublishedDataItemVector(env, value, data.datas_)) {
992 LOG_ERROR("UnwrapPublishedDataItems failed");
993 return {};
994 }
995 return data;
996 }
997
UnwrapStringByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,std::string & value)998 bool DataShareJSUtils::UnwrapStringByPropertyName(
999 napi_env env, napi_value jsObject, const char *propertyName, std::string &value)
1000 {
1001 napi_value jsResult = nullptr;
1002 auto status = napi_get_named_property(env, jsObject, propertyName, &jsResult);
1003 if ((status != napi_ok) || (jsResult == nullptr)) {
1004 LOG_ERROR("Convert bundleNameOfOwner failed");
1005 return false;
1006 }
1007 napi_valuetype valueType = napi_undefined;
1008 napi_typeof(env, jsResult, &valueType);
1009 if (valueType != napi_string) {
1010 LOG_ERROR("Convert2PublishedData error, value is not object");
1011 return false;
1012 }
1013 value = DataShareJSUtils::Convert2String(env, jsResult);
1014 return true;
1015 }
1016
Convert2JSValue(napi_env env,const std::vector<BatchUpdateResult> & result)1017 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<BatchUpdateResult> &result)
1018 {
1019 napi_value jsResult = nullptr;
1020 napi_status status = napi_create_object(env, &jsResult);
1021 if (status != napi_ok) {
1022 LOG_ERROR("Create object failed, ret : %{public}d", status);
1023 return nullptr;
1024 }
1025 for (const auto &valueArray : result) {
1026 napi_value values;
1027 if (napi_create_array(env, &values) != napi_ok) {
1028 LOG_ERROR("Create array failed");
1029 return nullptr;
1030 }
1031 uint32_t index = 0;
1032 for (const auto &value : valueArray.codes) {
1033 napi_value jsValue = Convert2JSValue(env, value);
1034 if (napi_set_element(env, values, index++, jsValue) != napi_ok) {
1035 LOG_ERROR("Set to array failed");
1036 return nullptr;
1037 }
1038 }
1039 if (napi_set_named_property(env, jsResult, valueArray.uri.c_str(), values) != napi_ok) {
1040 LOG_ERROR("Set to map failed");
1041 return nullptr;
1042 }
1043 }
1044 return jsResult;
1045 }
1046
Convert2Value(napi_env env,napi_value input,UpdateOperation & operation)1047 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, UpdateOperation& operation)
1048 {
1049 napi_valuetype valueType = napi_undefined;
1050 napi_typeof(env, input, &valueType);
1051 if (valueType != napi_object) {
1052 LOG_ERROR("value is not object");
1053 return napi_invalid_arg;
1054 }
1055 if (Convert2Value(env, input, "predicates", operation.predicates) != napi_ok) {
1056 return napi_invalid_arg;
1057 }
1058 if (Convert2Value(env, input, "values", operation.valuesBucket) != napi_ok) {
1059 return napi_invalid_arg;
1060 }
1061 return napi_ok;
1062 }
1063
Convert2Value(napi_env env,napi_value input,std::string & str)1064 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, std::string &str)
1065 {
1066 size_t strBufferSize = DEFAULT_BUF_SIZE;
1067 napi_get_value_string_utf8(env, input, nullptr, 0, &strBufferSize);
1068 char *buf = new (std::nothrow) char[strBufferSize + 1];
1069 if (buf == nullptr) {
1070 return napi_invalid_arg;
1071 }
1072 size_t len = 0;
1073 napi_get_value_string_utf8(env, input, buf, strBufferSize + 1, &len);
1074 buf[len] = 0;
1075 str = std::string(buf);
1076 delete[] buf;
1077 return napi_ok;
1078 }
1079
Convert2Value(napi_env env,napi_value input,OHOS::DataShare::DataShareObserver::ChangeType & changeType)1080 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input,
1081 OHOS::DataShare::DataShareObserver::ChangeType &changeType)
1082 {
1083 uint32_t number = 0;
1084 napi_status status = napi_get_value_uint32(env, input, &number);
1085 changeType = static_cast<OHOS::DataShare::DataShareObserver::ChangeType>(number);
1086 return status;
1087 }
1088
Convert2Value(napi_env env,napi_value input,DataShareObserver::ChangeInfo & changeInfo)1089 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataShareObserver::ChangeInfo &changeInfo)
1090 {
1091 napi_valuetype type = napi_undefined;
1092 napi_typeof(env, input, &type);
1093 if (type != napi_object) {
1094 LOG_ERROR("ChangeInfo is not object");
1095 return napi_invalid_arg;
1096 }
1097 std::string uriStr;
1098 std::vector<DataShareValuesBucket> valuebuckets = {};
1099 if (Convert2Value(env, input, "type", changeInfo.changeType_) != napi_ok) {
1100 return napi_invalid_arg;
1101 }
1102 if (Convert2Value(env, input, "uri", uriStr) != napi_ok) {
1103 return napi_invalid_arg;
1104 }
1105 if (Convert2Value(env, input, "values", valuebuckets) != napi_ok) {
1106 return napi_invalid_arg;
1107 }
1108
1109 Uri uri(uriStr);
1110 changeInfo.uris_.push_back(uri);
1111 changeInfo.valueBuckets_ = ValueProxy::Convert(std::move(valuebuckets));
1112 return napi_ok;
1113 }
1114
Convert2Value(napi_env env,napi_value input,DataProxyType & proxyType)1115 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataProxyType &proxyType)
1116 {
1117 uint32_t number = 0;
1118 napi_status status = napi_get_value_uint32(env, input, &number);
1119 proxyType = static_cast<DataProxyType>(number);
1120 return status;
1121 }
1122
Convert2JSValue(napi_env env,const DataShareObserver::ChangeInfo & changeInfo)1123 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataShareObserver::ChangeInfo &changeInfo)
1124 {
1125 napi_value napiValue = nullptr;
1126 napi_create_object(env, &napiValue);
1127 napi_value changeType = Convert2JSValue(env, changeInfo.changeType_);
1128 if (changeType == nullptr) {
1129 return nullptr;
1130 }
1131 napi_value uri = Convert2JSValue(env, changeInfo.uris_.front().ToString());
1132 if (uri == nullptr) {
1133 return nullptr;
1134 }
1135 auto &valBucket = const_cast<DataShareObserver::ChangeInfo &>(changeInfo);
1136 std::vector<DataShareValuesBucket> VBuckets = ValueProxy::Convert(std::move(valBucket.valueBuckets_));
1137 napi_value valueBuckets = Convert2JSValue(env, VBuckets);
1138 if (valueBuckets == nullptr) {
1139 return nullptr;
1140 }
1141 napi_set_named_property(env, napiValue, "type", changeType);
1142 napi_set_named_property(env, napiValue, "uri", uri);
1143 napi_set_named_property(env, napiValue, "values", valueBuckets);
1144 return napiValue;
1145 }
1146
UnwrapDataSharePredicates(napi_env env,napi_value value,DataSharePredicates & dataSharePredicates)1147 bool DataShareJSUtils::UnwrapDataSharePredicates(napi_env env, napi_value value,
1148 DataSharePredicates &dataSharePredicates)
1149 {
1150 auto predicates = DataSharePredicatesProxy::GetNativePredicates(env, value);
1151 if (predicates == nullptr) {
1152 LOG_ERROR("GetNativePredicates is nullptr.");
1153 return false;
1154 }
1155 dataSharePredicates = DataSharePredicates(predicates->GetOperationList());
1156 return true;
1157 }
1158
Convert2Value(napi_env env,napi_value input,DataSharePredicates & predicates)1159 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataSharePredicates &predicates)
1160 {
1161 if (!UnwrapDataSharePredicates(env, input, predicates)) {
1162 LOG_ERROR("get predicates from js failed");
1163 return napi_invalid_arg;
1164 }
1165 return napi_ok;
1166 }
1167
Convert2Value(napi_env env,napi_value input,DataShareValuesBucket & valueBucket)1168 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataShareValuesBucket &valueBucket)
1169 {
1170 if (!GetValueBucketObject(valueBucket, env, input)) {
1171 LOG_ERROR("get valueBucketObject from js failed");
1172 return napi_invalid_arg;
1173 }
1174 return napi_ok;
1175 }
1176 } // namespace DataShare
1177 } // namespace OHOS