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
18 #include "datashare_log.h"
19 #include "datashare_predicates_proxy.h"
20 #include "datashare_valuebucket_convert.h"
21 #include "napi/native_common.h"
22 #include "napi_datashare_values_bucket.h"
23 #include "securec.h"
24
25 namespace OHOS {
26 namespace DataShare {
Convert2String(napi_env env,napi_value jsStr,const size_t max)27 std::string DataShareJSUtils::Convert2String(napi_env env, napi_value jsStr, const size_t max)
28 {
29 size_t str_buffer_size = max;
30 napi_get_value_string_utf8(env, jsStr, nullptr, 0, &str_buffer_size);
31 char *buf = new (std::nothrow) char[str_buffer_size + 1];
32 if (buf == nullptr) {
33 return "";
34 }
35 size_t len = 0;
36 napi_get_value_string_utf8(env, jsStr, buf, str_buffer_size + 1, &len);
37 buf[len] = 0;
38 std::string value(buf);
39 delete[] buf;
40 return value;
41 }
42
Convert2StrVector(napi_env env,napi_value value,const size_t strMax)43 std::vector<std::string> DataShareJSUtils::Convert2StrVector(napi_env env, napi_value value, const size_t strMax)
44 {
45 NAPI_ASSERT_BASE(env, strMax > 0, "failed on strMax > 0", std::vector<std::string>());
46 uint32_t arrLen = 0;
47 napi_get_array_length(env, value, &arrLen);
48 if (arrLen == 0) {
49 return {};
50 }
51 std::vector<std::string> result;
52 for (size_t i = 0; i < arrLen; ++i) {
53 napi_value element;
54 if (napi_get_element(env, value, i, &element) != napi_ok) {
55 return {};
56 }
57 result.push_back(ConvertAny2String(env, element));
58 }
59 return result;
60 }
61
Convert2U8Vector(napi_env env,napi_value input_array)62 std::vector<uint8_t> DataShareJSUtils::Convert2U8Vector(napi_env env, napi_value input_array)
63 {
64 bool isTypedArray = false;
65 bool isArrayBuffer = false;
66 napi_is_typedarray(env, input_array, &isTypedArray);
67 if (!isTypedArray) {
68 napi_is_arraybuffer(env, input_array, &isArrayBuffer);
69 if (!isArrayBuffer) {
70 LOG_ERROR("unknow type");
71 return {};
72 }
73 }
74 size_t length = 0;
75 void *data = nullptr;
76 if (isTypedArray) {
77 napi_typedarray_type type;
78 napi_value input_buffer = nullptr;
79 size_t byte_offset = 0;
80 napi_get_typedarray_info(env, input_array, &type, &length, &data, &input_buffer, &byte_offset);
81 if (type != napi_uint8_array || data == nullptr) {
82 LOG_ERROR("napi_get_typedarray_info err");
83 return {};
84 }
85 } else {
86 napi_get_arraybuffer_info(env, input_array, &data, &length);
87 if (data == nullptr || length <= 0) {
88 LOG_ERROR("napi_get_arraybuffer_info err");
89 return {};
90 }
91 }
92 return std::vector<uint8_t>((uint8_t *)data, ((uint8_t *)data) + length);
93 }
94
ConvertU8Vector(napi_env env,napi_value jsValue)95 std::vector<uint8_t> DataShareJSUtils::ConvertU8Vector(napi_env env, napi_value jsValue)
96 {
97 bool isTypedArray = false;
98 if (napi_is_typedarray(env, jsValue, &isTypedArray) != napi_ok || !isTypedArray) {
99 return {};
100 }
101
102 napi_typedarray_type type;
103 size_t length = 0;
104 napi_value buffer = nullptr;
105 size_t offset = 0;
106 NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
107 if (type != napi_uint8_array) {
108 return {};
109 }
110 uint8_t *data = nullptr;
111 size_t total = 0;
112 NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
113 length = std::min<size_t>(length, total - offset);
114 std::vector<uint8_t> result(sizeof(uint8_t) + length);
115 int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
116 if (retCode != 0) {
117 return {};
118 }
119 return result;
120 }
121
ConvertAny2String(napi_env env,napi_value jsValue)122 std::string DataShareJSUtils::ConvertAny2String(napi_env env, napi_value jsValue)
123 {
124 napi_valuetype valueType = napi_undefined;
125 NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &valueType), "napi_typeof failed");
126 if (valueType == napi_string) {
127 return DataShareJSUtils::Convert2String(env, jsValue, DataShareJSUtils::DEFAULT_BUF_SIZE);
128 } else if (valueType == napi_number) {
129 double valueNumber;
130 napi_get_value_double(env, jsValue, &valueNumber);
131 return std::to_string(valueNumber);
132 } else if (valueType == napi_boolean) {
133 bool valueBool = false;
134 napi_get_value_bool(env, jsValue, &valueBool);
135 return std::to_string(valueBool);
136 } else if (valueType == napi_null) {
137 return "null";
138 } else if (valueType == napi_object) {
139 std::vector<uint8_t> bytes = DataShareJSUtils::Convert2U8Vector(env, jsValue);
140 std::string ret(bytes.begin(), bytes.end());
141 return ret;
142 }
143
144 return "invalid type";
145 }
146
Convert2JSValue(napi_env env,const std::monostate & value)147 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::monostate &value)
148 {
149 return nullptr;
150 }
151
Convert2JSValue(napi_env env,const std::vector<std::string> & value)152 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<std::string> &value)
153 {
154 napi_value jsValue;
155 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
156 if (status != napi_ok) {
157 return nullptr;
158 }
159
160 for (size_t i = 0; i < value.size(); ++i) {
161 napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
162 }
163 return jsValue;
164 }
165
Convert2JSValue(napi_env env,const std::string & value)166 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::string &value)
167 {
168 napi_value jsValue;
169 napi_status status = napi_create_string_utf8(env, value.c_str(), value.size(), &jsValue);
170 if (status != napi_ok) {
171 return nullptr;
172 }
173 return jsValue;
174 }
175
Convert2JSValue(napi_env env,const std::vector<uint8_t> & value,bool isTypedArray)176 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<uint8_t> &value, bool isTypedArray)
177 {
178 void *native = nullptr;
179 napi_value buffer = nullptr;
180 if (value.empty()) {
181 LOG_DEBUG("vector is empty");
182 return nullptr;
183 }
184 napi_status status = napi_create_arraybuffer(env, value.size(), &native, &buffer);
185 if (status != napi_ok) {
186 return nullptr;
187 }
188 if (memcpy_s(native, value.size(), value.data(), value.size()) != EOK && value.size() > 0) {
189 return nullptr;
190 }
191 if (!isTypedArray) {
192 return buffer;
193 }
194 napi_value jsValue;
195 status = napi_create_typedarray(env, napi_uint8_array, value.size(), buffer, 0, &jsValue);
196 if (status != napi_ok) {
197 return nullptr;
198 }
199 return jsValue;
200 }
201
Convert2JSValue(napi_env env,int32_t value)202 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int32_t value)
203 {
204 napi_value jsValue;
205 napi_status status = napi_create_int32(env, value, &jsValue);
206 if (status != napi_ok) {
207 return nullptr;
208 }
209 return jsValue;
210 }
211
Convert2JSValue(napi_env env,int64_t value)212 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int64_t value)
213 {
214 napi_value jsValue;
215 napi_status status = napi_create_int64(env, value, &jsValue);
216 if (status != napi_ok) {
217 return nullptr;
218 }
219 return jsValue;
220 }
221
Convert2JSValue(napi_env env,uint32_t value)222 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, uint32_t value)
223 {
224 napi_value jsValue;
225 napi_status status = napi_create_uint32(env, value, &jsValue);
226 if (status != napi_ok) {
227 return nullptr;
228 }
229 return jsValue;
230 }
231
Convert2JSValue(napi_env env,double value)232 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, double value)
233 {
234 napi_value jsValue;
235 napi_status status = napi_create_double(env, value, &jsValue);
236 if (status != napi_ok) {
237 return nullptr;
238 }
239 return jsValue;
240 }
241
Convert2JSValue(napi_env env,bool value)242 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, bool value)
243 {
244 napi_value jsValue;
245 napi_status status = napi_get_boolean(env, value, &jsValue);
246 if (status != napi_ok) {
247 return nullptr;
248 }
249 return jsValue;
250 }
251
Convert2JSValue(napi_env env,const std::map<std::string,int> & value)252 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::map<std::string, int> &value)
253 {
254 napi_value jsValue;
255 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
256 if (status != napi_ok) {
257 return nullptr;
258 }
259
260 int index = 0;
261 for (const auto& [device, result] : value) {
262 napi_value jsElement;
263 status = napi_create_array_with_length(env, SYNC_RESULT_ELEMNT_NUM, &jsElement);
264 if (status != napi_ok) {
265 return nullptr;
266 }
267 napi_set_element(env, jsElement, 0, Convert2JSValue(env, device));
268 napi_set_element(env, jsElement, 1, Convert2JSValue(env, result));
269 napi_set_element(env, jsValue, index++, jsElement);
270 }
271
272 return jsValue;
273 }
UnwrapStringFromJS(napi_env env,napi_value param,const std::string & defaultValue)274 std::string DataShareJSUtils::UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue)
275 {
276 size_t size = 0;
277 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
278 return defaultValue;
279 }
280
281 std::string value("");
282 if (size == 0) {
283 return defaultValue;
284 }
285
286 char *buf = new (std::nothrow) char[size + 1];
287 if (buf == nullptr) {
288 return value;
289 }
290 (void)memset_s(buf, size + 1, 0, size + 1);
291
292 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
293 if (rev) {
294 value = buf;
295 } else {
296 value = defaultValue;
297 }
298
299 if (buf != nullptr) {
300 delete[] buf;
301 buf = nullptr;
302 }
303 return value;
304 }
305
Convert2JSValue(napi_env env,const DataShareValuesBucket & valueBucket)306 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataShareValuesBucket &valueBucket)
307 {
308 napi_value res = NewInstance(env, valueBucket);
309 if (res == nullptr) {
310 LOG_ERROR("failed to make new instance of DataShareValueBucket.");
311 }
312 return res;
313 }
314
Convert2ValueObject(napi_env env,napi_value value,bool & status)315 DataShareValueObject DataShareJSUtils::Convert2ValueObject(napi_env env, napi_value value, bool &status)
316 {
317 napi_valuetype valueType = napi_undefined;
318 napi_typeof(env, value, &valueType);
319 status = true;
320 if (valueType == napi_string) {
321 std::string valueString = DataShareJSUtils::UnwrapStringFromJS(env, value);
322 return valueString;
323 } else if (valueType == napi_number) {
324 double valueNumber = 0;
325 napi_get_value_double(env, value, &valueNumber);
326 return valueNumber;
327 } else if (valueType == napi_boolean) {
328 bool valueBool = false;
329 napi_get_value_bool(env, value, &valueBool);
330 return valueBool;
331 } else if (valueType == napi_null) {
332 return {};
333 } else if (valueType == napi_object) {
334 std::vector<uint8_t> valueBlob = DataShareJSUtils::Convert2U8Vector(env, value);
335 return valueBlob;
336 } else {
337 LOG_ERROR("valuesBucket error");
338 status = false;
339 return {};
340 }
341 }
342
Equals(napi_env env,napi_value value,napi_ref copy)343 bool DataShareJSUtils::Equals(napi_env env, napi_value value, napi_ref copy)
344 {
345 if (copy == nullptr) {
346 return (value == nullptr);
347 }
348
349 napi_value copyValue = nullptr;
350 napi_get_reference_value(env, copy, ©Value);
351
352 bool isEqual = false;
353 napi_strict_equals(env, value, copyValue, &isEqual);
354 return isEqual;
355 }
356
Convert2JSValue(napi_env env,const TemplateId & templateId)357 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const TemplateId &templateId)
358 {
359 napi_value tplId = nullptr;
360 napi_create_object(env, &tplId);
361 napi_value subscriberId = Convert2JSValue(env, std::to_string(templateId.subscriberId_));
362 if (subscriberId == nullptr) {
363 return nullptr;
364 }
365 napi_value bundleName = nullptr;
366 bundleName = Convert2JSValue(env, templateId.bundleName_);
367 if (bundleName == nullptr) {
368 return nullptr;
369 }
370 napi_set_named_property(env, tplId, "subscriberId", subscriberId);
371 napi_set_named_property(env, tplId, "bundleName", bundleName);
372 return tplId;
373 }
374
Convert2JSValue(napi_env env,const RdbChangeNode & changeNode)375 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const RdbChangeNode &changeNode)
376 {
377 napi_value jsRdbChangeNode = nullptr;
378 napi_create_object(env, &jsRdbChangeNode);
379
380 napi_value uri = nullptr;
381 uri = Convert2JSValue(env, changeNode.uri_);
382 if (uri == nullptr) {
383 return nullptr;
384 }
385 napi_value templateId = nullptr;
386 templateId = Convert2JSValue(env, changeNode.templateId_);
387 if (templateId == nullptr) {
388 return nullptr;
389 }
390 napi_value data = Convert2JSValue(env, changeNode.data_);
391 if (data == nullptr) {
392 return nullptr;
393 }
394 napi_set_named_property(env, jsRdbChangeNode, "uri", uri);
395 napi_set_named_property(env, jsRdbChangeNode, "templateId", templateId);
396 napi_set_named_property(env, jsRdbChangeNode, "data", data);
397 return jsRdbChangeNode;
398 }
399
Convert2JSValue(napi_env env,PublishedDataItem & publishedDataItem)400 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, PublishedDataItem &publishedDataItem)
401 {
402 napi_value jsPublishedDataItem = nullptr;
403 napi_create_object(env, &jsPublishedDataItem);
404
405 napi_value key = Convert2JSValue(env, publishedDataItem.key_);
406 if (key == nullptr) {
407 return nullptr;
408 }
409
410 napi_value subscriberId = nullptr;
411 subscriberId = Convert2JSValue(env, std::to_string(publishedDataItem.subscriberId_));
412 if (subscriberId == nullptr) {
413 return nullptr;
414 }
415
416 napi_value data = nullptr;
417 if (publishedDataItem.IsAshmem()) {
418 data = Convert2JSValue(env, std::get<std::vector<uint8_t>>(publishedDataItem.GetData()), false);
419 } else {
420 data = Convert2JSValue(env, std::get<std::string>(publishedDataItem.GetData()));
421 }
422 if (data == nullptr) {
423 return nullptr;
424 }
425
426 napi_set_named_property(env, jsPublishedDataItem, "key", key);
427 napi_set_named_property(env, jsPublishedDataItem, "subscriberId", subscriberId);
428 napi_set_named_property(env, jsPublishedDataItem, "data", data);
429 return jsPublishedDataItem;
430 }
431
Convert2JSValue(napi_env env,std::vector<PublishedDataItem> & publishedDataItems)432 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, std::vector<PublishedDataItem> &publishedDataItems)
433 {
434 napi_value jsValue;
435 napi_status status = napi_create_array_with_length(env, publishedDataItems.size(), &jsValue);
436 if (status != napi_ok) {
437 return nullptr;
438 }
439
440 for (size_t i = 0; i < publishedDataItems.size(); ++i) {
441 napi_set_element(env, jsValue, i, Convert2JSValue(env, publishedDataItems[i]));
442 }
443 return jsValue;
444 }
445
Convert2JSValue(napi_env env,PublishedDataChangeNode & changeNode)446 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, PublishedDataChangeNode &changeNode)
447 {
448 napi_value jsPublishedDataChangeNode = nullptr;
449 napi_create_object(env, &jsPublishedDataChangeNode);
450
451 napi_value bundleName = nullptr;
452 bundleName = Convert2JSValue(env, changeNode.ownerBundleName_);
453 if (bundleName == nullptr) {
454 return nullptr;
455 }
456 napi_value data = nullptr;
457 data = Convert2JSValue(env, changeNode.datas_);
458 if (data == nullptr) {
459 return nullptr;
460 }
461 napi_set_named_property(env, jsPublishedDataChangeNode, "bundleName", bundleName);
462 napi_set_named_property(env, jsPublishedDataChangeNode, "data", data);
463 return jsPublishedDataChangeNode;
464 }
465
Convert2JSValue(napi_env env,const OperationResult & results)466 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const OperationResult &results)
467 {
468 napi_value jsOperationResult = nullptr;
469 napi_create_object(env, &jsOperationResult);
470
471 napi_value key = nullptr;
472 key = Convert2JSValue(env, results.key_);
473 if (key == nullptr) {
474 return nullptr;
475 }
476
477 napi_value result = nullptr;
478 result = Convert2JSValue(env, results.errCode_);
479 if (result == nullptr) {
480 return nullptr;
481 }
482 napi_set_named_property(env, jsOperationResult, "key", key);
483 napi_set_named_property(env, jsOperationResult, "result", result);
484 return jsOperationResult;
485 }
486
Convert2JSValue(napi_env env,const std::vector<OperationResult> & results)487 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<OperationResult> &results)
488 {
489 napi_value jsValue;
490 napi_status status = napi_create_array_with_length(env, results.size(), &jsValue);
491 if (status != napi_ok) {
492 return nullptr;
493 }
494
495 for (size_t i = 0; i < results.size(); ++i) {
496 napi_set_element(env, jsValue, i, Convert2JSValue(env, results[i]));
497 }
498 return jsValue;
499 }
500
UnwrapTemplatePredicates(napi_env env,napi_value jsPredicates,std::vector<PredicateTemplateNode> & predicates)501 bool DataShareJSUtils::UnwrapTemplatePredicates(napi_env env, napi_value jsPredicates,
502 std::vector<PredicateTemplateNode> &predicates)
503 {
504 napi_value keys = nullptr;
505 napi_get_property_names(env, jsPredicates, &keys);
506 uint32_t arrLen = 0;
507 napi_status status = napi_get_array_length(env, keys, &arrLen);
508 if (status != napi_ok) {
509 LOG_ERROR("UnwrapTemplatePredicates error");
510 return false;
511 }
512 LOG_DEBUG("TemplatePredicates length : %{public}u", arrLen);
513 for (size_t i = 0; i < arrLen; ++i) {
514 napi_value key = nullptr;
515 status = napi_get_element(env, keys, i, &key);
516 if (status != napi_ok) {
517 LOG_ERROR("UnwrapTemplatePredicates err");
518 return false;
519 }
520 napi_value value = nullptr;
521 status = napi_get_property(env, jsPredicates, key, &value);
522 if (status != napi_ok) {
523 LOG_ERROR("UnwrapTemplatePredicates err");
524 return false;
525 }
526 std::string keyStr = UnwrapStringFromJS(env, key);
527 std::string valueStr = UnwrapStringFromJS(env, value);
528 PredicateTemplateNode node(keyStr, valueStr);
529 predicates.emplace_back(node);
530 }
531 return true;
532 }
533
Convert2Template(napi_env env,napi_value value)534 Template DataShareJSUtils::Convert2Template(napi_env env, napi_value value)
535 {
536 napi_valuetype valueType = napi_undefined;
537 napi_typeof(env, value, &valueType);
538 if (valueType != napi_object) {
539 LOG_ERROR("Convert2Template error, value is not object");
540 return {};
541 }
542 napi_value jsPredicates;
543 auto status = napi_get_named_property(env, value, "predicates", &jsPredicates);
544 if (status != napi_ok) {
545 LOG_ERROR("Convert predicates failed");
546 return {};
547 }
548 std::vector<PredicateTemplateNode> predicates;
549 if (!UnwrapTemplatePredicates(env, jsPredicates, predicates)) {
550 LOG_ERROR("UnwrapTemplateNodeVector failed");
551 return {};
552 }
553
554 std::string scheduler;
555 if (!UnwrapStringByPropertyName(env, value, "scheduler", scheduler)) {
556 LOG_ERROR("Convert scheduler failed");
557 return {};
558 }
559 Template tpl(predicates, scheduler);
560 return tpl;
561 }
562
Convert2TemplateId(napi_env env,napi_value value)563 TemplateId DataShareJSUtils::Convert2TemplateId(napi_env env, napi_value value)
564 {
565 napi_valuetype valueType = napi_undefined;
566 napi_typeof(env, value, &valueType);
567 if (valueType != napi_object) {
568 LOG_ERROR("Convert2TemplateId error, value is not object");
569 return {};
570 }
571
572 TemplateId templateId;
573 std::string strSubId;
574 if (!UnwrapStringByPropertyName(env, value, "subscriberId", strSubId)) {
575 LOG_ERROR("Convert subscriberId failed");
576 return {};
577 }
578 templateId.subscriberId_ = atoll(strSubId.c_str());
579 if (!UnwrapStringByPropertyName(env, value, "bundleNameOfOwner", templateId.bundleName_)) {
580 LOG_ERROR("Convert bundleNameOfOwner failed");
581 return {};
582 }
583 return templateId;
584 }
585
UnwrapPublishedDataItem(napi_env env,napi_value jsObject,PublishedDataItem & publishedDataItem)586 bool DataShareJSUtils::UnwrapPublishedDataItem(napi_env env, napi_value jsObject, PublishedDataItem &publishedDataItem)
587 {
588 napi_valuetype valueType = napi_undefined;
589 napi_typeof(env, jsObject, &valueType);
590 if (valueType != napi_object) {
591 LOG_ERROR("UnwrapPublishedDataItem error, value is not object");
592 return false;
593 }
594
595 if (!UnwrapStringByPropertyName(env, jsObject, "key", publishedDataItem.key_)) {
596 LOG_ERROR("Convert key failed");
597 return false;
598 }
599 std::string keyStr = "data";
600 napi_value jsDataKey = Convert2JSValue(env, keyStr);
601 napi_value jsDataValue = nullptr;
602 napi_get_property(env, jsObject, jsDataKey, &jsDataValue);
603 napi_typeof(env, jsDataValue, &valueType);
604 PublishedDataItem::DataType value;
605 if (valueType == napi_object) {
606 value = Convert2U8Vector(env, jsDataValue);
607 publishedDataItem.Set(value);
608 } else if (valueType == napi_string) {
609 value = Convert2String(env, jsDataValue);
610 publishedDataItem.Set(value);
611 } else {
612 LOG_ERROR("Convert dataValue failed, type is %{public}d", valueType);
613 return false;
614 }
615 std::string strSubId;
616 if (!UnwrapStringByPropertyName(env, jsObject, "subscriberId", strSubId)) {
617 LOG_ERROR("Convert subscriberId failed");
618 return false;
619 }
620 publishedDataItem.subscriberId_ = atoll(strSubId.c_str());
621 return true;
622 }
623
IsArrayForNapiValue(napi_env env,napi_value param,uint32_t & arraySize)624 bool DataShareJSUtils::IsArrayForNapiValue(napi_env env, napi_value param, uint32_t &arraySize)
625 {
626 bool isArray = false;
627 arraySize = 0;
628
629 if (napi_is_array(env, param, &isArray) != napi_ok || isArray == false) {
630 return false;
631 }
632
633 if (napi_get_array_length(env, param, &arraySize) != napi_ok) {
634 return false;
635 }
636 return true;
637 }
638
UnwrapPublishedDataItemVector(napi_env env,napi_value value,std::vector<PublishedDataItem> & publishedDataItems)639 bool DataShareJSUtils::UnwrapPublishedDataItemVector(napi_env env, napi_value value,
640 std::vector<PublishedDataItem> &publishedDataItems)
641 {
642 uint32_t arraySize = 0;
643
644 if (!IsArrayForNapiValue(env, value, arraySize)) {
645 LOG_ERROR("IsArrayForNapiValue is false");
646 return false;
647 }
648
649 for (uint32_t i = 0; i < arraySize; i++) {
650 napi_value jsValue = nullptr;
651 if (napi_get_element(env, value, i, &jsValue) != napi_ok) {
652 LOG_ERROR("napi_get_element is false");
653 return false;
654 }
655
656 PublishedDataItem publishedDataItem;
657 if (!UnwrapPublishedDataItem(env, jsValue, publishedDataItem)) {
658 LOG_ERROR("UnwrapPublishedDataItem failed");
659 return false;
660 }
661 publishedDataItems.emplace_back(std::move(publishedDataItem));
662 }
663 return true;
664 }
665
Convert2PublishedData(napi_env env,napi_value value)666 Data DataShareJSUtils::Convert2PublishedData(napi_env env, napi_value value)
667 {
668 napi_valuetype valueType = napi_undefined;
669 napi_typeof(env, value, &valueType);
670 if (valueType != napi_object) {
671 LOG_ERROR("Convert2PublishedData error, value is not object");
672 return {};
673 }
674 Data data;
675 if (!UnwrapPublishedDataItemVector(env, value, data.datas_)) {
676 LOG_ERROR("UnwrapPublishedDataItems failed");
677 return {};
678 }
679 return data;
680 }
681
UnwrapStringByPropertyName(napi_env env,napi_value jsObject,const char * propertyName,std::string & value)682 bool DataShareJSUtils::UnwrapStringByPropertyName(
683 napi_env env, napi_value jsObject, const char *propertyName, std::string &value)
684 {
685 napi_value jsResult = nullptr;
686 auto status = napi_get_named_property(env, jsObject, propertyName, &jsResult);
687 if ((status != napi_ok) || (jsResult == nullptr)) {
688 LOG_ERROR("Convert bundleNameOfOwner failed");
689 return false;
690 }
691 napi_valuetype valueType = napi_undefined;
692 napi_typeof(env, jsResult, &valueType);
693 if (valueType != napi_string) {
694 LOG_ERROR("Convert2PublishedData error, value is not object");
695 return false;
696 }
697 value = DataShareJSUtils::Convert2String(env, jsResult);
698 return true;
699 }
700
Convert2JSValue(napi_env env,const std::vector<BatchUpdateResult> & result)701 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<BatchUpdateResult> &result)
702 {
703 napi_value jsResult = nullptr;
704 napi_status status = napi_create_object(env, &jsResult);
705 if (status != napi_ok) {
706 LOG_ERROR("Create object failed, ret : %{public}d", status);
707 return nullptr;
708 }
709 for (const auto &valueArray : result) {
710 napi_value values;
711 if (napi_create_array(env, &values) != napi_ok) {
712 LOG_ERROR("Create array failed");
713 return nullptr;
714 }
715 uint32_t index = 0;
716 for (const auto &value : valueArray.codes) {
717 napi_value jsValue = Convert2JSValue(env, value);
718 if (napi_set_element(env, values, index++, jsValue) != napi_ok) {
719 LOG_ERROR("Set to array failed");
720 return nullptr;
721 }
722 }
723 if (napi_set_named_property(env, jsResult, valueArray.uri.c_str(), values) != napi_ok) {
724 LOG_ERROR("Set to map failed");
725 return nullptr;
726 }
727 }
728 return jsResult;
729 }
730
Convert2Value(napi_env env,napi_value input,UpdateOperation & operation)731 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, UpdateOperation& operation)
732 {
733 napi_valuetype valueType = napi_undefined;
734 napi_typeof(env, input, &valueType);
735 if (valueType != napi_object) {
736 LOG_ERROR("value is not object");
737 return napi_invalid_arg;
738 }
739 if (Convert2Value(env, input, "predicates", operation.predicates) != napi_ok) {
740 return napi_invalid_arg;
741 }
742 if (Convert2Value(env, input, "values", operation.valuesBucket) != napi_ok) {
743 return napi_invalid_arg;
744 }
745 return napi_ok;
746 }
747
Convert2Value(napi_env env,napi_value input,std::string & str)748 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, std::string &str)
749 {
750 size_t strBufferSize = DEFAULT_BUF_SIZE;
751 napi_get_value_string_utf8(env, input, nullptr, 0, &strBufferSize);
752 char *buf = new (std::nothrow) char[strBufferSize + 1];
753 if (buf == nullptr) {
754 return napi_invalid_arg;
755 }
756 size_t len = 0;
757 napi_get_value_string_utf8(env, input, buf, strBufferSize + 1, &len);
758 buf[len] = 0;
759 str = std::string(buf);
760 delete[] buf;
761 return napi_ok;
762 }
763
Convert2Value(napi_env env,napi_value input,OHOS::DataShare::DataShareObserver::ChangeType & changeType)764 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input,
765 OHOS::DataShare::DataShareObserver::ChangeType &changeType)
766 {
767 uint32_t number = 0;
768 napi_status status = napi_get_value_uint32(env, input, &number);
769 changeType = static_cast<OHOS::DataShare::DataShareObserver::ChangeType>(number);
770 return status;
771 }
772
Convert2Value(napi_env env,napi_value input,DataShareObserver::ChangeInfo & changeInfo)773 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataShareObserver::ChangeInfo &changeInfo)
774 {
775 napi_valuetype type = napi_undefined;
776 napi_typeof(env, input, &type);
777 if (type != napi_object) {
778 LOG_ERROR("ChangeInfo is not object");
779 return napi_invalid_arg;
780 }
781 std::string uriStr;
782 std::vector<DataShareValuesBucket> valuebuckets = {};
783 if (Convert2Value(env, input, "type", changeInfo.changeType_) != napi_ok) {
784 return napi_invalid_arg;
785 }
786 if (Convert2Value(env, input, "uri", uriStr) != napi_ok) {
787 return napi_invalid_arg;
788 }
789 if (Convert2Value(env, input, "values", valuebuckets) != napi_ok) {
790 return napi_invalid_arg;
791 }
792
793 Uri uri(uriStr);
794 changeInfo.uris_.push_back(uri);
795 changeInfo.valueBuckets_ = ValueProxy::Convert(std::move(valuebuckets));
796 return napi_ok;
797 }
798
Convert2JSValue(napi_env env,const DataShareObserver::ChangeInfo & changeInfo)799 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const DataShareObserver::ChangeInfo &changeInfo)
800 {
801 napi_value napiValue = nullptr;
802 napi_create_object(env, &napiValue);
803 napi_value changeType = Convert2JSValue(env, changeInfo.changeType_);
804 if (changeType == nullptr) {
805 return nullptr;
806 }
807 napi_value uri = Convert2JSValue(env, changeInfo.uris_.front().ToString());
808 if (uri == nullptr) {
809 return nullptr;
810 }
811 auto &valBucket = const_cast<DataShareObserver::ChangeInfo &>(changeInfo);
812 std::vector<DataShareValuesBucket> VBuckets = ValueProxy::Convert(std::move(valBucket.valueBuckets_));
813 napi_value valueBuckets = Convert2JSValue(env, VBuckets);
814 if (valueBuckets == nullptr) {
815 return nullptr;
816 }
817 napi_set_named_property(env, napiValue, "type", changeType);
818 napi_set_named_property(env, napiValue, "uri", uri);
819 napi_set_named_property(env, napiValue, "values", valueBuckets);
820 return napiValue;
821 }
822
UnwrapDataSharePredicates(napi_env env,napi_value value,DataSharePredicates & dataSharePredicates)823 bool DataShareJSUtils::UnwrapDataSharePredicates(napi_env env, napi_value value,
824 DataSharePredicates &dataSharePredicates)
825 {
826 auto predicates = DataSharePredicatesProxy::GetNativePredicates(env, value);
827 if (predicates == nullptr) {
828 LOG_ERROR("GetNativePredicates is nullptr.");
829 return false;
830 }
831 dataSharePredicates = DataSharePredicates(predicates->GetOperationList());
832 return true;
833 }
834
Convert2Value(napi_env env,napi_value input,DataSharePredicates & predicates)835 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataSharePredicates &predicates)
836 {
837 if (!UnwrapDataSharePredicates(env, input, predicates)) {
838 LOG_ERROR("get predicates from js failed");
839 return napi_invalid_arg;
840 }
841 return napi_ok;
842 }
843
Convert2Value(napi_env env,napi_value input,DataShareValuesBucket & valueBucket)844 int32_t DataShareJSUtils::Convert2Value(napi_env env, napi_value input, DataShareValuesBucket &valueBucket)
845 {
846 if (!GetValueBucketObject(valueBucket, env, input)) {
847 LOG_ERROR("get valueBucketObject from js failed");
848 return napi_invalid_arg;
849 }
850 return napi_ok;
851 }
852 } // namespace DataShare
853 } // namespace OHOS