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
ParseInt64(napi_env env,napi_value argv,int64_t & outValue)185 bool NapiParseUtils::ParseInt64(napi_env env, napi_value argv, int64_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 int64_t number = 0;
195 napi_get_value_int64(env, argv, &number);
196 outValue = number;
197
198 return true;
199 }
200
ParseString(napi_env env,napi_value argv,std::string & outValue)201 bool NapiParseUtils::ParseString(napi_env env, napi_value argv, std::string& outValue)
202 {
203 size_t bufferSize = 0;
204 napi_valuetype valueType = napi_undefined;
205
206 napi_typeof(env, argv, &valueType);
207 if (valueType != napi_string) {
208 return false;
209 }
210 napi_get_value_string_utf8(env, argv, nullptr, 0, &bufferSize);
211 if (bufferSize + 1 > UINT_MAX) {
212 WVLOG_E("String length is too long");
213 return false;
214 }
215 char *stringValue = new (std::nothrow) char[bufferSize + 1];
216 if (stringValue == nullptr) {
217 WVLOG_E("new String failed");
218 return false;
219 }
220 size_t jsStringLength = 0;
221 napi_get_value_string_utf8(env, argv, stringValue, bufferSize + 1, &jsStringLength);
222 if (jsStringLength != bufferSize) {
223 delete [] stringValue;
224 stringValue = nullptr;
225 return false;
226 }
227 std::string message(stringValue);
228 outValue = message;
229 delete [] stringValue;
230 stringValue = nullptr;
231 return true;
232 }
233
ParseBoolean(napi_env env,napi_value argv,bool & outValue)234 bool NapiParseUtils::ParseBoolean(napi_env env, napi_value argv, bool& outValue)
235 {
236 napi_valuetype valueType = napi_null;
237
238 napi_typeof(env, argv, &valueType);
239 if (valueType != napi_boolean) {
240 return false;
241 }
242
243 bool boolValue;
244 napi_get_value_bool(env, argv, &boolValue);
245 outValue = boolValue;
246 return true;
247 }
248
ParseStringArray(napi_env env,napi_value argv,std::vector<std::string> & outValue)249 bool NapiParseUtils::ParseStringArray(napi_env env, napi_value argv, std::vector<std::string>& outValue)
250 {
251 bool isArray = false;
252 napi_is_array(env, argv, &isArray);
253 if (!isArray) {
254 return false;
255 }
256
257 uint32_t arrLen = 0;
258 napi_get_array_length(env, argv, &arrLen);
259 for (uint32_t i = 0; i < arrLen; ++i) {
260 napi_value item = nullptr;
261 napi_get_element(env, argv, i, &item);
262
263 std::string str;
264 if (ParseString(env, item, str)) {
265 outValue.push_back(str);
266 }
267 }
268
269 return true;
270 }
271
ParseInt64Array(napi_env env,napi_value argv,std::vector<int64_t> & outValue)272 bool NapiParseUtils::ParseInt64Array(napi_env env, napi_value argv, std::vector<int64_t>& outValue)
273 {
274 bool isArray = false;
275 napi_is_array(env, argv, &isArray);
276 if (!isArray) {
277 return false;
278 }
279
280 uint32_t arrLen = 0;
281 napi_get_array_length(env, argv, &arrLen);
282 for (uint32_t i = 0; i < arrLen; ++i) {
283 napi_value item = nullptr;
284 napi_get_element(env, argv, i, &item);
285
286 int64_t value;
287 if (ParseInt64(env, item, value)) {
288 outValue.push_back(value);
289 }
290 }
291
292 return true;
293 }
294
ParseBooleanArray(napi_env env,napi_value argv,std::vector<bool> & outValue)295 bool NapiParseUtils::ParseBooleanArray(napi_env env, napi_value argv, std::vector<bool>& outValue)
296 {
297 bool isArray = false;
298 napi_is_array(env, argv, &isArray);
299 if (!isArray) {
300 return false;
301 }
302
303 uint32_t arrLen = 0;
304 napi_get_array_length(env, argv, &arrLen);
305 for (uint32_t i = 0; i < arrLen; ++i) {
306 napi_value item = nullptr;
307 napi_get_element(env, argv, i, &item);
308
309 bool value;
310 if (ParseBoolean(env, item, value)) {
311 outValue.push_back(value);
312 }
313 }
314
315 return true;
316 }
317
ParseDoubleArray(napi_env env,napi_value argv,std::vector<double> & outValue)318 bool NapiParseUtils::ParseDoubleArray(napi_env env, napi_value argv, std::vector<double>& outValue)
319 {
320 bool isArray = false;
321 napi_is_array(env, argv, &isArray);
322 if (!isArray) {
323 return false;
324 }
325
326 uint32_t arrLen = 0;
327 napi_get_array_length(env, argv, &arrLen);
328 for (uint32_t i = 0; i < arrLen; ++i) {
329 napi_value item = nullptr;
330 napi_get_element(env, argv, i, &item);
331
332 double value;
333 if (ParseDouble(env, item, value)) {
334 outValue.push_back(value);
335 }
336 }
337
338 return true;
339 }
340
ParseFloat(napi_env env,napi_value argv,float & outValue)341 bool NapiParseUtils::ParseFloat(napi_env env, napi_value argv, float& outValue)
342 {
343 napi_valuetype valueType = napi_undefined;
344 napi_typeof(env, argv, &valueType);
345 if (valueType != napi_number) {
346 return false;
347 }
348
349 double value;
350 napi_get_value_double(env, argv, &value);
351 outValue = static_cast<float>(value);
352 return true;
353 }
354
ParseDouble(napi_env env,napi_value argv,double & outValue)355 bool NapiParseUtils::ParseDouble(napi_env env, napi_value argv, double& outValue)
356 {
357 napi_valuetype valueType = napi_undefined;
358 napi_typeof(env, argv, &valueType);
359 if (valueType != napi_number) {
360 return false;
361 }
362
363 double value;
364 napi_get_value_double(env, argv, &value);
365 outValue = value;
366 return true;
367 }
368
369 //static
ConvertNWebToNapiValue(napi_env env,std::shared_ptr<NWebMessage> src,napi_value & dst)370 bool NapiParseUtils::ConvertNWebToNapiValue(napi_env env, std::shared_ptr<NWebMessage> src, napi_value& dst)
371 {
372 NWebValue::Type type = src->GetType();
373 using ConvertNWebToNapiValueHandler = std::function<bool(napi_env, std::shared_ptr<NWebMessage>, napi_value&)>;
374 static const std::unordered_map<NWebValue::Type, ConvertNWebToNapiValueHandler> functionMap = {
375 { NWebValue::Type::STRING, ConvertToNapiHandlerOfString },
376 { NWebValue::Type::BINARY, ConvertToNapiHandlerOfBinary },
377 { NWebValue::Type::BOOLEAN, ConvertToNapiHandlerOfBoolean },
378 { NWebValue::Type::INTEGER, ConvertToNapiHandlerOfInteger },
379 { NWebValue::Type::DOUBLE, ConvertToNapiHandlerOfDouble },
380 { NWebValue::Type::ERROR, ConvertToNapiHandlerOfError },
381 { NWebValue::Type::STRINGARRAY, ConvertToNapiHandlerOfStringArray },
382 { NWebValue::Type::BOOLEANARRAY, ConvertToNapiHandlerOfBooleanArray },
383 { NWebValue::Type::DOUBLEARRAY, ConvertToNapiHandlerOfDoubleArray },
384 { NWebValue::Type::INT64ARRAY, ConvertToNapiHandlerOfInt64Array }
385 };
386 auto it = functionMap.find(type);
387 if (it == functionMap.end()) {
388 WVLOG_E("This type not support");
389 std::string msgStr = "This type not support";
390 napi_create_string_utf8(env, msgStr.c_str(), msgStr.length(), &dst);
391 return true;
392 }
393 return it->second(env, src, dst);
394 }
395 } // namespace NWeb
396 } // namespace OHOS
397