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 #ifndef URL_JS_URL_H
17 #define URL_JS_URL_H
18 
19 #include <algorithm>
20 #include <bitset>
21 #include <cmath>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <map>
25 #include <string>
26 #include <vector>
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 namespace OHOS::Url {
30     enum class BitsetStatusFlag {
31         BIT0 = 0, // 0:Bit 0 Set to true,The URL analysis failed
32         BIT1 = 1, // 1:Bit 1 Set to true,The protocol is the default protocol
33         BIT2 = 2, // 2:Bit 2 Set to true,The URL has username
34         BIT3 = 3, // 3:Bit 3 Set to true,The URL has password
35         BIT4 = 4, // 4:Bit 4 Set to true,The URL has hostname
36         BIT5 = 5, // 5:Bit 5 Set to true,The URL Port is the specially
37         BIT6 = 6, // 6:Bit 6 Set to true,The URL has pathname
38         BIT7 = 7, // 7:Bit 7 Set to true,The URL has query
39         BIT8 = 8, // 8:Bit 8 Set to true,The URL has fragment
40         BIT9 = 9, // 9:Bit 9 Set to true,The URL Can not be base
41         BIT10 = 10, // 10:Bit 10 Set to true,The host is IPV6
42         BIT_STATUS_11 = 11, // 11:Each bit of a BIT represents a different parsing state.
43         BIT_ASCII_32 = 32, // 32:32-bit previously invalid control characters in ascii
44         BIT_ASCII_127 = 127, // 127:127 bits in ascii are DEL characters
45         MAX_BIT_SIZE = 128 // 128:ascii max range
46     };
47 
48     struct UrlData {
49         int port = -1;
50         bool isSpecialPath = false;
51         std::vector<std::string> path;
52         std::string password = "";
53         std::string scheme = "";
54         std::string query = "";
55         std::string username = "";
56         std::string fragment = "";
57         std::string host = "";
58     };
59 
60     bool IsHexDigit(const char& ch);
61     std::string DecodeSpecialChars(std::string input);
62     void DeleteC0OrSpace(std::string& str);
63     void DeleteTabOrNewline(std::string& str1);
64     std::string DealIpv4(std::string str);
65     std::string SplitNum(std::string num, size_t& number);
66     void FormatIpv6(std::string& str);
67     bool ISFileNohost(const std::string& input);
68     bool AnalysisScheme(std::string& input, std::string& scheme,
69         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
70     void AnalysisUsernameAndPasswd(std::string& input, std::string& username, std::string& password,
71         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
72     void AnalysisPath(std::string& input, std::vector<std::string>& path,
73         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool isSpecial);
74     void AnalysisOpaqueHost(std::string input, std::string& host,
75         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
76     void AnalyseIPv4(const std::string& input, std::string& host,
77         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
78     void AnalysisHost(std::string& input, std::string& host,
79         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool special);
80     void AnalysisFilePath(std::string& input, UrlData& urlinfo,
81         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
82     void AnalysisFilescheme(const std::string& input, UrlData& urlinfo,
83         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
84     void AnalyInfoPath(std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> &flags,
85         UrlData& urlinfo, const std::string& input);
86     void AnalyHostPath(std::string &strHost, std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags,
87         UrlData& urlinfo);
88     void AnalyStrHost(std::string &strHost, UrlData& urlinfo,
89         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> &flags);
90     void AnalysisNoDefaultProtocol(std::string& input, UrlData& urlinfo,
91         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags);
92     void AnalysisOnlyHost(const std::string& input, UrlData& urlinfo,
93         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t pos);
94 
95     class URL {
96     public:
97         /**
98          * URI constructor, which is used to instantiate a URI object.
99          *
100          * @param input Constructs a URI by parsing a given string.
101          */
102         explicit URL(const std::string& input);
103 
104         /**
105          * URI constructor, which is used to instantiate a URI object.
106          *
107          * @param input Constructs a URI by parsing a given string.
108          * @param base The input parameter is a character string.
109          */
110         URL(const std::string& input, const std::string& base);
111 
112         /**
113          * URI constructor, which is used to instantiate a URI object.
114          *
115          * @param input Constructs a URI by parsing a given string.
116          * @param base The input parameter is the URL object.
117          */
118         URL(const std::string& input, const URL& base);
119 
120         /**
121          *
122          * @param env NAPI environment parameters.
123          * Gets the host name portion of the URL��not include the port.
124          */
125         napi_value GetHostname(napi_env env) const;
126 
127         /**
128          * Sets the host name portion of the URL��not include the port.
129          *
130          * @param input Constructs a URI by parsing a given string.
131          */
132         void SetHostname(const std::string& input);
133 
134         /**
135          * Sets the username name portion of the URL��not include the port.
136          *
137          * @param input Constructs a URI by parsing a given string.
138          */
139         void SetUsername(const std::string& input);
140 
141         /**
142          * Sets the password portion of the URL��not include the port.
143          *
144          * @param input Constructs a URI by parsing a given string.
145          */
146         void SetPassword(const std::string& input);
147 
148         /**
149          * Sets the scheme portion of the URL��not include the port.
150          *
151          * @param input Constructs a URI by parsing a given string.
152          */
153         void SetScheme(const std::string& input);
154 
155         /**
156          * Sets the fragment portion of the URL��not include the port.
157          *
158          * @param input Constructs a URI by parsing a given string.
159          */
160         void SetFragment(const std::string& input);
161 
162         /**
163          * Sets the search portion of the URL��not include the port.
164          *
165          * @param input Constructs a URI by parsing a given string.
166          */
167         void SetSearch(const std::string& input);
168 
169         /**
170          * Sets the host portion of the URL��not include the port.
171          *
172          * @param input Constructs a URI by parsing a given string.
173          */
174         void SetHost(const std::string& input);
175 
176         /**
177          * Sets the port portion of the URL��not include the port.
178          *
179          * @param input Constructs a URI by parsing a given string.
180          */
181         void SetPort(const std::string& input);
182 
183         /**
184          * Sets the href portion of the URL��not include the port.
185          *
186          * @param input Constructs a URI by parsing a given string.
187          */
188         void SetHref(const std::string& input);
189 
190         /**
191          * Sets the path portion of the URL��not include the port.
192          *
193          * @param input Constructs a URI by parsing a given string.
194          */
195         void SetPath(const std::string& input);
196 
197         /**
198          * Gets the search portion of the URL��not include the port.
199          *
200          * @param env NAPI environment parameters.
201          */
202         napi_value GetSearch(napi_env env) const;
203 
204         /**
205          * Gets the username portion of the URL��not include the port.
206          *
207          * @param env NAPI environment parameters.
208          */
209         napi_value GetUsername(napi_env env) const;
210 
211         /**
212          * Gets the password portion of the URL��not include the port.
213          *
214          * @param env NAPI environment parameters.
215          */
216         napi_value GetPassword(napi_env env) const;
217 
218         /**
219          * Gets the fragment portion of the URL��not include the port.
220          *
221          * @param env NAPI environment parameters.
222          */
223         napi_value GetFragment(napi_env env) const;
224 
225         /**
226          * Gets the scheme portion of the URL��not include the port.
227          *
228          * @param env NAPI environment parameters.
229          */
230         napi_value GetScheme(napi_env env) const;
231 
232         /**
233          * Gets the path portion of the URL��not include the port.
234          *
235          * @param env NAPI environment parameters.
236          */
237         napi_value GetPath(napi_env env) const;
238 
239         /**
240          * Gets the port portion of the URL��not include the port.
241          *
242          * @param env NAPI environment parameters.
243          */
244         napi_value GetPort(napi_env env) const;
245 
246         /**
247          * Judge whether it's on or off.
248          *
249          * @param env NAPI environment parameters.
250          */
251         napi_value GetOnOrOff(napi_env env) const;
252 
253         /**
254          * Judge whether it's Ipv6.
255          *
256          * @param env NAPI environment parameters.
257          */
258         napi_value GetIsIpv6(napi_env env) const;
259 
260         /**
261          * Gets the host name portion of the URL��not include the port.
262          *
263          * @param env NAPI environment parameters.
264          */
265         napi_value GetHost(napi_env env) const;
266 
267         /**
268          * The destructor of the url
269          */
~URL()270         virtual ~URL() {}
271 
272     private:
273         UrlData urlData_;
274         std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> flags_;
275         // bitset<11>:Similar to bool array, each bit status represents the real-time status of current URL parsing
276     };
277 
278     class URLSearchParams {
279     public:
280         /**
281          * A parameterized constructor used to create an URLSearchParams instance.
282          */
URLSearchParams()283         explicit URLSearchParams() {}
284 
285         /**
286          * Virtual destructor of URLSearchParams
287          */
~URLSearchParams()288         virtual ~URLSearchParams() {}
289 
290         /**
291          * Returns a Boolean that indicates whether a parameter with the specified name exists.
292          *
293          * @param env NAPI environment parameters.
294          * @param name Specifies the name of a key-value pair.
295          */
296         napi_value IsHas(napi_env env, napi_value  name) const;
297 
298         /**
299          * Returns the first value associated to the given search parameter.
300          *
301          * @param env NAPI environment parameters.
302          * @param buffer Returns the first value associated to the given search parameter.
303          */
304         napi_value Get(napi_env env, napi_value buffer);
305 
306         /**
307          * Returns all key-value pairs associated with a given search parameter as an array.
308          *
309          * @param env NAPI environment parameters.
310          * @param buffer Specifies the name of a key value.
311          */
312         napi_value GetAll(napi_env env, napi_value buffer);
313 
314         /**
315          * Appends a specified key/value pair as a new search parameter.
316          *
317          * @param env NAPI environment parameters.
318          * @param buffer Key name of the search parameter to be inserted.
319          * @param temp Values of search parameters to be inserted.
320          */
321         void Append(napi_env env, napi_value buffer, napi_value temp);
322 
323         /**
324          * Deletes the given search parameter and its associated value,from the list of all search parameters.
325          *
326          * @param env NAPI environment parameters.
327          * @param buffer Name of the key-value pair to be deleted.
328          */
329         void Delete(napi_env env, napi_value buffer);
330 
331         /**
332          * Returns an ES6 iterator. Each item of the iterator is a JavaScript Array.
333          *
334          * @param env NAPI environment parameters.
335          */
336         napi_value Entries(napi_env env) const;
337 
338         /**
339          * Sets the value associated with a given search parameter to the
340          * given value. If there were several matching values, this method
341          * deletes the others. If the search parameter doesn't exist, this
342          * method creates it.
343          *
344          * @param env NAPI environment parameters.
345          * @param name Key name of the parameter to be set.
346          * @param value Indicates the parameter value to be set.
347          */
348         void Set(napi_env env, napi_value name, napi_value value);
349 
350         /**
351          * Sort all key/value pairs contained in this object in place and return undefined.
352          */
353         void Sort();
354 
355         /**
356          * Returns an iterator allowing to go through all keys contained in this object.
357          *
358          * @param env NAPI environment parameters.
359          */
360         napi_value IterByKeys(napi_env env);
361 
362         /**
363          * Returns an iterator allowing to go through all values contained in this object.
364          *
365          * @param env NAPI environment parameters.
366          */
367         napi_value IterByValues(napi_env env);
368 
369         /**
370          * Sets the string array of searchParams.
371          *
372          * @param env NAPI environment parameters.
373          * @param input String array.
374          */
375         void SetArray(napi_env env, std::vector<std::string> input);
376 
377         /**
378          * Gets the string array of searchParams.
379          *
380          * @param env NAPI environment parameters.
381          */
382         napi_value GetArray(napi_env env) const;
383 
384         /**
385          * This function will decode the string and put the parsed key and value values into the
386          * vector container of urlsearchparams class according to the rules.
387          *
388          * @param env NAPI environment parameters.
389          * @param Stringpar The input parameter of urlsearchparams is string.
390          */
391         std::vector<std::string> StringParmas(napi_env env, std::string Stringpar);
392 
393     private:
394         std::string ToUSVString(std::string inputStr);
395         void HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it);
396         std::vector<std::string> searchParams {};
397     };
398 } // namespace OHOS::Url
399 #endif // URL_JS_URL_H
400