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 "native_module_url.h"
17 
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20 #include "js_url.h"
21 #include "securec.h"
22 #include "tools/log.h"
23 
24 extern const char _binary_js_url_js_start[];
25 extern const char _binary_js_url_js_end[];
26 extern const char _binary_url_abc_start[];
27 extern const char _binary_url_abc_end[];
28 namespace OHOS::Url {
UrlStructor(napi_env &env, napi_callback_info &info, URL *&object)29     static void UrlStructor(napi_env &env, napi_callback_info &info, URL *&object)
30     {
31         napi_value thisVar = nullptr;
32         size_t argc = 2; // 2:The number of parameters is 2
33         napi_value argv[2] = { 0 }; // 2:The number of parameters is 2
34         void *data = nullptr;
35         napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data);
36         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
37         napi_valuetype valuetype1 = napi_null;
38         napi_valuetype valuetype2 = napi_null;
39         napi_typeof(env, argv[0], &valuetype1);
40         if (valuetype1 == napi_string) {
41             std::string temp = "";
42             std::string tempType = "";
43             size_t tempSize = 0;
44             size_t tempTypeSize = 0;
45             if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tempSize) != napi_ok) {
46                 HILOG_ERROR("can not get argv[0] size");
47                 return;
48             }
49             temp.reserve(tempSize);
50             temp.resize(tempSize);
51             if (napi_get_value_string_utf8(env, argv[0], temp.data(), tempSize + 1, &tempSize) != napi_ok) {
52                 HILOG_ERROR("can not get argv[0] value");
53                 return;
54             }
55             std::string input = temp;
56             napi_typeof(env, argv[1], &valuetype2);
57             if (valuetype2 == napi_string) {
58                 if (napi_get_value_string_utf8(env, argv[1], nullptr, 0, &tempTypeSize) != napi_ok) {
59                     HILOG_ERROR("can not get argv[1] size");
60                     return;
61                 }
62                 tempType.reserve(tempTypeSize);
63                 tempType.resize(tempTypeSize);
64                 if (napi_get_value_string_utf8(env, argv[1], tempType.data(),
65                                                tempTypeSize + 1, &tempTypeSize) != napi_ok) {
66                     HILOG_ERROR("can not get argv[1] value");
67                     return;
68                 }
69                 std::string base = tempType;
70                 object = new (std::nothrow) URL(input, base);
71                 if (object == nullptr) {
72                     HILOG_ERROR("UrlStructor:: object is nullptr");
73                     return;
74                 }
75             } else if (valuetype2 == napi_object) {
76                 URL *tempUrl = nullptr;
77                 napi_unwrap(env, argv[1], reinterpret_cast<void**>(&tempUrl));
78                 if (tempUrl == nullptr) {
79                     HILOG_ERROR("UrlStructor:: tempUrl is nullptr");
80                     return;
81                 }
82                 object = new (std::nothrow) URL(input, *tempUrl);
83                 if (object == nullptr) {
84                     HILOG_ERROR("UrlStructor:: object is nullptr");
85                     return;
86                 }
87             } else {
88                 HILOG_INFO("secondParameter error");
89             }
90         } else {
91             HILOG_INFO("firstParameter error");
92         }
93         return;
94     }
95 
UrlConstructor(napi_env env, napi_callback_info info)96     static napi_value UrlConstructor(napi_env env, napi_callback_info info)
97     {
98         napi_value thisVar = nullptr;
99         void *data = nullptr;
100         size_t argc = 0;
101         napi_value argv[2] = { 0 }; // 2:The number of parameters is 2
102         URL *object = nullptr;
103         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data));
104         if (argc == 1) {
105             NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
106             napi_valuetype valuetype = napi_null;
107             NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
108             if (valuetype == napi_string) {
109                 std::string type = "";
110                 size_t typeSize = 0;
111                 if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeSize) != napi_ok) {
112                     HILOG_ERROR("can not get argv[0] size");
113                     return nullptr;
114                 }
115                 type.reserve(typeSize);
116                 type.resize(typeSize);
117                 if (napi_get_value_string_utf8(env, argv[0], type.data(), typeSize + 1, &typeSize) != napi_ok) {
118                     HILOG_ERROR("can not get argv[0] value");
119                     return nullptr;
120                 }
121                 std::string input = type;
122                 object = new (std::nothrow) URL(input);
123                 if (object == nullptr) {
124                     HILOG_ERROR("UrlStructor:: object is nullptr");
125                     return nullptr;
126                 }
127             } else {
128                 HILOG_INFO("Parameter error");
129             }
130         } else if (argc == 2) { // 2:When the input parameter is set to 2
131             UrlStructor(env, info, object);
132         }
133         napi_wrap(
134             env, thisVar, object,
135             [](napi_env environment, void *data, void *hint) {
136                 auto obj = reinterpret_cast<URL*>(data);
137                 if (obj != nullptr) {
138                     delete obj;
139                 }
140             },
141             nullptr, nullptr);
142         return thisVar;
143     }
144 
GetHostname(napi_env env, napi_callback_info info)145     static napi_value GetHostname(napi_env env, napi_callback_info info)
146     {
147         napi_value thisVar = nullptr;
148         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
149         URL *murl = nullptr;
150         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
151         napi_value retVal = murl->GetHostname(env);
152         return retVal;
153     }
154 
GetSearch(napi_env env, napi_callback_info info)155     static napi_value GetSearch(napi_env env, napi_callback_info info)
156     {
157         napi_value thisVar = nullptr;
158         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
159         URL *murl = nullptr;
160         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
161         napi_value retVal = murl->GetSearch(env);
162         return retVal;
163     }
164 
GetUsername(napi_env env, napi_callback_info info)165     static napi_value GetUsername(napi_env env, napi_callback_info info)
166     {
167         napi_value thisVar = nullptr;
168         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
169         URL *murl = nullptr;
170         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
171         napi_value retVal = murl->GetUsername(env);
172         return retVal;
173     }
174 
GetPassword(napi_env env, napi_callback_info info)175     static napi_value GetPassword(napi_env env, napi_callback_info info)
176     {
177         napi_value thisVar = nullptr;
178         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
179         URL *murl = nullptr;
180         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
181         napi_value retVal = murl->GetPassword(env);
182         return retVal;
183     }
184 
GetUrlFragment(napi_env env, napi_callback_info info)185     static napi_value GetUrlFragment(napi_env env, napi_callback_info info)
186     {
187         napi_value thisVar = nullptr;
188         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
189         URL *murl = nullptr;
190         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
191         napi_value retVal = murl->GetFragment(env);
192         return retVal;
193     }
194 
GetUrlScheme(napi_env env, napi_callback_info info)195     static napi_value GetUrlScheme(napi_env env, napi_callback_info info)
196     {
197         napi_value thisVar = nullptr;
198         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
199         URL *murl = nullptr;
200         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
201         napi_value retVal = murl->GetScheme(env);
202         return retVal;
203     }
204 
GetUrlPort(napi_env env, napi_callback_info info)205     static napi_value GetUrlPort(napi_env env, napi_callback_info info)
206     {
207         napi_value thisVar = nullptr;
208         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
209         URL *murl = nullptr;
210         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
211         napi_value retVal = murl->GetPort(env);
212         return retVal;
213     }
214 
GetUrlHost(napi_env env, napi_callback_info info)215     static napi_value GetUrlHost(napi_env env, napi_callback_info info)
216     {
217         napi_value thisVar = nullptr;
218         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
219         URL *murl = nullptr;
220         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
221         napi_value retVal = murl->GetHost(env);
222         return retVal;
223     }
224 
GetUrlPath(napi_env env, napi_callback_info info)225     static napi_value GetUrlPath(napi_env env, napi_callback_info info)
226     {
227         napi_value thisVar = nullptr;
228         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
229         URL *murl = nullptr;
230         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
231         napi_value retVal = murl->GetPath(env);
232         return retVal;
233     }
234 
GetOnOrOff(napi_env env, napi_callback_info info)235     static napi_value GetOnOrOff(napi_env env, napi_callback_info info)
236     {
237         napi_value thisVar = nullptr;
238         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
239         URL *murl = nullptr;
240         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
241         napi_value retVal = murl->GetOnOrOff(env);
242         return retVal;
243     }
244 
GetIsIpv6(napi_env env, napi_callback_info info)245     static napi_value GetIsIpv6(napi_env env, napi_callback_info info)
246     {
247         napi_value thisVar = nullptr;
248         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
249         URL *murl = nullptr;
250         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
251         napi_value retVal = murl->GetIsIpv6(env);
252         return retVal;
253     }
254 
SetHref(napi_env env, napi_callback_info info)255     static napi_value SetHref(napi_env env, napi_callback_info info)
256     {
257         napi_value thisVar = nullptr;
258         napi_value argv[1] = {0};
259         size_t argc = 1;
260         std::string input = "";
261         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
262         size_t typelen = 0;
263         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
264             HILOG_ERROR("can not get argv[0] size");
265             return nullptr;
266         }
267         input.resize(typelen);
268         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
269             HILOG_ERROR("can not get argv[0] value");
270             return nullptr;
271         }
272         URL *murl = nullptr;
273         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
274         murl->SetHref(input);
275         napi_value result = nullptr;
276         NAPI_CALL(env, napi_get_undefined(env, &result));
277         return result;
278     }
279 
SetHostname(napi_env env, napi_callback_info info)280     static napi_value SetHostname(napi_env env, napi_callback_info info)
281     {
282         napi_value thisVar = nullptr;
283         napi_value argv[1] = {0};
284         size_t argc = 1;
285         std::string input = "";
286         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
287         size_t typelen = 0;
288         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
289             HILOG_ERROR("can not get argv[0] size");
290             return nullptr;
291         }
292         input.resize(typelen);
293         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
294             HILOG_ERROR("can not get argv[0] value");
295             return nullptr;
296         }
297         URL *murl = nullptr;
298         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
299         murl->SetHostname(input);
300         napi_value result = nullptr;
301         NAPI_CALL(env, napi_get_undefined(env, &result));
302         return result;
303     }
304 
SetUrlPort(napi_env env, napi_callback_info info)305     static napi_value SetUrlPort(napi_env env, napi_callback_info info)
306     {
307         napi_value thisVar = nullptr;
308         napi_value argv[1] = {0};
309         size_t argc = 1;
310         std::string input = "";
311         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
312         size_t typelen = 0;
313         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
314             HILOG_ERROR("can not get argv[0] size");
315             return nullptr;
316         }
317         input.resize(typelen);
318         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
319             HILOG_ERROR("can not get argv[0] value");
320             return nullptr;
321         }
322         URL *murl = nullptr;
323         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
324         murl->SetPort(input);
325         napi_value result = nullptr;
326         NAPI_CALL(env, napi_get_undefined(env, &result));
327         return result;
328     }
329 
SetUrlHost(napi_env env, napi_callback_info info)330     static napi_value SetUrlHost(napi_env env, napi_callback_info info)
331     {
332         napi_value thisVar = nullptr;
333         napi_value argv[1] = {0};
334         size_t argc = 1;
335         std::string input = "";
336         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
337         size_t typelen = 0;
338         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
339             HILOG_ERROR("can not get argv[0] size");
340             return nullptr;
341         }
342         input.resize(typelen);
343         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
344             HILOG_ERROR("can not get argv[0] value");
345             return nullptr;
346         }
347         URL *murl = nullptr;
348         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
349         murl->SetHost(input);
350         napi_value result = nullptr;
351         NAPI_CALL(env, napi_get_undefined(env, &result));
352         return result;
353     }
354 
SetSearch(napi_env env, napi_callback_info info)355     static napi_value SetSearch(napi_env env, napi_callback_info info)
356     {
357         napi_value thisVar = nullptr;
358         napi_value argv[1] = {0};
359         size_t argc = 1;
360         std::string input = "";
361         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
362         size_t typelen = 0;
363         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
364             HILOG_ERROR("can not get argv[0] size");
365             return nullptr;
366         }
367         input.resize(typelen);
368         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
369             HILOG_ERROR("can not get argv[0] value");
370             return nullptr;
371         }
372         URL *murl = nullptr;
373         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
374         murl->SetSearch(input);
375         napi_value result = nullptr;
376         NAPI_CALL(env, napi_get_undefined(env, &result));
377         return result;
378     }
379 
SetUrlScheme(napi_env env, napi_callback_info info)380     static napi_value SetUrlScheme(napi_env env, napi_callback_info info)
381     {
382         napi_value thisVar = nullptr;
383         napi_value argv[1] = {0};
384         size_t argc = 1;
385         std::string input = "";
386         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
387         size_t typelen = 0;
388         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
389             HILOG_ERROR("can not get argv[0] size");
390             return nullptr;
391         }
392         input.resize(typelen);
393         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
394             HILOG_ERROR("can not get argv[0] value");
395             return nullptr;
396         }
397         URL *murl = nullptr;
398         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
399         murl->SetScheme(input);
400         napi_value result = nullptr;
401         NAPI_CALL(env, napi_get_undefined(env, &result));
402         return result;
403     }
404 
SetUrlFragment(napi_env env, napi_callback_info info)405     static napi_value SetUrlFragment(napi_env env, napi_callback_info info)
406     {
407         napi_value thisVar = nullptr;
408         napi_value argv[1] = {0};
409         size_t argc = 1;
410         std::string input = "";
411         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
412         size_t typelen = 0;
413         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
414             HILOG_ERROR("can not get argv[0] size");
415             return nullptr;
416         }
417         input.resize(typelen);
418         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
419             HILOG_ERROR("can not get argv[0] value");
420             return nullptr;
421         }
422         URL *murl = nullptr;
423         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
424         murl->SetFragment(input);
425         napi_value result = nullptr;
426         NAPI_CALL(env, napi_get_undefined(env, &result));
427         return result;
428     }
429 
SetUsername(napi_env env, napi_callback_info info)430     static napi_value SetUsername(napi_env env, napi_callback_info info)
431     {
432         napi_value thisVar = nullptr;
433         napi_value argv[1] = {0};
434         size_t argc = 1;
435         std::string input = "";
436         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
437         size_t typelen = 0;
438         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
439             HILOG_ERROR("can not get argv[0] size");
440             return nullptr;
441         }
442         input.resize(typelen);
443         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
444             HILOG_ERROR("can not get argv[0] value");
445             return nullptr;
446         }
447         URL *murl = nullptr;
448         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
449         murl->SetUsername(input);
450         napi_value result = nullptr;
451         NAPI_CALL(env, napi_get_undefined(env, &result));
452         return result;
453     }
454 
SetUrlPath(napi_env env, napi_callback_info info)455     static napi_value SetUrlPath(napi_env env, napi_callback_info info)
456     {
457         napi_value thisVar = nullptr;
458         napi_value argv[1] = {0};
459         size_t argc = 1;
460         std::string input = "";
461         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
462         size_t typelen = 0;
463         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
464             HILOG_ERROR("can not get argv[0] size");
465             return nullptr;
466         }
467         input.resize(typelen);
468         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
469             HILOG_ERROR("can not get argv[0] value");
470             return nullptr;
471         }
472         URL *murl = nullptr;
473         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
474         murl->SetPath(input);
475         napi_value result = nullptr;
476         NAPI_CALL(env, napi_get_undefined(env, &result));
477         return result;
478     }
479 
SetPassword(napi_env env, napi_callback_info info)480     static napi_value SetPassword(napi_env env, napi_callback_info info)
481     {
482         napi_value thisVar = nullptr;
483         napi_value argv[1] = {0};
484         size_t argc = 1;
485         std::string input = "";
486         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
487         size_t typelen = 0;
488         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
489             HILOG_ERROR("can not get argv[0] size");
490             return nullptr;
491         }
492         input.resize(typelen);
493         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
494             HILOG_ERROR("can not get argv[0] value");
495             return nullptr;
496         }
497         URL *murl = nullptr;
498         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
499         murl->SetPassword(input);
500         napi_value result = nullptr;
501         NAPI_CALL(env, napi_get_undefined(env, &result));
502         return result;
503     }
504 
SeachParamsConstructor(napi_env env, napi_callback_info info)505     static napi_value SeachParamsConstructor(napi_env env, napi_callback_info info)
506     {
507         napi_value thisVar = nullptr;
508         void *data = nullptr;
509         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data));
510         auto object = new (std::nothrow) URLSearchParams();
511         if (object == nullptr) {
512             HILOG_ERROR("SeachParamsConstructor:: object is nullptr");
513             return nullptr;
514         }
515         napi_wrap(
516             env, thisVar, object,
517             [](napi_env environment, void *data, void *hint) {
518                 auto obj = reinterpret_cast<URLSearchParams*>(data);
519                 if (obj != nullptr) {
520                     delete obj;
521                 }
522             },
523             nullptr, nullptr);
524         return thisVar;
525     }
526 
SetArray(napi_env env, napi_callback_info info)527     static napi_value SetArray(napi_env env, napi_callback_info info)
528     {
529         napi_value thisVar = nullptr;
530         napi_value argv[1] = {0};
531         size_t argc = 1;
532         uint32_t length = 0;
533         napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
534         napi_get_array_length(env, argv[0], &length);
535         std::vector<std::string> vec;
536         size_t arraySize = 0;
537         napi_value napiStr = nullptr;
538         for (size_t i = 0; i < length; i++) {
539             napi_get_element(env, argv[0], i, &napiStr);
540             if (napi_get_value_string_utf8(env, napiStr, nullptr, 0, &arraySize) != napi_ok) {
541                 HILOG_ERROR("can not get napiStr size");
542                 return nullptr;
543             }
544             if (arraySize > 0) {
545                 std::string cstr = "";
546                 cstr.resize(arraySize);
547                 if (napi_get_value_string_utf8(env, napiStr, cstr.data(), arraySize + 1, &arraySize) != napi_ok) {
548                     HILOG_ERROR("can not get name value");
549                     return nullptr;
550                 }
551                 vec.push_back(cstr);
552             } else {
553                 vec.push_back("");
554             }
555         }
556         URLSearchParams *murl = nullptr;
557         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
558         murl->SetArray(env, vec);
559         napi_value result = nullptr;
560         NAPI_CALL(env, napi_get_undefined(env, &result));
561         return result;
562     }
563 
GetArray(napi_env env, napi_callback_info info)564     static napi_value GetArray(napi_env env, napi_callback_info info)
565     {
566         napi_value thisVar = nullptr;
567         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
568         URLSearchParams *murl = nullptr;
569         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&murl)));
570         napi_value retVal = murl->GetArray(env);
571         return retVal;
572     }
573 
Get(napi_env env, napi_callback_info info)574     static napi_value Get(napi_env env, napi_callback_info info)
575     {
576         napi_value thisVar = nullptr;
577         size_t argc = 1;
578         napi_value args = nullptr;
579         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
580         if (argc != 1) {
581             HILOG_INFO("One arg needs to be specified");
582             return nullptr;
583         }
584         URLSearchParams *object = nullptr;
585         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
586         if (object == nullptr) {
587             return nullptr;
588         }
589         napi_value result = object->Get(env, args);
590         return result;
591     }
592 
GetAll(napi_env env, napi_callback_info info)593     static napi_value GetAll(napi_env env, napi_callback_info info)
594     {
595         napi_value thisVar = nullptr;
596         size_t argc = 1;
597         napi_value args = nullptr;
598         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
599         if (argc != 1) {
600             HILOG_INFO("One arg needs to be specified");
601             return nullptr;
602         }
603         URLSearchParams *object = nullptr;
604         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
605         if (object == nullptr) {
606             return nullptr;
607         }
608         napi_value result = object->GetAll(env, args);
609         return result;
610     }
611 
Append(napi_env env, napi_callback_info info)612     static napi_value Append(napi_env env, napi_callback_info info)
613     {
614         napi_value thisVar = nullptr;
615         size_t argc = 2; // 2:The number of parameters is 2
616         napi_value args[2] = { 0 }; // 2:The number of parameters is 2
617         void *data = nullptr;
618         napi_get_cb_info(env, info, &argc, args, &thisVar, &data);
619         if (argc != 2) { // 2:If the input parameter is not set to 2,
620             HILOG_INFO("Two args needs to be specified");
621             return nullptr;
622         }
623         URLSearchParams *object = nullptr;
624         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
625         if (object == nullptr) {
626             return nullptr;
627         }
628         object->Append(env, args[0], args[1]);
629         return nullptr;
630     }
631 
Delete(napi_env env, napi_callback_info info)632     static napi_value Delete(napi_env env, napi_callback_info info)
633     {
634         napi_value thisVar = nullptr;
635         size_t argc = 1;
636         napi_value args = nullptr;
637         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
638         if (argc != 1) {
639             HILOG_INFO("One arg needs to be specified");
640             return nullptr;
641         }
642         URLSearchParams *object = nullptr;
643         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
644         if (object == nullptr) {
645             return nullptr;
646         }
647         object->Delete(env, args);
648         return nullptr;
649     }
650 
Entries(napi_env env, napi_callback_info info)651     static napi_value Entries(napi_env env, napi_callback_info info)
652     {
653         napi_value thisVar = nullptr;
654         size_t argc = 0;
655         napi_value args = nullptr;
656         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
657         URLSearchParams *object = nullptr;
658         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
659         if (object == nullptr) {
660             return nullptr;
661         }
662         napi_value result = object->Entries(env);
663         return result;
664     }
665 
IsHas(napi_env env, napi_callback_info info)666     static napi_value IsHas(napi_env env, napi_callback_info info)
667     {
668         napi_value thisVar = nullptr;
669         size_t argc = 1;
670         napi_value args = nullptr;
671         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr));
672         URLSearchParams *object = nullptr;
673         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
674         napi_value result = object->IsHas(env, args);
675         return result;
676     }
677 
Set(napi_env env, napi_callback_info info)678     static napi_value Set(napi_env env, napi_callback_info info)
679     {
680         napi_value thisVar = nullptr;
681         size_t argc = 2; // 2:The number of parameters is 2
682         napi_value args[2] = { 0 }; // 2:The number of parameters is 2
683         napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
684         URLSearchParams *object = nullptr;
685         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
686         if (object == nullptr) {
687             return nullptr;
688         }
689         object->Set(env, args[0], args[1]);
690         return nullptr;
691     }
692 
Sort(napi_env env, napi_callback_info info)693     static napi_value Sort(napi_env env, napi_callback_info info)
694     {
695         napi_value thisVar = nullptr;
696         size_t argc = 0;
697         napi_value args = nullptr;
698         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
699         URLSearchParams *object = nullptr;
700         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
701         if (object == nullptr) {
702             return nullptr;
703         }
704         object->Sort();
705         return nullptr;
706     }
707 
IterByKeys(napi_env env, napi_callback_info info)708     static napi_value IterByKeys(napi_env env, napi_callback_info info)
709     {
710         napi_value thisVar = nullptr;
711         size_t argc = 0;
712         napi_value args = nullptr;
713         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
714         URLSearchParams *object = nullptr;
715         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
716         if (object == nullptr) {
717             return nullptr;
718         }
719         napi_value result = object->IterByKeys(env);
720         return result;
721     }
722 
IterByValues(napi_env env, napi_callback_info info)723     static napi_value IterByValues(napi_env env, napi_callback_info info)
724     {
725         napi_value thisVar = nullptr;
726         size_t argc = 0;
727         napi_value args = nullptr;
728         napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
729         URLSearchParams *object = nullptr;
730         napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object));
731         if (object == nullptr) {
732             return nullptr;
733         }
734         napi_value result = object->IterByValues(env);
735         return result;
736     }
737 
IsEqualSign(size_t &strLastPos, const size_t &iteaor, std::string &buf, std::string &stringParm, std::vector<std::string> &seachParasVec)738     static void IsEqualSign(size_t &strLastPos, const size_t &iteaor,
739         std::string &buf, std::string &stringParm, std::vector<std::string> &seachParasVec)
740     {
741         if (strLastPos < iteaor) {
742             buf += stringParm.substr(strLastPos, iteaor - strLastPos);
743         }
744         seachParasVec.push_back(buf);
745         buf = "";
746         strLastPos = iteaor + 1;
747         return;
748     }
749 
IsAddressSign(const size_t &strLastPos, const size_t &iteaor, std::string &buf, std::string &stringParm, std::vector<std::string> &seachParasVec)750     static void IsAddressSign(const size_t &strLastPos, const size_t &iteaor, std::string &buf,
751         std::string &stringParm, std::vector<std::string> &seachParasVec)
752     {
753         if (strLastPos < iteaor) {
754             buf += stringParm.substr(strLastPos, iteaor - strLastPos);
755         }
756         seachParasVec.push_back(buf);
757         return;
758     }
DealParmsString(const size_t &strLastPos, const size_t &iteaor, std::string &buf, std::string &stringParm, std::vector<std::string> &seachParasVec)759     static void DealParmsString(const size_t &strLastPos, const size_t &iteaor, std::string &buf,
760         std::string &stringParm, std::vector<std::string> &seachParasVec)
761     {
762         if (strLastPos < iteaor) {
763             buf += stringParm.substr(strLastPos, iteaor - strLastPos);
764         }
765         seachParasVec.push_back(buf);
766     }
IsEqualCode(size_t &strStartPos, const size_t &iteaor, size_t &strLastPos)767     static void IsEqualCode(size_t &strStartPos, const size_t &iteaor, size_t &strLastPos)
768     {
769         if (strStartPos == iteaor) {
770             strLastPos = iteaor + 1;
771             strStartPos = iteaor + 1;
772         }
773         return;
774     }
StringParsing(std::string stringParm)775     static std::vector<std::string> StringParsing(std::string stringParm)
776     {
777         std::vector<std::string> seachParasVec;
778         size_t strStartPos = 0;
779         size_t strLastPos = 0;
780         bool isHasSpace = false;
781         std::string buf = "";
782         size_t iteaor = 0;
783         for (iteaor = 0; iteaor < stringParm.length(); iteaor++) {
784             char code = stringParm[iteaor];
785             switch (code) {
786                 case '&':
787                     {
788                         IsEqualCode(strStartPos, iteaor, strLastPos);
789                         IsAddressSign(strLastPos, iteaor, buf, stringParm, seachParasVec);
790                         if (!isHasSpace) {
791                             seachParasVec.push_back("");
792                         }
793                         isHasSpace = false;
794                         buf = "";
795                         strLastPos = iteaor + 1;
796                         strStartPos = iteaor + 1;
797                         break;
798                     }
799                 case '=':
800                     {
801                         if (isHasSpace) {
802                             break;
803                         }
804                         IsEqualSign(strLastPos, iteaor, buf, stringParm, seachParasVec);
805                         isHasSpace = true;
806                         break;
807                     }
808                 default:break;
809             }
810         }
811         if (strStartPos == iteaor) {
812             return seachParasVec;
813         }
814         DealParmsString(strLastPos, iteaor, buf, stringParm, seachParasVec);
815         if (!isHasSpace) {
816             seachParasVec.push_back("");
817         }
818         return seachParasVec;
819     }
820 
StringParmas(napi_env env, napi_callback_info info)821     static napi_value StringParmas(napi_env env, napi_callback_info info)
822     {
823         napi_value thisVar = nullptr;
824         napi_value argv[1] = {0};
825         size_t argc = 1;
826         std::string input = "";
827         napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
828         size_t typelen = 0;
829         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen) != napi_ok) {
830             HILOG_ERROR("can not get argv[0] size");
831             return nullptr;
832         }
833         input.resize(typelen);
834         if (napi_get_value_string_utf8(env, argv[0], input.data(), typelen + 1, &typelen) != napi_ok) {
835             HILOG_ERROR("can not get argv[0] value");
836             return nullptr;
837         }
838         std::vector<std::string> seachParasmsString;
839         seachParasmsString = StringParsing(input);
840         napi_value arr = nullptr;
841         napi_create_array(env, &arr);
842         for (size_t i = 0; i < seachParasmsString.size(); i++) {
843             napi_value result = nullptr;
844             napi_create_string_utf8(env, seachParasmsString[i].c_str(), seachParasmsString[i].size(), &result);
845             napi_set_element(env, arr, i, result);
846         }
847         return arr;
848     }
849 
FixUSVstring(napi_env env, napi_callback_info info)850     static napi_value FixUSVstring(napi_env env, napi_callback_info info)
851     {
852         napi_value thisVar = nullptr;
853         napi_value argv[1] = {0};
854         size_t argc = 1;
855         char16_t* inputStr = nullptr;
856         napi_value resultStr = nullptr;
857         size_t inputSize = 0;
858         napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
859         if (napi_get_value_string_utf16(env, argv[0], nullptr, 0, &inputSize) != napi_ok) {
860             HILOG_ERROR("url:: get args failed.");
861             return nullptr;
862         }
863         if (inputSize > 0) {
864             inputStr = new (std::nothrow) char16_t[inputSize + 1]();
865             if (inputStr == nullptr) {
866                 HILOG_ERROR("url:: inputStr is nullptr");
867                 return resultStr;
868             }
869             napi_get_value_string_utf16(env, argv[0], inputStr, inputSize + 1, &inputSize);
870         }
871         for (size_t i = 0; i < inputSize; i++) {
872             char16_t c = *(inputStr + i);
873             // 0xD800: minimum value of low proxy term. 0xF800: key bit mode for dividing high proxy and low proxy.
874             if (!((c & 0xF800) == 0xD800)) {
875                 continue;
876             } else if ((c & 0x400) != 0 || i == inputSize - 1) { // 0x400: Determine is component of low proxy.
877                 *(inputStr + i) = 0xFFFD; // 0xFFFD: Invalid character.
878             } else {
879                 char16_t d = *(inputStr + i + 1);
880                 // 0xDC00: minimum value of high proxy item. 0xFC00: Check if it meets the requirements of high proxy.
881                 if ((d & 0xFC00) == 0xDC00) {
882                     i++;
883                 } else {
884                     *(inputStr + i) = 0xFFFD; // 0xFFFD: Invalid character.
885                 }
886             }
887         }
888         napi_create_string_utf16(env, inputStr, inputSize, &resultStr);
889         if (inputStr != nullptr) {
890             delete[] inputStr;
891             inputStr = nullptr;
892         }
893         return resultStr;
894     }
895 
SeachParamsInit(napi_env env, napi_value exports)896     static napi_value SeachParamsInit(napi_env env, napi_value exports)
897     {
898         const char *seachParamsClassName = "URLSearchParams";
899         napi_value seachParamsInitClass = nullptr;
900         napi_property_descriptor UrlDesc[] = {
901             DECLARE_NAPI_FUNCTION("has", IsHas),
902             DECLARE_NAPI_FUNCTION("set", Set),
903             DECLARE_NAPI_FUNCTION("sort", Sort),
904             DECLARE_NAPI_FUNCTION("keys", IterByKeys),
905             DECLARE_NAPI_FUNCTION("values", IterByValues),
906             DECLARE_NAPI_FUNCTION("get", Get),
907             DECLARE_NAPI_FUNCTION("getAll", GetAll),
908             DECLARE_NAPI_FUNCTION("append", Append),
909             DECLARE_NAPI_FUNCTION("delete", Delete),
910             DECLARE_NAPI_FUNCTION("entries", Entries),
911             DECLARE_NAPI_GETTER_SETTER("array", GetArray, SetArray),
912         };
913         NAPI_CALL(env, napi_define_class(env, seachParamsClassName, strlen(seachParamsClassName),
914             SeachParamsConstructor, nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]),
915             UrlDesc, &seachParamsInitClass));
916         napi_property_descriptor desc[] = {
917             DECLARE_NAPI_PROPERTY("URLSearchParams1", seachParamsInitClass)
918         };
919         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
920         return exports;
921     };
922 
ParamsInit(napi_env env, napi_value exports)923     static napi_value ParamsInit(napi_env env, napi_value exports)
924     {
925         const char *paramsClassName = "URLSearchParams";
926         napi_value ParamsInitClass = nullptr;
927         napi_property_descriptor UrlDesc[] = {
928             DECLARE_NAPI_FUNCTION("has", IsHas),
929             DECLARE_NAPI_FUNCTION("set", Set),
930             DECLARE_NAPI_FUNCTION("sort", Sort),
931             DECLARE_NAPI_FUNCTION("keys", IterByKeys),
932             DECLARE_NAPI_FUNCTION("values", IterByValues),
933             DECLARE_NAPI_FUNCTION("get", Get),
934             DECLARE_NAPI_FUNCTION("getAll", GetAll),
935             DECLARE_NAPI_FUNCTION("append", Append),
936             DECLARE_NAPI_FUNCTION("delete", Delete),
937             DECLARE_NAPI_FUNCTION("entries", Entries),
938             DECLARE_NAPI_GETTER_SETTER("array", GetArray, SetArray),
939         };
940         NAPI_CALL(env, napi_define_class(env, paramsClassName, strlen(paramsClassName),
941             SeachParamsConstructor, nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]),
942             UrlDesc, &ParamsInitClass));
943         napi_property_descriptor desc[] = {
944             DECLARE_NAPI_PROPERTY("URLParams1", ParamsInitClass)
945         };
946         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
947         return exports;
948     };
949 
UrlInit(napi_env env, napi_value exports)950     static napi_value UrlInit(napi_env env, napi_value exports)
951     {
952         const char *urlClassName = "Url";
953         napi_value urlClass = nullptr;
954         napi_property_descriptor UrlDesc[] = {
955             DECLARE_NAPI_GETTER_SETTER("hostname", GetHostname, SetHostname),
956             DECLARE_NAPI_FUNCTION("href", SetHref),
957             DECLARE_NAPI_GETTER_SETTER("search", GetSearch, SetSearch),
958             DECLARE_NAPI_GETTER_SETTER("username", GetUsername, SetUsername),
959             DECLARE_NAPI_GETTER_SETTER("password", GetPassword, SetPassword),
960             DECLARE_NAPI_GETTER_SETTER("host", GetUrlHost, SetUrlHost),
961             DECLARE_NAPI_GETTER_SETTER("hash", GetUrlFragment, SetUrlFragment),
962             DECLARE_NAPI_GETTER_SETTER("protocol", GetUrlScheme, SetUrlScheme),
963             DECLARE_NAPI_GETTER_SETTER("pathname", GetUrlPath, SetUrlPath),
964             DECLARE_NAPI_GETTER_SETTER("port", GetUrlPort, SetUrlPort),
965             DECLARE_NAPI_GETTER("onOrOff", GetOnOrOff),
966             DECLARE_NAPI_GETTER("GetIsIpv6", GetIsIpv6),
967         };
968         NAPI_CALL(env, napi_define_class(env, urlClassName, strlen(urlClassName), UrlConstructor,
969                                          nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]), UrlDesc, &urlClass));
970         napi_property_descriptor desc[] = {
971             DECLARE_NAPI_PROPERTY("Url", urlClass)
972         };
973         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
974         return exports;
975     }
976 
Init(napi_env env, napi_value exports)977     napi_value Init(napi_env env, napi_value exports)
978     {
979         napi_property_descriptor desc[] = {
980             DECLARE_NAPI_FUNCTION("stringParmas", StringParmas),
981             DECLARE_NAPI_FUNCTION("fixUSVstring", FixUSVstring),
982         };
983         NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
984         SeachParamsInit(env, exports);
985         ParamsInit(env, exports);
986         UrlInit(env, exports);
987         return exports;
988     }
989 
990     extern "C"
NAPI_url_GetJSCode(const char **buf, int *bufLen)991     __attribute__((visibility("default"))) void NAPI_url_GetJSCode(const char **buf, int *bufLen)
992     {
993         if (buf != nullptr) {
994             *buf = _binary_js_url_js_start;
995         }
996         if (bufLen != nullptr) {
997             *bufLen = _binary_js_url_js_end - _binary_js_url_js_start;
998         }
999     }
1000     extern "C"
NAPI_url_GetABCCode(const char** buf, int* buflen)1001     __attribute__((visibility("default"))) void NAPI_url_GetABCCode(const char** buf, int* buflen)
1002     {
1003         if (buf != nullptr) {
1004             *buf = _binary_url_abc_start;
1005         }
1006         if (buflen != nullptr) {
1007             *buflen = _binary_url_abc_end - _binary_url_abc_start;
1008         }
1009     }
1010 
1011     static napi_module_with_js UrlModule = {
1012         .nm_version = 1,
1013         .nm_flags = 0,
1014         .nm_filename = nullptr,
1015         .nm_register_func = Init,
1016         .nm_modname = "url",
1017         .nm_priv = reinterpret_cast<void*>(0),
1018         .nm_get_abc_code = NAPI_url_GetABCCode,
1019         .nm_get_js_code = NAPI_url_GetJSCode,
1020     };
UrlRegisterModule()1021     extern "C" __attribute__((constructor)) void UrlRegisterModule()
1022     {
1023         napi_module_with_js_register(&UrlModule);
1024     }
1025 } // namespace
1026