• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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_util.h"
17 #include <codecvt>
18 #include <cstdio>
19 #include <climits>
20 #include <locale>
21 #include <string>
22 
23 #include "hilog_wrapper.h"
24 #include "securec.h"
25 #include "usb_common.h"
26 #include "usb_errors.h"
27 #include "usb_napi_errors.h"
28 namespace OHOS {
29 namespace USB {
30 const int32_t MAX_STR_LENGTH = 1024;
JsValueToString(const napi_env & env,const napi_value & value,const int32_t bufLen,std::string & target)31 void NapiUtil::JsValueToString(const napi_env &env, const napi_value &value, const int32_t bufLen, std::string &target)
32 {
33     if (bufLen <= 0 || bufLen > MAX_STR_LENGTH) {
34         USB_HILOGE(MODULE_JS_NAPI, "string too long malloc failed");
35         return;
36     }
37     // 1 represent '\0'
38     int32_t actBufLen = bufLen + 1;
39     std::unique_ptr<char[]> buf = std::make_unique<char[]>(actBufLen);
40 
41     errno_t ret = memset_s(buf.get(), actBufLen, 0, actBufLen);
42     RETURN_IF_WITH_LOG(ret != EOK, "JsValueToString memset_s failed.");
43 
44     size_t result = 0;
45     napi_get_value_string_utf8(env, value, buf.get(), actBufLen, &result);
46     target = buf.get();
47 }
48 
JsObjectToString(const napi_env & env,const napi_value & object,std::string fieldStr,const int32_t bufLen,std::string & fieldRef)49 void NapiUtil::JsObjectToString(
50     const napi_env &env, const napi_value &object, std::string fieldStr, const int32_t bufLen, std::string &fieldRef)
51 {
52     if (bufLen <= 0) {
53         USB_HILOGE(MODULE_JS_NAPI, "invalid bufLen=%{public}d", bufLen);
54         return;
55     }
56 
57     bool hasProperty = false;
58     napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
59     if (hasProperty) {
60         napi_value field;
61         napi_valuetype valueType;
62 
63         napi_get_named_property(env, object, fieldStr.c_str(), &field);
64         napi_typeof(env, field, &valueType);
65         USB_ASSERT_RETURN_VOID(
66             env, valueType == napi_string, OHEC_COMMON_PARAM_ERROR, "The type of " + fieldStr + " must be string.");
67         // 1 represent '\0'
68         int32_t actBufLen = bufLen + 1;
69         std::unique_ptr<char[]> buf = std::make_unique<char[]>(actBufLen);
70 
71         errno_t ret = memset_s(buf.get(), actBufLen, 0, actBufLen);
72         RETURN_IF_WITH_LOG(ret != EOK, "JsObjectToString memset_s failed.");
73 
74         size_t result = 0;
75         napi_get_value_string_utf8(env, field, buf.get(), actBufLen, &result);
76         fieldRef = buf.get();
77     } else {
78         USB_HILOGW(MODULE_JS_NAPI, "js to str no property: %{public}s", fieldStr.c_str());
79     }
80 }
81 
JsObjectGetProperty(const napi_env & env,const napi_value & object,std::string fieldStr,napi_value & value)82 bool NapiUtil::JsObjectGetProperty(
83     const napi_env &env, const napi_value &object, std::string fieldStr, napi_value &value)
84 {
85     bool hasProperty = false;
86     napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
87     if (hasProperty) {
88         napi_get_named_property(env, object, fieldStr.c_str(), &value);
89     } else {
90         USB_HILOGW(MODULE_JS_NAPI, "js object has no property: %{public}s", fieldStr.c_str());
91     }
92     return hasProperty;
93 }
94 
JsObjectToBool(const napi_env & env,const napi_value & object,std::string fieldStr,bool & fieldRef)95 void NapiUtil::JsObjectToBool(const napi_env &env, const napi_value &object, std::string fieldStr, bool &fieldRef)
96 {
97     bool hasProperty = false;
98     napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
99     if (hasProperty) {
100         napi_value field;
101         napi_valuetype valueType;
102 
103         napi_get_named_property(env, object, fieldStr.c_str(), &field);
104         napi_typeof(env, field, &valueType);
105         USB_ASSERT_RETURN_VOID(
106             env, valueType == napi_boolean, OHEC_COMMON_PARAM_ERROR, "The type of " + fieldStr + " must be boolean.");
107         napi_get_value_bool(env, field, &fieldRef);
108     } else {
109         USB_HILOGW(MODULE_JS_NAPI, "js to boolean no property: %{public}s", fieldStr.c_str());
110     }
111 }
112 
JsObjectToInt(const napi_env & env,const napi_value & object,std::string fieldStr,int32_t & fieldRef)113 void NapiUtil::JsObjectToInt(const napi_env &env, const napi_value &object, std::string fieldStr, int32_t &fieldRef)
114 {
115     bool hasProperty = false;
116     napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
117     if (hasProperty) {
118         napi_value field;
119         napi_valuetype valueType;
120 
121         napi_get_named_property(env, object, fieldStr.c_str(), &field);
122         napi_typeof(env, field, &valueType);
123         USB_ASSERT_RETURN_VOID(
124             env, valueType == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of " + fieldStr + " must be number.");
125         napi_get_value_int32(env, field, &fieldRef);
126     } else {
127         USB_HILOGW(MODULE_JS_NAPI, "js to int32_t no property: %{public}s", fieldStr.c_str());
128     }
129 }
130 
JsObjectToUint(const napi_env & env,const napi_value & object,const std::string & fieldStr,uint32_t & fieldRef)131 void NapiUtil::JsObjectToUint(
132     const napi_env &env, const napi_value &object, const std::string &fieldStr, uint32_t &fieldRef)
133 {
134     bool hasProperty = false;
135     napi_status status = napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
136     if (status != napi_ok || !hasProperty) {
137         USB_HILOGE(MODULE_JS_NAPI, "js to uint32_t no property: %{public}s", fieldStr.c_str());
138         return;
139     }
140 
141     napi_value field = nullptr;
142     napi_valuetype valueType;
143 
144     status = napi_get_named_property(env, object, fieldStr.c_str(), &field);
145     if (status != napi_ok) {
146         USB_HILOGE(MODULE_JS_NAPI, "get property failed: %{public}s", fieldStr.c_str());
147         return;
148     }
149 
150     status = napi_typeof(env, field, &valueType);
151     if (status != napi_ok) {
152         USB_HILOGE(MODULE_JS_NAPI, "type error failed: %{public}s", fieldStr.c_str());
153         return;
154     }
155 
156     USB_ASSERT_RETURN_VOID(
157         env, valueType == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of " + fieldStr + " must be number.");
158     status = napi_get_value_uint32(env, field, &fieldRef);
159     if (status != napi_ok) {
160         USB_HILOGE(MODULE_JS_NAPI, "get value failed: %{public}s", fieldStr.c_str());
161     }
162 }
163 
JsObjectToUint32(const napi_env & env,const napi_value & object,const std::string & fieldStr,uint32_t & fieldRef)164 bool NapiUtil::JsObjectToUint32(
165     const napi_env &env, const napi_value &object, const std::string &fieldStr, uint32_t &fieldRef)
166 {
167     bool hasProperty = false;
168     napi_status status = napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty);
169     if (status != napi_ok || !hasProperty) {
170         USB_HILOGE(MODULE_JS_NAPI, "js to uint32_t no property: %{public}s", fieldStr.c_str());
171         return false;
172     }
173 
174     napi_value field = nullptr;
175     napi_valuetype valueType;
176 
177     status = napi_get_named_property(env, object, fieldStr.c_str(), &field);
178     if (status != napi_ok) {
179         USB_HILOGE(MODULE_JS_NAPI, "get property failed: %{public}s", fieldStr.c_str());
180         return false;
181     }
182 
183     status = napi_typeof(env, field, &valueType);
184     if (status != napi_ok) {
185         USB_HILOGE(MODULE_JS_NAPI, "type error failed: %{public}s", fieldStr.c_str());
186         return false;
187     }
188 
189     USB_ASSERT_RETURN_FALSE(
190         env, valueType == napi_number, OHEC_COMMON_PARAM_ERROR, "The type of " + fieldStr + " must be number.");
191     status = napi_get_value_uint32(env, field, &fieldRef);
192     if (status != napi_ok) {
193         USB_HILOGE(MODULE_JS_NAPI, "get value failed: %{public}s", fieldStr.c_str());
194         return false;
195     }
196     return true;
197 }
198 
JsObjectToUint8(const napi_env & env,const napi_value & object,const std::string & fieldStr,uint8_t & fieldRef)199 bool NapiUtil::JsObjectToUint8(
200     const napi_env &env, const napi_value &object, const std::string &fieldStr, uint8_t &fieldRef)
201 {
202     uint32_t tmpValue = UINT_MAX;
203     JsObjectToUint(env, object, fieldStr, tmpValue);
204     if (tmpValue > SCHAR_MAX) {
205         USB_HILOGE(MODULE_JS_NAPI, "type error failed: uint32_t to uint8_t");
206         return false;
207     } else {
208         fieldRef = tmpValue;
209         return true;
210     }
211 }
212 
JsUint8ArrayParse(const napi_env & env,const napi_value & object,uint8_t ** uint8Buffer,size_t & bufferSize,size_t & offset)213 bool NapiUtil::JsUint8ArrayParse(
214     const napi_env &env, const napi_value &object, uint8_t **uint8Buffer, size_t &bufferSize, size_t &offset)
215 {
216     bool isTypedArray = false;
217     if (napi_is_typedarray(env, object, &isTypedArray) != napi_ok || !isTypedArray) {
218         USB_ASSERT_RETURN_FALSE(env, isTypedArray, OHEC_COMMON_PARAM_ERROR, "The type of buffer must be TypedArray.");
219         USB_HILOGW(MODULE_JS_NAPI, "invalid type");
220         return false;
221     }
222 
223     napi_typedarray_type type;
224     napi_value buffer;
225 
226     napi_status infoStatus = napi_get_typedarray_info(
227         env, object, &type, &bufferSize, reinterpret_cast<void **>(uint8Buffer), &buffer, &offset);
228     if (infoStatus != napi_ok) {
229         USB_HILOGW(MODULE_JS_NAPI, "get typedarray info failed, status: %{public}d", infoStatus);
230         return false;
231     }
232     USB_ASSERT_RETURN_FALSE(
233         env, type == napi_uint8_array, OHEC_COMMON_PARAM_ERROR, "The type of buffer must be Uint8Array.");
234     USB_ASSERT_RETURN_FALSE(
235         env, bufferSize != 0, OHEC_COMMON_PARAM_ERROR, "The size of buffer must be a positive number.");
236     return true;
237 }
238 
Uint8ArrayToJsValue(const napi_env & env,std::vector<uint8_t> & uint8Buffer,size_t bufferSize,napi_value & result)239 void NapiUtil::Uint8ArrayToJsValue(
240     const napi_env &env, std::vector<uint8_t> &uint8Buffer, size_t bufferSize, napi_value &result)
241 {
242     uint8_t *nativeArraybuffer = nullptr;
243     napi_value nativeValue = nullptr;
244     napi_create_arraybuffer(env, bufferSize, reinterpret_cast<void **>(&nativeArraybuffer), &nativeValue);
245 
246     errno_t ret = memcpy_s(nativeArraybuffer, bufferSize, uint8Buffer.data(), bufferSize);
247     if (ret != EOK) {
248         USB_HILOGE(MODULE_JS_NAPI, "memcpy_s failed");
249         return;
250     }
251 
252     napi_create_typedarray(env, napi_uint8_array, bufferSize, nativeValue, 0, &result);
253 }
254 
SetValueUtf8String(const napi_env & env,std::string fieldStr,std::string str,napi_value & result)255 void NapiUtil::SetValueUtf8String(const napi_env &env, std::string fieldStr, std::string str, napi_value &result)
256 {
257     napi_value value;
258     napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value);
259     napi_set_named_property(env, result, fieldStr.c_str(), value);
260 }
261 
SetValueInt32(const napi_env & env,std::string fieldStr,const int32_t intValue,napi_value & result)262 void NapiUtil::SetValueInt32(const napi_env &env, std::string fieldStr, const int32_t intValue, napi_value &result)
263 {
264     napi_value value;
265     napi_create_int32(env, intValue, &value);
266     napi_set_named_property(env, result, fieldStr.c_str(), value);
267 }
268 
SetValueUint32(const napi_env & env,const std::string & fieldStr,const uint32_t uintValue,napi_value & result)269 void NapiUtil::SetValueUint32(
270     const napi_env &env, const std::string &fieldStr, const uint32_t uintValue, napi_value &result)
271 {
272     napi_value value = nullptr;
273     napi_status status = napi_create_uint32(env, uintValue, &value);
274     if (status != napi_ok) {
275         USB_HILOGE(MODULE_JS_NAPI, "create uint32 failed:%{public}s", fieldStr.c_str());
276         return;
277     }
278 
279     status = napi_set_named_property(env, result, fieldStr.c_str(), value);
280     if (status != napi_ok) {
281         USB_HILOGE(MODULE_JS_NAPI, "set property failed:%{public}s", fieldStr.c_str());
282     }
283 }
284 
SetValueBool(const napi_env & env,std::string fieldStr,const bool boolValue,napi_value & result)285 void NapiUtil::SetValueBool(const napi_env &env, std::string fieldStr, const bool boolValue, napi_value &result)
286 {
287     napi_value value;
288     napi_get_boolean(env, boolValue, &value);
289     napi_set_named_property(env, result, fieldStr.c_str(), value);
290 }
291 
292 } // namespace USB
293 } // namespace OHOS
294