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 "datashare_log.h"
18
19 #include "securec.h"
20
21 namespace OHOS {
22 namespace DataShare {
Convert2String(napi_env env,napi_value jsStr,const size_t max)23 std::string DataShareJSUtils::Convert2String(napi_env env, napi_value jsStr, const size_t max)
24 {
25 NAPI_ASSERT_BASE(env, max > 0, "failed on max > 0", std::string());
26 char *buf = new char[max + 1];
27 size_t len = 0;
28 napi_get_value_string_utf8(env, jsStr, buf, max, &len);
29 buf[len] = 0;
30 std::string value(buf);
31 delete[] buf;
32 return value;
33 }
34
Convert2StrVector(napi_env env,napi_value value,const size_t strMax)35 std::vector<std::string> DataShareJSUtils::Convert2StrVector(napi_env env, napi_value value, const size_t strMax)
36 {
37 NAPI_ASSERT_BASE(env, strMax > 0, "failed on strMax > 0", std::vector<std::string>());
38 uint32_t arrLen = 0;
39 napi_get_array_length(env, value, &arrLen);
40 if (arrLen == 0) {
41 return {};
42 }
43 std::vector<std::string> result;
44 for (size_t i = 0; i < arrLen; ++i) {
45 napi_value element;
46 napi_get_element(env, value, i, &element);
47 result.push_back(ConvertAny2String(env, element));
48 }
49 return result;
50 }
51
Convert2U8Vector(napi_env env,napi_value input_array)52 std::vector<uint8_t> DataShareJSUtils::Convert2U8Vector(napi_env env, napi_value input_array)
53 {
54 bool isTypedArray = false;
55 napi_is_typedarray(env, input_array, &isTypedArray);
56 if (!isTypedArray) {
57 return {};
58 }
59
60 napi_typedarray_type type;
61 napi_value input_buffer = nullptr;
62 size_t byte_offset = 0;
63 size_t length = 0;
64 void *data = nullptr;
65 napi_get_typedarray_info(env, input_array, &type, &length, &data, &input_buffer, &byte_offset);
66 if (type != napi_uint8_array || data == nullptr) {
67 return {};
68 }
69 return std::vector<uint8_t>((uint8_t *)data, ((uint8_t *)data) + length);
70 }
71
ConvertU8Vector(napi_env env,napi_value jsValue)72 std::vector<uint8_t> DataShareJSUtils::ConvertU8Vector(napi_env env, napi_value jsValue)
73 {
74 bool isTypedArray = false;
75 if (napi_is_typedarray(env, jsValue, &isTypedArray) != napi_ok || !isTypedArray) {
76 return {};
77 }
78
79 napi_typedarray_type type;
80 size_t length = 0;
81 napi_value buffer = nullptr;
82 size_t offset = 0;
83 NAPI_CALL_BASE(env, napi_get_typedarray_info(env, jsValue, &type, &length, nullptr, &buffer, &offset), {});
84 if (type != napi_uint8_array) {
85 return {};
86 }
87 uint8_t *data = nullptr;
88 size_t total = 0;
89 NAPI_CALL_BASE(env, napi_get_arraybuffer_info(env, buffer, reinterpret_cast<void **>(&data), &total), {});
90 length = std::min<size_t>(length, total - offset);
91 std::vector<uint8_t> result(sizeof(uint8_t) + length);
92 int retCode = memcpy_s(result.data(), result.size(), &data[offset], length);
93 if (retCode != 0) {
94 return {};
95 }
96 return result;
97 }
98
ConvertAny2String(napi_env env,napi_value jsValue)99 std::string DataShareJSUtils::ConvertAny2String(napi_env env, napi_value jsValue)
100 {
101 napi_valuetype valueType = napi_undefined;
102 NAPI_CALL_BASE(env, napi_typeof(env, jsValue, &valueType), "napi_typeof failed");
103 if (valueType == napi_string) {
104 return DataShareJSUtils::Convert2String(env, jsValue, DataShareJSUtils::DEFAULT_BUF_SIZE);
105 } else if (valueType == napi_number) {
106 double valueNumber;
107 napi_get_value_double(env, jsValue, &valueNumber);
108 return std::to_string(valueNumber);
109 } else if (valueType == napi_boolean) {
110 bool valueBool = false;
111 napi_get_value_bool(env, jsValue, &valueBool);
112 return std::to_string(valueBool);
113 } else if (valueType == napi_null) {
114 return "null";
115 } else if (valueType == napi_object) {
116 std::vector<uint8_t> bytes = DataShareJSUtils::Convert2U8Vector(env, jsValue);
117 std::string ret(bytes.begin(), bytes.end());
118 return ret;
119 }
120
121 return "invalid type";
122 }
123
Convert2JSValue(napi_env env,const std::vector<std::string> & value)124 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<std::string> &value)
125 {
126 napi_value jsValue;
127 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
128 if (status != napi_ok) {
129 return nullptr;
130 }
131
132 for (size_t i = 0; i < value.size(); ++i) {
133 napi_set_element(env, jsValue, i, Convert2JSValue(env, value[i]));
134 }
135 return jsValue;
136 }
137
Convert2JSValue(napi_env env,const std::string & value)138 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::string &value)
139 {
140 napi_value jsValue;
141 napi_status status = napi_create_string_utf8(env, value.c_str(), value.size(), &jsValue);
142 if (status != napi_ok) {
143 return nullptr;
144 }
145 return jsValue;
146 }
147
Convert2JSValue(napi_env env,const std::vector<uint8_t> & value)148 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::vector<uint8_t> &value)
149 {
150 napi_value jsValue;
151 void *native = nullptr;
152 napi_value buffer = nullptr;
153 napi_status status = napi_create_arraybuffer(env, value.size(), &native, &buffer);
154 if (status != napi_ok) {
155 return nullptr;
156 }
157 if (memcpy_s(native, value.size(), value.data(), value.size()) != EOK && value.size() > 0) {
158 return nullptr;
159 }
160 status = napi_create_typedarray(env, napi_uint8_array, value.size(), buffer, 0, &jsValue);
161 if (status != napi_ok) {
162 return nullptr;
163 }
164 return jsValue;
165 }
166
Convert2JSValue(napi_env env,int32_t value)167 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int32_t value)
168 {
169 napi_value jsValue;
170 napi_status status = napi_create_int32(env, value, &jsValue);
171 if (status != napi_ok) {
172 return nullptr;
173 }
174 return jsValue;
175 }
176
Convert2JSValue(napi_env env,int64_t value)177 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, int64_t value)
178 {
179 napi_value jsValue;
180 napi_status status = napi_create_int64(env, value, &jsValue);
181 if (status != napi_ok) {
182 return nullptr;
183 }
184 return jsValue;
185 }
186
Convert2JSValue(napi_env env,double value)187 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, double value)
188 {
189 napi_value jsValue;
190 napi_status status = napi_create_double(env, value, &jsValue);
191 if (status != napi_ok) {
192 return nullptr;
193 }
194 return jsValue;
195 }
196
Convert2JSValue(napi_env env,bool value)197 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, bool value)
198 {
199 napi_value jsValue;
200 napi_status status = napi_get_boolean(env, value, &jsValue);
201 if (status != napi_ok) {
202 return nullptr;
203 }
204 return jsValue;
205 }
206
Convert2JSValue(napi_env env,const std::map<std::string,int> & value)207 napi_value DataShareJSUtils::Convert2JSValue(napi_env env, const std::map<std::string, int> &value)
208 {
209 napi_value jsValue;
210 napi_status status = napi_create_array_with_length(env, value.size(), &jsValue);
211 if (status != napi_ok) {
212 return nullptr;
213 }
214
215 int index = 0;
216 for (const auto& [device, result] : value) {
217 napi_value jsElement;
218 status = napi_create_array_with_length(env, SYNC_RESULT_ELEMNT_NUM, &jsElement);
219 if (status != napi_ok) {
220 return nullptr;
221 }
222 napi_set_element(env, jsElement, 0, Convert2JSValue(env, device));
223 napi_set_element(env, jsElement, 1, Convert2JSValue(env, result));
224 napi_set_element(env, jsValue, index++, jsElement);
225 }
226
227 return jsValue;
228 }
UnwrapStringFromJS(napi_env env,napi_value param,const std::string & defaultValue)229 std::string DataShareJSUtils::UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue)
230 {
231 size_t size = 0;
232 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
233 return defaultValue;
234 }
235
236 std::string value("");
237 if (size == 0) {
238 return defaultValue;
239 }
240
241 char *buf = new (std::nothrow) char[size + 1];
242 if (buf == nullptr) {
243 return value;
244 }
245 (void)memset_s(buf, size + 1, 0, size + 1);
246
247 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
248 if (rev) {
249 value = buf;
250 } else {
251 value = defaultValue;
252 }
253
254 if (buf != nullptr) {
255 delete[] buf;
256 buf = nullptr;
257 }
258 return value;
259 }
Equals(napi_env env,napi_value value,napi_ref copy)260 bool DataShareJSUtils::Equals(napi_env env, napi_value value, napi_ref copy)
261 {
262 if (copy == nullptr) {
263 return (value == nullptr);
264 }
265
266 napi_value copyValue = nullptr;
267 napi_get_reference_value(env, copy, ©Value);
268
269 bool isEqual = false;
270 napi_strict_equals(env, value, copyValue, &isEqual);
271 return isEqual;
272 }
273 } // namespace DataShare
274 } // namespace OHOS