• 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 "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