• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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_utils.h"
17 
18 #include <cstring>
19 #include <initializer_list>
20 #include <memory>
21 #include "log.h"
22 #include "securec.h"
23 #include "download_manager.h"
24 
25 namespace OHOS::Request::Download::NapiUtils {
26 static constexpr const int MAX_STRING_LENGTH = 65536;
27 
GetValueType(napi_env env,napi_value value)28 napi_valuetype GetValueType(napi_env env, napi_value value)
29 {
30     if (value == nullptr) {
31         return napi_undefined;
32     }
33 
34     napi_valuetype valueType = napi_undefined;
35     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
36     return valueType;
37 }
38 
39 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)40 bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
41 {
42     bool hasProperty = false;
43     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
44     return hasProperty;
45 }
46 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)47 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
48 {
49     napi_value value = nullptr;
50     bool hasProperty = false;
51     NAPI_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
52     if (!hasProperty) {
53         return value;
54     }
55     NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
56     return value;
57 }
58 
GetPropertyNames(napi_env env,napi_value object)59 std::vector<std::string> GetPropertyNames(napi_env env, napi_value object)
60 {
61     std::vector<std::string> ret;
62     napi_value names = nullptr;
63     NAPI_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
64     uint32_t length = 0;
65     NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
66     for (uint32_t index = 0; index < length; ++index) {
67         napi_value name = nullptr;
68         if (napi_get_element(env, names, index, &name) != napi_ok) {
69             continue;
70         }
71         if (GetValueType(env, name) != napi_string) {
72             continue;
73         }
74         ret.emplace_back(GetStringFromValueUtf8(env, name));
75     }
76     return ret;
77 }
78 
79 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)80 napi_value CreateUint32(napi_env env, uint32_t code)
81 {
82     napi_value value = nullptr;
83     if (napi_create_uint32(env, code, &value) != napi_ok) {
84         return nullptr;
85     }
86     return value;
87 }
88 
GetUint32FromValue(napi_env env,napi_value value)89 uint32_t GetUint32FromValue(napi_env env, napi_value value)
90 {
91     uint32_t ret = 0;
92     NAPI_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
93     return ret;
94 }
95 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)96 uint32_t GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
97 {
98     if (!HasNamedProperty(env, object, propertyName)) {
99         return 0;
100     }
101     napi_value value = GetNamedProperty(env, object, propertyName);
102     return GetUint32FromValue(env, value);
103 }
104 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)105 void SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
106 {
107     napi_value jsValue = CreateUint32(env, value);
108     if (GetValueType(env, jsValue) != napi_number) {
109         return;
110     }
111 
112     napi_set_named_property(env, object, name.c_str(), jsValue);
113 }
114 
115 /* INT32 */
CreateInt32(napi_env env,int32_t code)116 napi_value CreateInt32(napi_env env, int32_t code)
117 {
118     napi_value value = nullptr;
119     if (napi_create_int32(env, code, &value) != napi_ok) {
120         return nullptr;
121     }
122     return value;
123 }
124 
GetInt32FromValue(napi_env env,napi_value value)125 int32_t GetInt32FromValue(napi_env env, napi_value value)
126 {
127     int32_t ret = 0;
128     NAPI_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
129     return ret;
130 }
131 
132 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)133 napi_value CreateStringUtf8(napi_env env, const std::string &str)
134 {
135     napi_value value = nullptr;
136     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
137         return nullptr;
138     }
139     return value;
140 }
141 
GetStringFromValueUtf8(napi_env env,napi_value value)142 std::string GetStringFromValueUtf8(napi_env env, napi_value value)
143 {
144     std::string result;
145     std::vector<char> str(MAX_STRING_LENGTH + 1, '\0');
146     size_t length = 0;
147     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result);
148     if (length > 0) {
149         return result.append(&str[0], length);
150     }
151     return result;
152 }
153 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)154 std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
155 {
156     if (!HasNamedProperty(env, object, propertyName)) {
157         return "";
158     }
159     napi_value value = GetNamedProperty(env, object, propertyName);
160     return GetStringFromValueUtf8(env, value);
161 }
162 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)163 void SetStringPropertyUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
164 {
165     napi_value jsValue = CreateStringUtf8(env, value);
166     if (GetValueType(env, jsValue) != napi_string) {
167         return;
168     }
169     napi_set_named_property(env, object, name.c_str(), jsValue);
170 }
171 
172 /* object */
CreateObject(napi_env env)173 napi_value CreateObject(napi_env env)
174 {
175     napi_value object = nullptr;
176     NAPI_CALL(env, napi_create_object(env, &object));
177     return object;
178 }
179 
180 /* undefined */
GetUndefined(napi_env env)181 napi_value GetUndefined(napi_env env)
182 {
183     napi_value undefined = nullptr;
184     NAPI_CALL(env, napi_get_undefined(env, &undefined));
185     return undefined;
186 }
187 
188 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)189 napi_value CallFunction(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
190 {
191     napi_value res = nullptr;
192     NAPI_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
193     return res;
194 }
195 
196 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)197 bool GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
198 {
199     if (!HasNamedProperty(env, object, propertyName)) {
200         return false;
201     }
202     napi_value value = GetNamedProperty(env, object, propertyName);
203     bool ret = false;
204     NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
205     return ret;
206 }
207 
ToLower(const std::string & s)208 std::string ToLower(const std::string &s)
209 {
210     std::string res = s;
211     std::transform(res.begin(), res.end(), res.begin(), tolower);
212     return res;
213 }
214 
GetParameterNumber(napi_env env,napi_callback_info info,napi_value * argv,napi_value * this_arg)215 int32_t GetParameterNumber(napi_env env, napi_callback_info info, napi_value *argv, napi_value *this_arg)
216 {
217     size_t argc = NapiUtils::MAX_ARGC;
218     void *data = nullptr;
219     napi_status status = napi_get_cb_info(env, info, &argc, argv, this_arg, &data);
220     if (status != napi_ok) {
221         return -1;
222     }
223     return static_cast<int32_t>(argc);
224 }
225 
ThrowError(napi_env env,const ExceptionErrorCode & code,const std::string & msg)226 void ThrowError(napi_env env, const ExceptionErrorCode &code, const std::string &msg)
227 {
228     napi_value error = CreateBusinessError(env, code, msg);
229     napi_throw(env, error);
230 }
231 
CreateBusinessError(napi_env env,const ExceptionErrorCode & errorCode,const std::string & errorMessage)232 napi_value CreateBusinessError(napi_env env, const ExceptionErrorCode &errorCode, const std::string &errorMessage)
233 {
234     napi_value error = nullptr;
235     napi_value code = nullptr;
236     napi_value msg = nullptr;
237     auto iter = ErrorCodeToMsg.find(errorCode);
238     std::string strMsg = (iter != ErrorCodeToMsg.end() ? iter->second : "") + "   "+ errorMessage;
239     NAPI_CALL(env, napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg));
240     NAPI_CALL(env, napi_create_uint32(env, errorCode, &code));
241     NAPI_CALL(env, napi_create_error(env, nullptr, msg, &error));
242     napi_set_named_property(env, error, "code", code);
243     return error;
244 }
245 
CheckParameterCorrect(napi_env env,napi_callback_info info,const std::string & type,ExceptionError & err)246 bool CheckParameterCorrect(napi_env env, napi_callback_info info, const std::string &type, ExceptionError &err)
247 {
248     if (!DownloadManager::GetInstance()->CheckPermission()) {
249         err.code = EXCEPTION_PERMISSION;
250         err.errInfo = "Permission denied.An attempt was made to forbidden by permission:INTERNET";
251         return false;
252     }
253     std::string errInfo;
254     napi_value argv[NapiUtils::MAX_ARGC] = {nullptr};
255     int32_t num = NapiUtils::GetParameterNumber(env, info, argv, nullptr);
256     if (num < 0) {
257         err.code = EXCEPTION_PARAMETER_CHECK;
258         err.errInfo = "function ${" + type + "} Wrong number of arguments";
259         return false;
260     }
261     if (num == NapiUtils::ONE_ARG) {
262         if (NapiUtils::GetValueType(env, argv[NapiUtils::FIRST_ARGV]) != napi_function) {
263             err.code = EXCEPTION_PARAMETER_CHECK;
264             err.errInfo = "function ${" + type + "} the first parameter must be function";
265             return false;
266         }
267     }
268     return true;
269 }
270 } // namespace OHOS::Request::Download::NapiUtils