• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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, &copyValue);
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