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