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 "napi_parse_utils.h"
17
18 #include "nweb_log.h"
19
20 namespace OHOS {
21 namespace NWeb {
22 namespace {
ConvertToNapiHandlerOfString(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)23 bool ConvertToNapiHandlerOfString(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
24 {
25 std::string msgStr = src->GetString();
26 napi_create_string_utf8(env, msgStr.c_str(), msgStr.length(), &dst);
27 return true;
28 }
29
ConvertToNapiHandlerOfBinary(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)30 bool ConvertToNapiHandlerOfBinary(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
31 {
32 std::vector<uint8_t> msgArr = src->GetBinary();
33 void *arrayData = nullptr;
34 napi_create_arraybuffer(env, msgArr.size(), &arrayData, &dst);
35 if (arrayData == nullptr) {
36 WVLOG_E("Create arraybuffer failed");
37 return false;
38 }
39 for (size_t i = 0; i < msgArr.size(); ++i) {
40 *(uint8_t*)((uint8_t*)arrayData + i) = msgArr[i];
41 }
42 return true;
43 }
44
ConvertToNapiHandlerOfBoolean(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)45 bool ConvertToNapiHandlerOfBoolean(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
46 {
47 bool value = src->GetBoolean();
48 napi_get_boolean(env, value, &dst);
49 return true;
50 }
51
ConvertToNapiHandlerOfInteger(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)52 bool ConvertToNapiHandlerOfInteger(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
53 {
54 int64_t value = src->GetInt64();
55 napi_create_int64(env, value, &dst);
56 return true;
57 }
58
ConvertToNapiHandlerOfDouble(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)59 bool ConvertToNapiHandlerOfDouble(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
60 {
61 double value = src->GetDouble();
62 napi_create_double(env, value, &dst);
63 return true;
64 }
65
ConvertToNapiHandlerOfError(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)66 bool ConvertToNapiHandlerOfError(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
67 {
68 std::string errorName = src->GetErrName();
69 std::string errorMsg = src->GetErrName() + ": " + src->GetErrMsg();
70 napi_value name = nullptr;
71 napi_value message = nullptr;
72 napi_create_string_utf8(env, errorName.c_str(), errorName.length(), &name);
73 napi_create_string_utf8(env, errorMsg.c_str(), errorMsg.length(), &message);
74 napi_create_error(env, name, message, &dst);
75 return true;
76 }
77
ConvertToNapiHandlerOfStringArray(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)78 bool ConvertToNapiHandlerOfStringArray(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
79 {
80 std::vector<std::string> values = src->GetStringArray();
81 napi_create_array(env, &dst);
82 bool isArray = false;
83 if (napi_is_array(env, dst, &isArray) != napi_ok || !isArray) {
84 WVLOG_E("Create array failed");
85 return false;
86 }
87
88 int32_t index = 0;
89 for (auto value : values) {
90 napi_value element = nullptr;
91 napi_create_string_utf8(env, value.c_str(), value.length(), &element);
92 napi_set_element(env, dst, index++, element);
93 }
94 return true;
95 }
96
ConvertToNapiHandlerOfBooleanArray(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)97 bool ConvertToNapiHandlerOfBooleanArray(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
98 {
99 std::vector<bool> values = src->GetBooleanArray();
100 napi_create_array(env, &dst);
101 bool isArray = false;
102 if (napi_is_array(env, dst, &isArray) != napi_ok || !isArray) {
103 WVLOG_E("Create array failed");
104 return false;
105 }
106
107 int32_t index = 0;
108 for (auto value : values) {
109 napi_value element = nullptr;
110 napi_get_boolean(env, value, &element);
111 napi_set_element(env, dst, index++, element);
112 }
113 return true;
114 }
115
ConvertToNapiHandlerOfDoubleArray(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)116 bool ConvertToNapiHandlerOfDoubleArray(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
117 {
118 std::vector<double> values = src->GetDoubleArray();
119 napi_create_array(env, &dst);
120 bool isArray = false;
121 if (napi_is_array(env, dst, &isArray) != napi_ok || !isArray) {
122 WVLOG_E("Create array failed");
123 return false;
124 }
125
126 int32_t index = 0;
127 for (auto value : values) {
128 napi_value element = nullptr;
129 napi_create_double(env, value, &element);
130 napi_set_element(env, dst, index++, element);
131 }
132 return true;
133 }
134
ConvertToNapiHandlerOfInt64Array(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)135 bool ConvertToNapiHandlerOfInt64Array(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
136 {
137 std::vector<int64_t> values = src->GetInt64Array();
138 napi_create_array(env, &dst);
139 bool isArray = false;
140 if (napi_is_array(env, dst, &isArray) != napi_ok || !isArray) {
141 WVLOG_E("Create array failed");
142 return false;
143 }
144
145 int32_t index = 0;
146 for (auto value : values) {
147 napi_value element = nullptr;
148 napi_create_int64(env, value, &element);
149 napi_set_element(env, dst, index++, element);
150 }
151 return true;
152 }
153 } // namespace
154
CreateEnumConstructor(napi_env env,napi_callback_info info)155 napi_value NapiParseUtils::CreateEnumConstructor(napi_env env, napi_callback_info info)
156 {
157 napi_value arg = nullptr;
158 napi_get_cb_info(env, info, nullptr, nullptr, &arg, nullptr);
159 return arg;
160 }
161
ToInt32Value(napi_env env,int32_t number)162 napi_value NapiParseUtils::ToInt32Value(napi_env env, int32_t number)
163 {
164 napi_value result = nullptr;
165 napi_create_int32(env, number, &result);
166 return result;
167 }
168
ParseInt32(napi_env env,napi_value argv,int32_t & outValue)169 bool NapiParseUtils::ParseInt32(napi_env env, napi_value argv, int32_t& outValue)
170 {
171 napi_valuetype valueType = napi_undefined;
172
173 napi_typeof(env, argv, &valueType);
174 if (valueType != napi_number) {
175 return false;
176 }
177
178 int32_t number = 0;
179 napi_get_value_int32(env, argv, &number);
180 outValue = number;
181
182 return true;
183 }
184
ParseUint32(napi_env env,napi_value argv,uint32_t & outValue)185 bool NapiParseUtils::ParseUint32(napi_env env, napi_value argv, uint32_t& outValue)
186 {
187 napi_valuetype valueType = napi_undefined;
188
189 napi_typeof(env, argv, &valueType);
190 if (valueType != napi_number) {
191 return false;
192 }
193
194 uint32_t number = 0;
195 napi_get_value_uint32(env, argv, &number);
196 outValue = number;
197
198 return true;
199 }
200
ParseUint64(napi_env env,napi_value argv,uint64_t & outValue,bool * lossless)201 bool NapiParseUtils::ParseUint64(napi_env env, napi_value argv, uint64_t& outValue, bool *lossless)
202 {
203 napi_valuetype valueType = napi_undefined;
204
205 napi_typeof(env, argv, &valueType);
206 if (valueType != napi_bigint) {
207 return false;
208 }
209
210 uint64_t number = 0;
211 napi_get_value_bigint_uint64(env, argv, &number, lossless);
212 outValue = number;
213
214 return true;
215 }
216
ParseInt64(napi_env env,napi_value argv,int64_t & outValue)217 bool NapiParseUtils::ParseInt64(napi_env env, napi_value argv, int64_t& outValue)
218 {
219 napi_valuetype valueType = napi_undefined;
220
221 napi_typeof(env, argv, &valueType);
222 if (valueType != napi_number) {
223 return false;
224 }
225
226 int64_t number = 0;
227 napi_get_value_int64(env, argv, &number);
228 outValue = number;
229
230 return true;
231 }
232
ParseString(napi_env env,napi_value argv,std::string & outValue)233 bool NapiParseUtils::ParseString(napi_env env, napi_value argv, std::string& outValue)
234 {
235 size_t bufferSize = 0;
236 napi_valuetype valueType = napi_undefined;
237
238 napi_typeof(env, argv, &valueType);
239 if (valueType != napi_string) {
240 WVLOG_E("Not a valid napi string");
241 return false;
242 }
243 napi_get_value_string_utf8(env, argv, nullptr, 0, &bufferSize);
244 if (bufferSize + 1 > UINT_MAX) {
245 WVLOG_E("String length is too long");
246 return false;
247 }
248 char *stringValue = new (std::nothrow) char[bufferSize + 1];
249 if (stringValue == nullptr) {
250 WVLOG_E("new String failed");
251 return false;
252 }
253 size_t jsStringLength = 0;
254 napi_get_value_string_utf8(env, argv, stringValue, bufferSize + 1, &jsStringLength);
255 if (jsStringLength != bufferSize) {
256 WVLOG_E("The length values obtained twice are different");
257 delete [] stringValue;
258 stringValue = nullptr;
259 return false;
260 }
261 std::string message(stringValue);
262 outValue = message;
263 delete [] stringValue;
264 stringValue = nullptr;
265 return true;
266 }
267
ParseBoolean(napi_env env,napi_value argv,bool & outValue)268 bool NapiParseUtils::ParseBoolean(napi_env env, napi_value argv, bool& outValue)
269 {
270 napi_valuetype valueType = napi_null;
271
272 napi_typeof(env, argv, &valueType);
273 if (valueType != napi_boolean) {
274 return false;
275 }
276
277 bool boolValue;
278 napi_get_value_bool(env, argv, &boolValue);
279 outValue = boolValue;
280 return true;
281 }
282
ParseStringArray(napi_env env,napi_value argv,std::vector<std::string> & outValue)283 bool NapiParseUtils::ParseStringArray(napi_env env, napi_value argv, std::vector<std::string>& outValue)
284 {
285 bool isArray = false;
286 napi_is_array(env, argv, &isArray);
287 if (!isArray) {
288 return false;
289 }
290
291 uint32_t arrLen = 0;
292 napi_get_array_length(env, argv, &arrLen);
293 for (uint32_t i = 0; i < arrLen; ++i) {
294 napi_value item = nullptr;
295 napi_get_element(env, argv, i, &item);
296
297 std::string str;
298 if (ParseString(env, item, str)) {
299 outValue.push_back(str);
300 }
301 }
302
303 return true;
304 }
305
ParseInt64Array(napi_env env,napi_value argv,std::vector<int64_t> & outValue)306 bool NapiParseUtils::ParseInt64Array(napi_env env, napi_value argv, std::vector<int64_t>& outValue)
307 {
308 bool isArray = false;
309 napi_is_array(env, argv, &isArray);
310 if (!isArray) {
311 return false;
312 }
313
314 uint32_t arrLen = 0;
315 napi_get_array_length(env, argv, &arrLen);
316 for (uint32_t i = 0; i < arrLen; ++i) {
317 napi_value item = nullptr;
318 napi_get_element(env, argv, i, &item);
319
320 int64_t value;
321 if (ParseInt64(env, item, value)) {
322 outValue.push_back(value);
323 }
324 }
325
326 return true;
327 }
328
ParseBooleanArray(napi_env env,napi_value argv,std::vector<bool> & outValue)329 bool NapiParseUtils::ParseBooleanArray(napi_env env, napi_value argv, std::vector<bool>& outValue)
330 {
331 bool isArray = false;
332 napi_is_array(env, argv, &isArray);
333 if (!isArray) {
334 return false;
335 }
336
337 uint32_t arrLen = 0;
338 napi_get_array_length(env, argv, &arrLen);
339 for (uint32_t i = 0; i < arrLen; ++i) {
340 napi_value item = nullptr;
341 napi_get_element(env, argv, i, &item);
342
343 bool value;
344 if (ParseBoolean(env, item, value)) {
345 outValue.push_back(value);
346 }
347 }
348
349 return true;
350 }
351
ParseDoubleArray(napi_env env,napi_value argv,std::vector<double> & outValue)352 bool NapiParseUtils::ParseDoubleArray(napi_env env, napi_value argv, std::vector<double>& outValue)
353 {
354 bool isArray = false;
355 napi_is_array(env, argv, &isArray);
356 if (!isArray) {
357 return false;
358 }
359
360 uint32_t arrLen = 0;
361 napi_get_array_length(env, argv, &arrLen);
362 for (uint32_t i = 0; i < arrLen; ++i) {
363 napi_value item = nullptr;
364 napi_get_element(env, argv, i, &item);
365
366 double value;
367 if (ParseDouble(env, item, value)) {
368 outValue.push_back(value);
369 }
370 }
371
372 return true;
373 }
374
ParseFloat(napi_env env,napi_value argv,float & outValue)375 bool NapiParseUtils::ParseFloat(napi_env env, napi_value argv, float& outValue)
376 {
377 napi_valuetype valueType = napi_undefined;
378 napi_typeof(env, argv, &valueType);
379 if (valueType != napi_number) {
380 return false;
381 }
382
383 double value;
384 napi_get_value_double(env, argv, &value);
385 outValue = static_cast<float>(value);
386 return true;
387 }
388
ParseDouble(napi_env env,napi_value argv,double & outValue)389 bool NapiParseUtils::ParseDouble(napi_env env, napi_value argv, double& outValue)
390 {
391 napi_valuetype valueType = napi_undefined;
392 napi_typeof(env, argv, &valueType);
393 if (valueType != napi_number) {
394 return false;
395 }
396
397 double value;
398 napi_get_value_double(env, argv, &value);
399 outValue = value;
400 return true;
401 }
402
403 //static
ConvertNWebToNapiValue(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)404 bool NapiParseUtils::ConvertNWebToNapiValue(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
405 {
406 NWebValue::Type type = src->GetType();
407 using ConvertNWebToNapiValueHandler = std::function<bool(napi_env, std::shared_ptr<NWebMessage>, napi_value&)>;
408 static const std::unordered_map<NWebValue::Type, ConvertNWebToNapiValueHandler> functionMap = {
409 { NWebValue::Type::STRING, ConvertToNapiHandlerOfString },
410 { NWebValue::Type::BINARY, ConvertToNapiHandlerOfBinary },
411 { NWebValue::Type::BOOLEAN, ConvertToNapiHandlerOfBoolean },
412 { NWebValue::Type::INTEGER, ConvertToNapiHandlerOfInteger },
413 { NWebValue::Type::DOUBLE, ConvertToNapiHandlerOfDouble },
414 { NWebValue::Type::ERROR, ConvertToNapiHandlerOfError },
415 { NWebValue::Type::STRINGARRAY, ConvertToNapiHandlerOfStringArray },
416 { NWebValue::Type::BOOLEANARRAY, ConvertToNapiHandlerOfBooleanArray },
417 { NWebValue::Type::DOUBLEARRAY, ConvertToNapiHandlerOfDoubleArray },
418 { NWebValue::Type::INT64ARRAY, ConvertToNapiHandlerOfInt64Array }
419 };
420 auto it = functionMap.find(type);
421 if (it == functionMap.end()) {
422 WVLOG_E("This type not support");
423 std::string msgStr = "This type not support";
424 napi_create_string_utf8(env, msgStr.c_str(), msgStr.length(), &dst);
425 return true;
426 }
427 return it->second(env, src, dst);
428 }
429 } // namespace NWeb
430 } // namespace OHOS
431