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
24extern const char _binary_js_url_js_start[];
25extern const char _binary_js_url_js_end[];
26extern const char _binary_url_abc_start[];
27extern const char _binary_url_abc_end[];
28namespace OHOS::Url {
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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    }
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    }
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    }
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
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
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
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
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
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
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"
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"
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    };
1021    extern "C" __attribute__((constructor)) void UrlRegisterModule()
1022    {
1023        napi_module_with_js_register(&UrlModule);
1024    }
1025} // namespace
1026