• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2024 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 <cstdint>
19 #include <mutex>
20 #include <string>
21 
22 #include "base/request/request/common/include/constant.h"
23 #include "js_native_api.h"
24 #include "napi/native_common.h"
25 
26 namespace OHOS::Request {
CreateBusinessError(napi_env env,int32_t errorCode,const std::string & errorMessage)27 napi_value CreateBusinessError(napi_env env, int32_t errorCode, const std::string &errorMessage)
28 {
29     napi_value error = nullptr;
30     napi_value msg = nullptr;
31     NAPI_CALL(env, napi_create_string_utf8(env, errorMessage.c_str(), errorMessage.length(), &msg));
32     NAPI_CALL(env, napi_create_error(env, nullptr, msg, &error));
33     napi_value code = nullptr;
34     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(errorCode), &code));
35     napi_set_named_property(env, error, "code", code);
36     return error;
37 }
38 
ThrowError(napi_env env,int32_t code,const std::string & msg)39 void ThrowError(napi_env env, int32_t code, const std::string &msg)
40 {
41     napi_value error = CreateBusinessError(env, code, msg);
42     napi_throw(env, error);
43 }
44 
GetValueType(napi_env env,napi_value value)45 napi_valuetype GetValueType(napi_env env, napi_value value)
46 {
47     if (value == nullptr) {
48         return napi_undefined;
49     }
50     napi_valuetype valueType = napi_undefined;
51     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
52     return valueType;
53 }
54 
GetStringLength(napi_env env,napi_value value)55 size_t GetStringLength(napi_env env, napi_value value)
56 {
57     size_t length;
58     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, nullptr, 0, &length), 0);
59     return length;
60 }
61 
GetValueString(napi_env env,napi_value value,size_t length)62 std::string GetValueString(napi_env env, napi_value value, size_t length)
63 {
64     char chars[length + 1];
65     NAPI_CALL(env, napi_get_value_string_utf8(env, value, chars, sizeof(chars), &length));
66     return std::string(chars);
67 }
68 
GetValueNum(napi_env env,napi_value value)69 int64_t GetValueNum(napi_env env, napi_value value)
70 {
71     int64_t ret;
72     NAPI_CALL_BASE(env, napi_get_value_int64(env, value, &ret), 0);
73     return ret;
74 }
75 
GetPropertyNames(napi_env env,napi_value object)76 std::vector<std::string> GetPropertyNames(napi_env env, napi_value object)
77 {
78     std::vector<std::string> ret;
79     napi_value names = nullptr;
80     NAPI_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
81     uint32_t length = 0;
82     NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
83     for (uint32_t index = 0; index < length; ++index) {
84         napi_value name = nullptr;
85         if (napi_get_element(env, names, index, &name) != napi_ok) {
86             continue;
87         }
88         if (GetValueType(env, name) != napi_string) {
89             continue;
90         }
91         size_t propertyLength = GetStringLength(env, name);
92         ret.emplace_back(GetValueString(env, name, propertyLength));
93     }
94     return ret;
95 }
96 
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)97 bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
98 {
99     bool hasProperty = false;
100     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
101     return hasProperty;
102 }
103 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)104 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
105 {
106     napi_value value = nullptr;
107     bool hasProperty = false;
108     NAPI_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
109     if (!hasProperty) {
110         return value;
111     }
112     NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
113     return value;
114 }
115 
GetPropertyValue(napi_env env,napi_value object,const std::string & propertyName)116 std::string GetPropertyValue(napi_env env, napi_value object, const std::string &propertyName)
117 {
118     if (!HasNamedProperty(env, object, propertyName)) {
119         return "";
120     }
121     napi_value value = GetNamedProperty(env, object, propertyName);
122     if (GetValueType(env, value) != napi_string) {
123         return "";
124     }
125     auto length = GetStringLength(env, value);
126     return GetValueString(env, value, length);
127 }
128 
setPerformanceField(napi_env env,napi_value performance,double field_value,const char * js_name)129 inline napi_status setPerformanceField(napi_env env, napi_value performance, double field_value, const char *js_name)
130 {
131     napi_value value;
132     napi_status status = napi_create_double(env, field_value, &value);
133     if (status != napi_ok) {
134         return status;
135     }
136 
137     return napi_set_named_property(env, performance, js_name, value);
138 }
139 
buildInfoResource(napi_env env,const CppDownloadInfo & result,napi_value & jsInfo)140 bool buildInfoResource(napi_env env, const CppDownloadInfo &result, napi_value &jsInfo)
141 {
142     napi_status status;
143     napi_value resource;
144     status = napi_create_object(env, &resource);
145     if (status != napi_ok) {
146         return false;
147     }
148 
149     napi_value sizeValue;
150     status = napi_create_int64(env, result.resource_size(), &sizeValue);
151     if (status != napi_ok) {
152         return false;
153     }
154 
155     status = napi_set_named_property(env, resource, "size", sizeValue);
156     if (status != napi_ok) {
157         return false;
158     }
159 
160     status = napi_set_named_property(env, jsInfo, "resource", resource);
161     if (status != napi_ok) {
162         return false;
163     }
164 
165     return true;
166 }
167 
buildInfoNetwork(napi_env env,const CppDownloadInfo & result,napi_value & jsInfo)168 bool buildInfoNetwork(napi_env env, const CppDownloadInfo &result, napi_value &jsInfo)
169 {
170     napi_status status;
171     napi_value network;
172     status = napi_create_object(env, &network);
173     if (status != napi_ok) {
174         return false;
175     }
176 
177     napi_value ipValue;
178     status = napi_create_string_utf8(env, result.network_ip().c_str(), NAPI_AUTO_LENGTH, &ipValue);
179     if (status != napi_ok) {
180         return false;
181     }
182 
183     status = napi_set_named_property(env, network, "ip", ipValue);
184     if (status != napi_ok) {
185         return false;
186     }
187 
188     std::vector<std::string> dnsServers = result.dns_servers();
189 
190     napi_value dnsArray;
191     status = napi_create_array_with_length(env, dnsServers.size(), &dnsArray);
192     if (status != napi_ok) {
193         return false;
194     }
195     for (size_t i = 0; i < dnsServers.size(); i++) {
196         const std::string &server = dnsServers[i];
197         napi_value dnsItem;
198         status = napi_create_string_utf8(env, server.c_str(), NAPI_AUTO_LENGTH, &dnsItem);
199         if (status != napi_ok) {
200             return false;
201         }
202 
203         status = napi_set_element(env, dnsArray, i, dnsItem);
204         if (status != napi_ok) {
205             return false;
206         }
207     }
208     status = napi_set_named_property(env, network, "dnsServers", dnsArray);
209     if (status != napi_ok) {
210         return false;
211     }
212     status = napi_set_named_property(env, jsInfo, "network", network);
213     if (status != napi_ok) {
214         return false;
215     }
216     return true;
217 }
218 
buildInfoPerformance(napi_env env,const CppDownloadInfo & result,napi_value & jsInfo)219 bool buildInfoPerformance(napi_env env, const CppDownloadInfo &result, napi_value &jsInfo)
220 {
221     napi_status status;
222     napi_value performance;
223     status = napi_create_object(env, &performance);
224     if (status != napi_ok) {
225         return false;
226     }
227 
228     if ((status = setPerformanceField(env, performance, result.dns_time(), "dnsTime")) != napi_ok) {
229         return false;
230     }
231     if ((status = setPerformanceField(env, performance, result.connect_time(), "connectTime")) != napi_ok) {
232         return false;
233     }
234     if ((status = setPerformanceField(env, performance, result.tls_time(), "tlsTime")) != napi_ok) {
235         return false;
236     }
237     if ((status = setPerformanceField(env, performance, result.first_send_time(), "firstSendTime")) != napi_ok) {
238         return false;
239     }
240     if ((status = setPerformanceField(env, performance, result.first_recv_time(), "firstReceiveTime")) != napi_ok) {
241         return false;
242     }
243     if ((status = setPerformanceField(env, performance, result.total_time(), "totalTime")) != napi_ok) {
244         return false;
245     }
246     if ((status = setPerformanceField(env, performance, result.redirect_time(), "redirectTime")) != napi_ok) {
247         return false;
248     }
249 
250     status = napi_set_named_property(env, jsInfo, "performance", performance);
251     if (status != napi_ok) {
252         return false;
253     }
254 
255     return true;
256 }
257 
258 } // namespace OHOS::Request