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