diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md index 6eccad8e6a7d63fa97b79f7fd7bc1377d74f0456..576e68b5ed58d0ea77c54592517c508b16b9fcce 100755 --- a/README.md +++ b/README.md @@ -1,88 +1,88 @@ -# js_api_module子系统/组件 +# js_api_module Subsystem/Component -- [简介](#简介) -- [目录](#目录) -- [说明](#说明) - - [接口说明](#接口说明) - - [使用说明](#使用说明) +- [Introduction](#Introduction) +- [Contents](#Contents) +- [Illustrate](#Illustrate) + - [Interface Description](#Interface Description) + - [Instructions for use](#Instructions for use) -- [相关仓](#相关仓) +- [Related warehouse](#Related warehouse) -## 简介 +## Introduction -URL接口用于解析,构造,规范化和编码 URLs。 URL的构造函数创建新的URL对象。 以便对URL的已解析组成部分或对URL进行更改。URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。 +The interface of URL is used to parse, construct, normalize, and encode URLs. The URL constructor creates a new URL object. In order to make changes to the resolved components of the URL or to the URL. The URLSearchParams interface defines some practical methods to process URL query strings. -## 目录 +## Contents ``` base/compileruntime/js_api_module/ -├── Class:URL # URL类 -│ ├── new URL(input[, base]) # 创建URL对象 -│ ├── hash # hash属性 -│ ├── host # host属性 -│ ├── hostname # hostname属性 -│ ├── href # href属性 -│ ├── origin # origin属性 -│ ├── password # password属性 -│ ├── pathname # pathname属性 -│ ├── port # port属性 -│ ├── protocol # protocol属性 -│ ├── search # search属性 -│ ├── searchParams # searchParams属性 -│ ├── username # username属性 -│ ├── toString() # toString方法 -│ └── toJSON() # toJSON方法 -└─── Class: URLSearchParams # URLSearchParams类 - ├── new URLSearchParams() # 创建URLSearchParams对象 - ├── new URLSearchParams(string) # 创建URLSearchParams对象 - ├── new URLSearchParams(obj) # 创建URLSearchParams对象 - ├── new URLSearchParams(iterable) # 创建URLSearchParams对象 - ├── append(name, value) # append方法 - ├── delete(name) # delete方法 - ├── entries() # entries方法 - ├── forEach(fn[, thisArg]) # forEach方法 - ├── get(name) # get方法 - ├── getAll(name) # getAll方法 - ├── has(name) # has方法 - ├── keys() # keys方法 - ├── set(name, value) # set方法 - ├── sort() # sort方法 - ├── toString() # toString方法 - ├── values() # values方法 - └── urlSearchParams[Symbol.iterator]() # 创建URLSearchParams对象 -``` - -## 说明 - -### 接口说明 - - -| 接口名 | 说明 | +├── Class:URL # URL class +│ ├── new URL(input[, base]) # Create URL object +│ ├── hash # hash attribute +│ ├── host # host attribute +│ ├── hostname # hostname attribute +│ ├── href # href attribute +│ ├── origin # origin attribute +│ ├── password # password attribute +│ ├── pathname # pathname attribute +│ ├── port # port attribute +│ ├── protocol # protocol attribute +│ ├── search # search attribute +│ ├── searchParams # searchParams attribute +│ ├── username # username attribute +│ ├── toString() # toString method +│ └── toJSON() # toJSON method +└─── Class: URLSearchParams # URLSearchParams class + ├── new URLSearchParams() # Create URLSearchParams object + ├── new URLSearchParams(string) # Create URLSearchParams object + ├── new URLSearchParams(obj) # Create URLSearchParams object + ├── new URLSearchParams(iterable) # Create URLSearchParams object + ├── append(name, value) # append method + ├── delete(name) # delete method + ├── entries() # entries method + ├── forEach(fn[, thisArg]) # forEach method + ├── get(name) # get method + ├── getAll(name) # getAll method + ├── has(name) # has method + ├── keys() # keys method + ├── set(name, value) # set method + ├── sort() # sort method + ├── toString() # toString method + ├── values() # values method + └── urlSearchParams[Symbol.iterator]() # Create URLSearchParams object +``` + +## Illustrate + +### Interface Description + + +| Interface name | Illustrate | | -------- | -------- | -| new URL(url: string,base?:string I URL) | 创建并返回一个URL对象,该URL对象引用使用绝对URL字符串,相对URL字符串和基本URL字符串指定的URL。 | -| tostring():string | 该字符串化方法返回一个包含完整 URL 的 USVString。它的作用等同于只读的 URL.href。 | -| toJSON():string | 该方法返回一个USVString,其中包含一个序列化的URL版本。 | -| new URLSearchParams() | URLSearchParams() 构造器无入参,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | -| new URLSearchParams(string) | URLSearchParams(string) 构造器的入参为string数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | -| new URLSearchParams(obj) | URLSearchParams(obj) 构造器的入参为obj数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | -| new URLSearchParams(iterable) | URLSearchParams(iterable) 构造器的入参为iterable数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | -| has(name: string): boolean | 检索searchParams对象中是否含有name。有则返回ture,否则返回false。 | -| set(name: string, value string): void | 检索searchParams对象中是否含有key为name的键值对。没有的话则添加该键值对,有的话则修改对象中第一个key所对应的value,并删除键为name的其余键值对。 | -| sort(): void | 根据键的Unicode代码点,对包含在此对象中的所有键/值对进行排序,并返回undefined。 | -| toString(): string | 根据searchParams对象,返回适用在URL中的查询字符串。 | -| keys(): iterableIterator | 返回一个iterator,遍历器允许遍历对象中包含的所有key值。 | -| values(): iterableIterator | 返回一个iterator,遍历器允许遍历对象中包含的所有value值。 | -| append(name: string, value: string): void | 在searchParams对象中插入name, value键值对。 | -| delete(name: string): void | 遍历searchParams对象,查找所有的name,删除对应的键值对。 | -| get(name: string): string | 检索searchParams对象中第一个name,返回name键对应的值。 | -| getAll(name: string): string[] | 检索searchParams对象中所有name,返回name键对应的所有值。 | -| entries(): iterableIterator<[string, string]> | 返回一个iterator,允许遍历searchParams对象中包含的所有键/值对。 | -| forEach(): void | 通过回调函数来遍历URLSearchParams实例对象上的键值对。 | -| urlSearchParams[Symbol.iterator] () | 返回查询字符串中每个名称-值对的ES6迭代器。迭代器的每个项都是一个JavaScript数组。 | - -### 使用说明 - -各接口使用方法如下: +| new URL(url: string,base?:string I URL) | Create and return a URL object that references the URL specified by the absolute URL string, the relative URL string, and the basic URL string. | +| tostring():string | The stringification method returns a USVString containing the complete URL. It is equivalent to the read-only URL.href. | +| toJSON():string | This method returns a USVString, which contains a serialized URL version. | +| new URLSearchParams() | The URLSearchParams() constructor has no parameters. This method creates and returns a new URLSearchParams object. The beginning'?' character will be ignored. | +| new URLSearchParams(string) | The input parameter of URLSearchParams(string) constructor is string data type. This method creates and returns a new URLSearchParams object. The beginning'?' character will be ignored. | +| new URLSearchParams(obj) | URLSearchParams(obj) The input parameter of the constructor is the obj data type. This method creates and returns a new URLSearchParams object. The beginning'?' character will be ignored. | +| new URLSearchParams(iterable) | URLSearchParams(iterable) The input parameter of the constructor is the iterable data type. This method creates and returns a new URLSearchParams object. The beginning'?' character will be ignored. | +| has(name: string): boolean | Retrieve whether the searchParams object contains name. If yes, it returns true, otherwise it returns false. | +| set(name: string, value string): void | Retrieve whether the searchParams object contains a key-value pair whose key is name. If not, add the key-value pair, if any, modify the value corresponding to the first key in the object, and delete the remaining key-value pairs whose key is name. | +| sort(): void | According to the Unicode code point of the key, sort all key/value pairs contained in this object and return undefined. | +| toString(): string | According to the searchParams object, the query string applicable in the URL is returned. | +| keys(): iterableIterator | Return an iterator, which allows iterating through all the key values contained in the object. | +| values(): iterableIterator | Returns an iterator, which allows iterating over all the value values contained in the object. | +| append(name: string, value: string): void | Insert the name, value key-value pair in the searchParams object. | +| delete(name: string): void | Traverse the searchParams object, find all the names, and delete the corresponding key-value pairs. | +| get(name: string): string | Retrieve the first name in the searchParams object and return the value corresponding to the name key. | +| getAll(name: string): string[] | Retrieve all names in the searchParams object and return all the values corresponding to the name key. | +| entries(): iterableIterator<[string, string]> | Returns an iterator that allows iterating through all key/value pairs contained in the searchParams object. | +| forEach(): void | Through the callback function to traverse the key-value pairs on the URLSearchParams instance object. | +| urlSearchParams[Symbol.iterator] () | Returns an ES6 iterator for each name-value pair in the query string. Each item of the iterator is a JavaScript array. | + +### Instructions for use + +The usage of each interface is as follows: 1、new URL(url: string,base?:string|URL) ``` @@ -207,7 +207,7 @@ for (const [name, value] of params) { // foo bar // xyz ba ``` -## 相关仓 -[js_api_module子系统](https://gitee.com/OHOS_STD/js_api_module) +## Related warehouse +[js_api_module Subsystem](https://gitee.com/OHOS_STD/js_api_module) [base/compileruntime/js_api_module/](base/compileruntime/js_api_module-readme.md) diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..6eccad8e6a7d63fa97b79f7fd7bc1377d74f0456 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,213 @@ +# js_api_module子系统/组件 + +- [简介](#简介) +- [目录](#目录) +- [说明](#说明) + - [接口说明](#接口说明) + - [使用说明](#使用说明) + +- [相关仓](#相关仓) + +## 简介 + +URL接口用于解析,构造,规范化和编码 URLs。 URL的构造函数创建新的URL对象。 以便对URL的已解析组成部分或对URL进行更改。URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。 + +## 目录 + +``` +base/compileruntime/js_api_module/ +├── Class:URL # URL类 +│ ├── new URL(input[, base]) # 创建URL对象 +│ ├── hash # hash属性 +│ ├── host # host属性 +│ ├── hostname # hostname属性 +│ ├── href # href属性 +│ ├── origin # origin属性 +│ ├── password # password属性 +│ ├── pathname # pathname属性 +│ ├── port # port属性 +│ ├── protocol # protocol属性 +│ ├── search # search属性 +│ ├── searchParams # searchParams属性 +│ ├── username # username属性 +│ ├── toString() # toString方法 +│ └── toJSON() # toJSON方法 +└─── Class: URLSearchParams # URLSearchParams类 + ├── new URLSearchParams() # 创建URLSearchParams对象 + ├── new URLSearchParams(string) # 创建URLSearchParams对象 + ├── new URLSearchParams(obj) # 创建URLSearchParams对象 + ├── new URLSearchParams(iterable) # 创建URLSearchParams对象 + ├── append(name, value) # append方法 + ├── delete(name) # delete方法 + ├── entries() # entries方法 + ├── forEach(fn[, thisArg]) # forEach方法 + ├── get(name) # get方法 + ├── getAll(name) # getAll方法 + ├── has(name) # has方法 + ├── keys() # keys方法 + ├── set(name, value) # set方法 + ├── sort() # sort方法 + ├── toString() # toString方法 + ├── values() # values方法 + └── urlSearchParams[Symbol.iterator]() # 创建URLSearchParams对象 +``` + +## 说明 + +### 接口说明 + + +| 接口名 | 说明 | +| -------- | -------- | +| new URL(url: string,base?:string I URL) | 创建并返回一个URL对象,该URL对象引用使用绝对URL字符串,相对URL字符串和基本URL字符串指定的URL。 | +| tostring():string | 该字符串化方法返回一个包含完整 URL 的 USVString。它的作用等同于只读的 URL.href。 | +| toJSON():string | 该方法返回一个USVString,其中包含一个序列化的URL版本。 | +| new URLSearchParams() | URLSearchParams() 构造器无入参,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | +| new URLSearchParams(string) | URLSearchParams(string) 构造器的入参为string数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | +| new URLSearchParams(obj) | URLSearchParams(obj) 构造器的入参为obj数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | +| new URLSearchParams(iterable) | URLSearchParams(iterable) 构造器的入参为iterable数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 | +| has(name: string): boolean | 检索searchParams对象中是否含有name。有则返回ture,否则返回false。 | +| set(name: string, value string): void | 检索searchParams对象中是否含有key为name的键值对。没有的话则添加该键值对,有的话则修改对象中第一个key所对应的value,并删除键为name的其余键值对。 | +| sort(): void | 根据键的Unicode代码点,对包含在此对象中的所有键/值对进行排序,并返回undefined。 | +| toString(): string | 根据searchParams对象,返回适用在URL中的查询字符串。 | +| keys(): iterableIterator | 返回一个iterator,遍历器允许遍历对象中包含的所有key值。 | +| values(): iterableIterator | 返回一个iterator,遍历器允许遍历对象中包含的所有value值。 | +| append(name: string, value: string): void | 在searchParams对象中插入name, value键值对。 | +| delete(name: string): void | 遍历searchParams对象,查找所有的name,删除对应的键值对。 | +| get(name: string): string | 检索searchParams对象中第一个name,返回name键对应的值。 | +| getAll(name: string): string[] | 检索searchParams对象中所有name,返回name键对应的所有值。 | +| entries(): iterableIterator<[string, string]> | 返回一个iterator,允许遍历searchParams对象中包含的所有键/值对。 | +| forEach(): void | 通过回调函数来遍历URLSearchParams实例对象上的键值对。 | +| urlSearchParams[Symbol.iterator] () | 返回查询字符串中每个名称-值对的ES6迭代器。迭代器的每个项都是一个JavaScript数组。 | + +### 使用说明 + +各接口使用方法如下: + +1、new URL(url: string,base?:string|URL) +``` +let b = new URL('https://developer.mozilla.org'); // => 'https://developer.mozilla.org/' + +let a = new URL( 'sca/./path/path/../scasa/text', 'http://www.example.com'); +// => 'http://www.example.com/sca/path/scasa/text' +``` +2、tostring():string +``` +const url = new URL('http://10.0xFF.O400.235:8080/directory/file?query#fragment'); +url.toString() // => 'http://10.0xff.o400.235:8080/directory/file?query#fragment' + +const url = new URL("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html"); +url.toString() // => 'http://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/index.html' + +const url = new URL("http://username:password@host:8080/directory/file?query#fragment"); +url.toString() // => 'http://username:password@host:8080/directory/file?query#fragment' +``` +3、toJSON():string +``` +const url = new URL("https://developer.mozilla.org/en-US/docs/Web/API/URL/toString"); +url.toJSON(); // => 'https://developer.mozilla.org/en-US/docs/Web/API/URL/toString' +``` +4、new URLSearchParams() +``` +let params = new URLSearchParams('foo=1&bar=2'); +``` +5、new URLSearchParams(string) +``` +params = new URLSearchParams('user=abc&query=xyz'); +console.log(params.get('user')); +// Prints 'abc' +``` +6、new URLSearchParams(obj) +``` +const params = new URLSearchParams({ + user: 'abc', + query: ['first', 'second'] +}); +console.log(params.getAll('query')); +// Prints [ 'first,second' ] +``` +7、new URLSearchParams(iterable) +``` +let params; + +// Using an array +params = new URLSearchParams([ + ['user', 'abc'], + ['query', 'first'], + ['query', 'second'], +]); +console.log(params.toString()); +// Prints 'user = abc & query = first&query = second' +``` +8、has(name: string): boolean +``` +console.log(params.has('bar')); // =>ture +``` +9、set(name: string, value string): void +``` +params.set('baz', 3); +``` +10、sort(): void +``` +params .sort(); +``` +11、toString(): string +``` +console.log(params .toString()); // =>bar=2&baz=3&foo=1' +``` +12、keys(): iterableIterator +``` +for(var key of params.keys()) { + console.log(key); +} // =>bar baz foo +``` +13、values(): iterableIterator +``` +for(var value of params.values()) { + console.log(value); +} // =>2 3 1 +``` +14、append(name: string, value: string): void +``` +params.append('foo', 3); // =>bar=2&baz=3&foo=1&foo=3 +``` +15、delete(name: string): void +``` +params.delete('baz'); // => bar=2&foo=1&foo=3 +``` +16、get(name: string): string +``` +params.get('foo'); // => 1 +``` +17、getAll(name: string): string[] +``` +params.getAll('foo'); // =>[ '1', '3' ] +``` +18、entries(): iterableIterator<[string, string]> +``` +for(var pair of searchParams.entries()) { + console.log(pair[0]+ ', '+ pair[1]); +} // => bar, 2 foo, 1 foo, 3 +``` +19、forEach(): void +``` +url.searchParams.forEach((value, name, searchParams) => { + console.log(name, value, url.searchParams === searchParams); +}); +// => foo 1 true +// => bar 2 true +``` +20、urlSearchParams[Symbol.iterator] () +``` +const params = new URLSearchParams('foo=bar&xyz=baz'); +for (const [name, value] of params) { + console.log(name, value); +} +// Prints: +// foo bar +// xyz ba +``` +## 相关仓 +[js_api_module子系统](https://gitee.com/OHOS_STD/js_api_module) + +[base/compileruntime/js_api_module/](base/compileruntime/js_api_module-readme.md) diff --git a/url/BUILD.gn b/api/BUILD.gn old mode 100644 new mode 100755 similarity index 73% rename from url/BUILD.gn rename to api/BUILD.gn index cd730c1c2fd657008f2dda751697a4c6950a1e54..829f0f2b7b530c413a6b070e290e33727da10bf7 --- a/url/BUILD.gn +++ b/api/BUILD.gn @@ -9,34 +9,35 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -base_output_path = get_label_info(":js_url", "target_out_dir") -js_url_obj_path = base_output_path + "/url.o" -gen_js_obj("js_url") { - input = "//base/compileruntime/js_api_module/url/js_url.js" - output = js_url_obj_path +base_output_path = get_label_info(":js_api", "target_out_dir") +js_api_obj_path = base_output_path + "/api.o" +gen_js_obj("js_api") { + input = "//base/compileruntime/js_api_module/api/js_api.js" + output = js_api_obj_path } -ohos_shared_library("url") { +ohos_shared_library("api") { include_dirs = [ "//third_party/icu/icu4c/source/common", "//third_party/node/src", "//foundation/ace/napi/interfaces/kits", - "//base/compileruntime/js_api_module/url", + "//base/compileruntime/js_api_module/api", ] sources = [ + "js_uri.cpp", "js_url.cpp", - "native_module_url.cpp", + "native_module_api.cpp", ] deps = [ - ":js_url", - "//base/compileruntime/js_api_module/url/:js_url", + ":js_api", + "//base/compileruntime/js_api_module/api/:js_api", "//foundation/ace/napi/:ace_napi", "//foundation/ace/napi/:ace_napi_quickjs", "//third_party/icu/icu4c:static_icuuc", @@ -54,6 +55,6 @@ ohos_shared_library("url") { relative_install_dir = "module" } -group("url_packages") { - deps = [ ":url" ] +group("api_packages") { + deps = [ ":api" ] } diff --git a/url/js_url.js b/api/js_api.js old mode 100644 new mode 100755 similarity index 82% rename from url/js_url.js rename to api/js_api.js index 2d00fb6bdd7b014d3c118615202df02865d3a176..4abd6fbe49c9b649468f2924e2859dc8d39ab015 --- a/url/js_url.js +++ b/api/js_api.js @@ -14,15 +14,94 @@ */ 'use strict'; -const urlUtil = requireInternal('url'); -let seachParamsArr = []; +const api = requireInternal("api"); + +class URI { + constructor(input) { + if (typeof input !== 'string' || input.length === 0) { + throw new Error("input type err"); + } + this.uricalss = new api.Uri(input); + let errStr = this.uricalss.isFailed; + if (errStr.length !== 0) { + throw new Error(errStr); + } + } + toString() { + return toAscllString(this.uricalss.toString()); + } + + equals(other) { + return this.uricalss.equals(other.uricalss); + } + + isAbsolute() { + return this.uricalss.isAbsolute(); + } + + normalize() { + return this.uricalss.normalize(); + } + + get scheme() { + return this.uricalss.scheme; + } + + get authority() { + return this.uricalss.authority; + } + + get ssp() { + return this.uricalss.ssp; + } + + get userinfo() { + return this.uricalss.userinfo; + } + get host() { + return this.uricalss.host; + } + + get port() { + return this.uricalss.port; + } + + get path() { + return this.uricalss.path; + } + + get query() { + return this.uricalss.query; + } + + get fragment() { + return this.uricalss.fragment; + } + +} + +function toAscllString(uriStr) { + if (uriStr.indexOf('[') !== -1) { + let arr = uriStr.split("["); + let brr = arr[1].split("]"); + arr[1] = '[' + brr[0] + ']'; + arr[2] = brr[1]; + arr[0] = encodeURI(arr[0]); + arr[2] = encodeURI(arr[2]); + return arr.join(''); + } else { + return encodeURI(uriStr); + } +} + +let seachParamsArr = []; class URLSearchParams { urlcalss; constructor(input) { let out = []; out = parameterProcessing(input); - this.urlcalss = new urlUtil.URLSearchParams1(); + this.urlcalss = new api.URLSearchParams1(); this.urlcalss.array = out; } append(params1, params2) { @@ -84,6 +163,7 @@ class URLSearchParams { this.urlcalss.array = out; } } + function toHleString(arg) { return arg.toString(); } @@ -144,7 +224,7 @@ function initToStringSeachParams(input) { input = input.slice(1); } let strVal = decodeURI(input); - seachParamsArr = urlUtil.stringParmas(strVal); + seachParamsArr = api.stringParmas(strVal); return seachParamsArr; } class URL { @@ -169,7 +249,7 @@ class URL { if (arguments.length === 1) { inputUrl = arguments[0]; if (typeof inputUrl === 'string' && inputUrl.length > 0) { - nativeUrl = new urlUtil.Url(inputUrl); + nativeUrl = new api.Url(inputUrl); } else { console.log('Input parameter error'); } @@ -181,7 +261,7 @@ class URL { if (typeof inputUrl === 'string') { if (typeof inputBase === 'string') { if (inputBase.length > 0) { - nativeUrl = new urlUtil.Url(inputUrl, inputBase); + nativeUrl = new api.Url(inputUrl, inputBase); } else { console.log('Input parameter error'); return; @@ -189,7 +269,7 @@ class URL { } if (typeof inputBase === 'object') { let nativeBase = inputBase.getInfo(); - nativeUrl = new urlUtil.Url(inputUrl, nativeBase); + nativeUrl = new api.Url(inputUrl, nativeBase); } } } @@ -358,6 +438,7 @@ class URL { this.set_href(); } } + get pathname() { return this.pathname_; } @@ -409,6 +490,7 @@ class URL { } export default { + URI: URI, URLSearchParams: URLSearchParams, URL: URL, } diff --git a/api/js_uri.cpp b/api/js_uri.cpp new file mode 100755 index 0000000000000000000000000000000000000000..306c118072ea970b328c8fef87da8a6fccd5ca6d --- /dev/null +++ b/api/js_uri.cpp @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "js_uri.h" +#include "utils/log.h" +namespace OHOS::Api { + std::bitset g_ruleAlpha; + std::bitset g_ruleScheme; + std::bitset g_ruleUrlc; + std::bitset g_rulePath; + std::bitset g_ruleUserInfo; + std::bitset g_ruleScope; + std::bitset g_ruleDigit; + std::bitset g_rulePort; + void Uri::PreliminaryWork() + { + std::string digitAggregate = "0123456789"; + for (size_t i = 0; i < digitAggregate.size(); ++i) { + g_ruleDigit.set(digitAggregate[i]); + } + + std::string alphasAggregate = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + for (size_t i = 0; i < alphasAggregate.size(); ++i) { + g_ruleAlpha.set(alphasAggregate[i]); + } + + std::string schemeAggregate = digitAggregate + alphasAggregate + "+-."; + for (size_t i = 0; i < schemeAggregate.size(); ++i) { + g_ruleScheme.set(schemeAggregate[i]); + } + + std::string uricAggregate = schemeAggregate + ";/?:@&=$,[]_!~*'()"; + for (size_t i = 0; i < uricAggregate.size(); ++i) { + g_ruleUrlc.set(uricAggregate[i]); + } + + std::string pathAggregate = schemeAggregate + ";/:@&=$,_!~*'()"; + for (size_t i = 0; i < pathAggregate.size(); ++i) { + g_rulePath.set(pathAggregate[i]); + } + + std::string userInfoAggregate = schemeAggregate + ";:&=$,_!~*'()"; + for (size_t i = 0; i < userInfoAggregate.size(); ++i) { + g_ruleUserInfo.set(userInfoAggregate[i]); + } + + std::string scopeAggregate = digitAggregate + alphasAggregate + "_."; + for (size_t i = 0; i < scopeAggregate.size(); ++i) { + g_ruleScope.set(scopeAggregate[i]); + } + + std::string portAggregate = digitAggregate + alphasAggregate + ".:@-;&=+$,-_!~*'()"; + for (size_t i = 0; i < portAggregate.size(); ++i) { + g_rulePort.set(portAggregate[i]); + } + } + + Uri::Uri(napi_env env, const std::string input) + { + PreliminaryWork(); + env_ = env; + errStr_ = ""; + if (input.empty()) { + errStr_ = "uri is empty"; + return; + } + inputUri_ = input; + AnalysisUri(); + } + + void Uri::AnalysisUri() + { + data_ = inputUri_; + // Fragment + size_t pos = data_.find('#'); + if (pos != std::string::npos) { + if (pos != 0) { + AnalysisFragment(pos); + } else { + errStr_ = "#It can't be the first"; + return; + } + } + pos = data_.find('?'); // Query + if (pos != std::string::npos) { + AnalysisQuery(pos); + if (!errStr_.empty()) { + return; + } + } + pos = data_.find(':'); // Scheme + if (pos != std::string::npos) { + AnalysisScheme(pos); + if (!errStr_.empty()) { + return; + } + } else { + SpecialPath(); + if (!errStr_.empty()) { + return; + } + uriData_.SchemeSpecificPart = data_ + "?" + uriData_.query; + return; + } + // userInfo path host port ipv4 or ipv6 + pos = data_.find("//"); + if (pos != std::string::npos && pos == 0) { + uriData_.SchemeSpecificPart = data_ + "?" + uriData_.query; + data_ = data_.substr(2); // 2:Intercept the string from the second subscript + AnalysisHostAndPath(); + if (!errStr_.empty()) { + return; + } + } else if (data_.find('/') == 0) { + uriData_.path = data_; + uriData_.SchemeSpecificPart = data_ + uriData_.query; + data_ = ""; + return; + } else if (!data_.empty()) { + uriData_.SchemeSpecificPart = data_ + uriData_.query; + uriData_.query = ""; + data_ = ""; + return; + } + } + + bool Uri::CheckCharacter(std::string data, std::bitset rule, bool flag) + { + size_t dataLen = data.size(); + for (size_t i = 0; i < dataLen; ++i) { + if (data[i] >= 0 && data[i] < 128) { // 128:Number of ASCII characters + bool isLegal = rule.test(data[i]); + if (!isLegal) { + return false; + } + } else if (!flag) { + return false; + } + } + return true; + } + + void Uri::SpecialPath() + { + if (!CheckCharacter(data_, g_rulePath, true)) { + errStr_ = "SpecialPath does not conform to the rule"; + return; + } + uriData_.path = data_; + data_ = ""; + } + + void Uri::AnalysisFragment(size_t pos) + { + std::string fragment = data_.substr(pos + 1); + if (!CheckCharacter(fragment, g_ruleUrlc, true)) { + errStr_ = "Fragment does not conform to the rule"; + return; + } + uriData_.fragment = fragment; + data_ = data_.substr(0, pos); + } + + void Uri::AnalysisQuery(size_t pos) + { + std::string query = data_.substr(pos + 1); + if (!CheckCharacter(query, g_ruleUrlc, true)) { + errStr_ = "Query does not conform to the rule"; + return; + } + uriData_.query = query; + data_ = data_.substr(0, pos); + } + + void Uri::AnalysisScheme(size_t pos) + { + size_t slashPos = data_.find('/'); + if (slashPos != std::string::npos && slashPos < pos) { + SpecialPath(); + uriData_.SchemeSpecificPart = uriData_.path + "?" + uriData_.query; + data_ = ""; + } else { + if (!g_ruleAlpha.test(data_[0])) { + errStr_ = "Scheme the first character must be a letter"; + return; + } + std::string scheme = data_.substr(0, pos); + if (!CheckCharacter(scheme, g_ruleScheme, false)) { + errStr_ = "scheme does not conform to the rule"; + return; + } + uriData_.scheme = scheme; + data_ = data_.substr(pos + 1); + } + } + + void Uri::AnalysisHostAndPath() + { + if (data_.empty()) { + return; + } + // find path + size_t pos = data_.find('/'); + if (pos != std::string::npos) { + AnalysisPath(pos); + if (!errStr_.empty()) { + return; + } + } + + uriData_.authority = data_; + + // find UserInfo + pos = data_.find('@'); + if (pos != std::string::npos) { + AnalysisUserInfo(pos); + if (!errStr_.empty()) { + return; + } + } + bool isLawfulProt = false; + // find port + pos = data_.rfind(':'); + if (pos != std::string::npos) { + isLawfulProt = AnalysisPort(pos); + if (!errStr_.empty()) { + return; + } + } + + // find ipv4 or ipv6 or host + if (data_[0] == '[') { + if (data_[data_.size() - 1] == ']') { + // IPV6 + if (!isLawfulProt) { + errStr_ = "ipv6 does not conform to the rule"; + return; + } + AnalysisIPV6(); + } else { + errStr_ = "ipv6 does not conform to the rule"; + return; + } + } else { + // ipv4 + if (!isLawfulProt | !AnalysisIPV4()) { + uriData_.port = -1; + uriData_.host = ""; + uriData_.userInfo = ""; + } + } + } + + void Uri::AnalysisPath(size_t pos) + { + std::string path = data_.substr(pos); + if (!CheckCharacter(path, g_rulePath, true)) { + errStr_ = "path does not conform to the rule"; + return; + } + uriData_.path = path; + data_ = data_.substr(0, pos); + } + + void Uri::AnalysisUserInfo(size_t pos) + { + std::string userInfo = data_.substr(0, pos); + if (!CheckCharacter(userInfo, g_ruleUserInfo, true)) { + errStr_ = "userInfo does not conform to the rule"; + return; + } + uriData_.userInfo = userInfo; + data_ = data_.substr(pos + 1); + } + + bool Uri::AnalysisPort(size_t pos) + { + std::string port = data_.substr(pos + 1); + if (!CheckCharacter(port, g_rulePort, true)) { // 存在非规则内字符 + errStr_ = "port does not conform to the rule"; + return false; + } else if (CheckCharacter(port, g_ruleDigit, false)) { // 纯数字 + uriData_.port = std::stoi(port); + data_ = data_.substr(0, pos); + return true; + } else { + data_ = data_.substr(0, pos); + return false; + } + return false; + } + + bool Uri::AnalysisIPV4() + { + std::regex ipv4("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"); + std::regex hostname("([a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+([a-zA-Z]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)"); + bool isIpv4 = std::regex_match(data_, ipv4); + bool isHosName = std::regex_match(data_, hostname); + if (!isIpv4 && !isHosName) { + return false; + } else { + uriData_.host = data_; + data_ = ""; + return true; + } + } + + void Uri::AnalysisIPV6() + { + std::string str = data_.substr(1, data_.size() - 2); // 2:Intercept the string from the second subscript + std::regex ipv6("^(::|(:((:[0-9A-Fa-f]{1,4}){1,7}))|(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|" + "(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(([0-9A-Fa-f]{1,4}:){2}" + "(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})" + "|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){5}" + "(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|" + "(((:(:[0-9A-Fa-f]{1,4}){0,5}:)|(([0-9A-Fa-f]{1,4}:){1}(:[0-9A-Fa-f]{1,4}){0,4}:)" + "|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:)|(([0-9A-Fa-f]{1,4}:){3}" + "(:[0-9A-Fa-f]{1,4}){0,2}:)|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4})?:)|" + "(([0-9A-Fa-f]{1,4}:){5}:)|(([0-9A-Fa-f]{1,4}:){6}))((25[0-5]|2[0-4]\\d|1\\d{2}|" + "[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)))(%[a-zA-Z0-9._]+)?$"); + if (!std::regex_match(str, ipv6)) { + errStr_ = "ipv6 does not conform to the rule"; + return; + } + uriData_.host = data_; + data_ = ""; + } + + bool Uri::Equals(const Uri other) const + { + if (uriData_.port != other.uriData_.port) { + return false; + } + if (uriData_.scheme != other.uriData_.scheme) { + return false; + } + if (uriData_.userInfo != other.uriData_.userInfo) { + return false; + } + if (uriData_.host != other.uriData_.host) { + return false; + } + if (uriData_.query != other.uriData_.query) { + return false; + } + if (uriData_.fragment != other.uriData_.fragment) { + return false; + } + if (uriData_.path != other.uriData_.path) { + return false; + } + if (uriData_.authority != other.uriData_.authority) { + return false; + } + if (uriData_.SchemeSpecificPart != other.uriData_.SchemeSpecificPart) { + return false; + } + return true; + } + + std::string Uri::ToString() const + { + return inputUri_; + } + + bool Uri::IsAbsolute() const + { + return !uriData_.scheme.empty(); + } + + std::string Uri::IsFailed() const + { + return errStr_; + } + + std::string Uri::Normalize() const + { + std::vector temp; + size_t pathLen = uriData_.path.size(); + if (pathLen == 0) { + return this->inputUri_; + } + size_t pos = 0; + size_t left = 0; + while ((pos = uriData_.path.find('/', left)) != std::string::npos) { + temp.push_back(uriData_.path.substr(left, pos - left)); + left = pos + 1; + } + if (left != pathLen) { + temp.push_back(uriData_.path.substr(left)); + } + size_t tempLen = temp.size(); + std::vector normalizeTemp; + for (size_t i = 0; i < tempLen; ++i) { + if (!temp[i].empty() && !(temp[i] == ".") && !(temp[i] == "..")) { + normalizeTemp.push_back(temp[i]); + } + if (temp[i] == "..") { + if (!normalizeTemp.empty() && normalizeTemp.back() != "..") { + normalizeTemp.pop_back(); + } else { + normalizeTemp.push_back(temp[i]); + } + } + } + std::string normalizePath = ""; + tempLen = normalizeTemp.size(); + if (tempLen == 0) { + normalizePath = "/"; + } else { + for (size_t i = 0; i < tempLen; ++i) { + normalizePath += "/" + normalizeTemp[i]; + } + } + return Split(normalizePath); + } + + + std::string Uri::Split(std::string path) const + { + std::string normalizeUri = ""; + if (!uriData_.scheme.empty()) { + normalizeUri += uriData_.scheme + ":"; + } + if (uriData_.path.empty()) { + normalizeUri += uriData_.SchemeSpecificPart; + } else { + if (!uriData_.host.empty()) { + normalizeUri += "//"; + if (!uriData_.userInfo.empty()) { + normalizeUri += uriData_.userInfo + "@"; + } + normalizeUri += uriData_.host; + if (uriData_.port != -1) { + normalizeUri += ":" + std::to_string(uriData_.port); + } + } else if (!uriData_.authority.empty()) { + normalizeUri += "//" + uriData_.authority; + } + normalizeUri += path; + } + if (!uriData_.query.empty()) { + normalizeUri += "?" + uriData_.query; + } + if (!uriData_.fragment.empty()) { + normalizeUri += "#" + uriData_.fragment; + } + return normalizeUri; + } + + + std::string Uri::GetScheme() const + { + if (uriData_.scheme.empty()) { + return "null"; + } + return uriData_.scheme; + } + + std::string Uri::GetAuthority() const + { + if (uriData_.authority.empty()) { + return "null"; + } + return uriData_.authority; + } + + std::string Uri::GetSsp() const + { + if (uriData_.SchemeSpecificPart.empty()) { + return "null"; + } + return uriData_.SchemeSpecificPart; + } + + std::string Uri::GetUserinfo() const + { + if (uriData_.userInfo.empty()) { + return "null"; + } + return uriData_.userInfo; + } + + std::string Uri::GetHost() const + { + if (uriData_.host.empty()) { + return "null"; + } + return uriData_.host; + } + + std::string Uri::GetPort() const + { + return std::to_string(uriData_.port); + } + + std::string Uri::GetPath() const + { + if (uriData_.path.empty()) { + return "null"; + } + return uriData_.path; + } + + std::string Uri::GetQuery() const + { + if (uriData_.query.empty()) { + return "null"; + } + return uriData_.query; + } + + std::string Uri::GetFragment() const + { + if (uriData_.fragment.empty()) { + return "null"; + } + return uriData_.fragment; + } +} // namespace \ No newline at end of file diff --git a/api/js_uri.h b/api/js_uri.h new file mode 100755 index 0000000000000000000000000000000000000000..d2774f38baf6abf05feadbb39e05a405a423a225 --- /dev/null +++ b/api/js_uri.h @@ -0,0 +1,86 @@ + /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMPILERUNTIME_JS_API_URI_H +#define COMPILERUNTIME_JS_API_URI_H + +#include +#include +#include +#include +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS::Api { + constexpr int MAX_BIT_SIZE = 128; + struct uri_data { + int port = -1; + std::string scheme = ""; + std::string userInfo = ""; + std::string host = ""; + std::string query = ""; + std::string fragment = ""; + std::string path = ""; + std::string authority = ""; + std::string SchemeSpecificPart = ""; + }; + + class Uri { + public: + Uri(napi_env env, const std::string input); + virtual ~Uri() {} + + bool Equals(const Uri other) const; + bool IsAbsolute() const; + + std::string IsFailed() const; + std::string ToString() const; + std::string Normalize() const; + std::string GetScheme() const; + std::string GetAuthority() const; + std::string GetSsp() const; + std::string GetUserinfo() const; + std::string GetHost() const; + std::string GetPort() const; + std::string GetPath() const; + std::string GetQuery() const; + std::string GetFragment() const; + private: + void PreliminaryWork(); + void AnalysisUri(); + void SpecialPath(); + void AnalysisFragment(size_t pos); + void AnalysisQuery(size_t pos); + void AnalysisScheme(size_t pos); + void AnalysisHostAndPath(); + void AnalysisPath(size_t pos); + void AnalysisUserInfo(size_t pos); + void AnalysisIPV6(); + + bool CheckCharacter(std::string data, std::bitset rule, bool flag); + bool AnalysisPort(size_t pos); + bool AnalysisIPV4(); + + std::string Split(std::string path) const; + private: + uri_data uriData_; + std::string data_; + std::string inputUri_; + std::string errStr_; + napi_env env_ = nullptr; + }; +} // namespace +#endif /* COMPILERUNTIME_JS_API_URI_H */ \ No newline at end of file diff --git a/api/js_url.cpp b/api/js_url.cpp new file mode 100755 index 0000000000000000000000000000000000000000..1175b0cf17c5e4ecb1cd8523062e54a65da7d8de --- /dev/null +++ b/api/js_url.cpp @@ -0,0 +1,2130 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "js_url.h" +#include +#include +#include +#include "securec.h" +#include "utils/log.h" +namespace OHOS::Api { + static std::map g_head = { + {"ftp:", 21}, {"file:", -1}, {"gopher:", 70}, {"http:", 80}, + {"https:", 443}, {"ws:", 80}, {"wss:", 443} + }; + + static std::vector g_doubleSegment = { + "..", ".%2e", ".%2E", "%2e.", "%2E.", + "%2e%2e", "%2E%2E", "%2e%2E", "%2E%2e" + }; + + static std::vector g_singlesegment = { ".", "%2e", "%2E" }; + + static std::vector g_specialcharacter = { + '\0', '\t', '\n', '\r', ' ', '#', '%', '/', ':', '?', + '@', '[', '\\', ']' + }; + + static void ReplaceSpecialSymbols(std::string& input, std::string& oldstr, std::string& newstr) + { + size_t oldlen = oldstr.size(); + while (true) { + size_t pos = 0; + if ((pos = input.find(oldstr)) != std::string::npos) { + input.replace(pos, oldlen, newstr); + } else { + break; + } + } + } + + template + bool IsASCIITabOrNewline(const T ch) + { + return (ch == '\t' || ch == '\n' || ch == '\r'); + } + + template + bool IsHexDigit(const T ch) + { + if (isdigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { + return true; + } + return false; + } + + static unsigned AsciiToHex(const unsigned char pram) + { + if (pram >= '0' && pram <= '9') { + return pram - '0'; + } + if (pram >= 'A' && pram <= 'F') { + return pram - 'A' + 10; // 10:Convert to hexadecimal + } + if (pram >= 'a' && pram <= 'f') { + return pram - 'a' + 10; // 10:Convert to hexadecimal + } + return static_cast(-1); + } + + static std::string DecodePercent(const char *input, size_t len) + { + std::string temp; + if (len == 0) { + return temp; + } + temp.reserve(len); + const char *it = input; + const char *end = input + len; + while (it < end) { + const char ch = it[0]; + size_t left = end - it - 1; + if (ch != '%' || left < 2 || (ch == '%' && (!IsHexDigit(it[1]) || // 2:The length is less than 2 + !IsHexDigit(it[2])))) { // 2:The number of characters is less than 2 + temp += ch; + it++; + continue; + } else { + unsigned first = AsciiToHex(it[1]); + unsigned second = AsciiToHex(it[2]); // 2:Subscript 2 + char pram = static_cast(first * 16 + second); // 16:Convert hex + temp += pram; + it += 3; // 3:Move the pointer to the right by 3 digits. + } + } + return temp; + } + + static void DeleteC0OrSpace(std::string& str) + { + if (str.empty()) { + return; + } + size_t i = 0; + size_t strlen = str.size(); + for (; i < strlen;) { + if (str[i] >= '\0' && str[i] <= ' ') { + i++; + } else { + break; + } + } + str = str.substr(i); + strlen = str.size(); + for (i = strlen - 1; i != 0; i--) { + if (str[i] >= '\0' && str[i] <= ' ') { + str.pop_back(); + } else { + break; + } + } + } + + static void DeleteTabOrNewline(std::string& str1) + { + for (auto item = str1.begin(); item != str1.end();) { + if (IsASCIITabOrNewline(*item)) { + item = str1.erase(item); + } else { + ++item; + } + } + } + + static bool IsSpecial(std::string scheme) + { + auto temp = g_head.count(scheme); + if (temp > 0) { + return true; + } + return false; + } + + static bool AnalysisScheme(std::string& input, std::string& scheme, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (!isalpha(input[0])) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return false; + } else { + size_t strlen = input.size(); + for (size_t i = 0; i < strlen - 1; ++i) { + if ((isalnum(input[i]) || input[i] == '+' || input[i] == '-' || input[i] == '.') && + isupper(input[i])) { + input[i] = tolower(input[i]); + } + if (!isalnum(input[i]) && input[i] != '+' && input[i] != '-' && input[i] != '.') { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + // 0:Bit 0 Set to true,The URL analysis failed + return false; + } + } + scheme = input; + if (IsSpecial(scheme)) { + flags.set(static_cast(BitsetStatusFlag::BIT1)); + } + return true; + } + } + + static void AnalysisFragment(const std::string& input, std::string& fragment, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + fragment = input; + flags.set(static_cast(BitsetStatusFlag::BIT8)); + } + + static void AnalysisQuery(const std::string& input, std::string& query, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + query = input; + flags.set(static_cast(BitsetStatusFlag::BIT7)); + } + static void AnalysisUsernameAndPasswd(std::string& input, std::string& username, std::string& password, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + int pos = input.size() - 1; + for (; pos >= 0; pos--) { + if (input[pos] == '@') { + break; + } + } + std::string userAndPasswd = input.substr(0, pos); + input = input.substr(pos + 1); + if (userAndPasswd.empty()) { + return; + } + if (userAndPasswd.find('@') != std::string::npos) { + while (true) { + size_t i = 0; + if ((i = userAndPasswd.find('@')) != std::string::npos) { + userAndPasswd = userAndPasswd.replace(i, 1, "%40"); + } else { + break; + } + } + } + + if (userAndPasswd.find(':') != std::string::npos) { + size_t i = userAndPasswd.find(':'); + std::string user = userAndPasswd.substr(0, i); + std::string keyWord = userAndPasswd.substr(i + 1); + if (!user.empty()) { + username = user; + flags.set(static_cast(BitsetStatusFlag::BIT2)); + } + if (!keyWord.empty()) { + password = keyWord; + flags.set(static_cast(BitsetStatusFlag::BIT3)); + } + } else { + username = userAndPasswd; + flags.set(static_cast(BitsetStatusFlag::BIT2)); + } + } + + static void AnalysisPath(std::string& input, std::vector& path, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool isSpecial) + { + std::vector temp; + size_t pos = 0; + while (((pos = input.find('/')) != std::string::npos) || + ((pos = input.find('\\')) != std::string::npos && isSpecial)) { + temp.push_back(input.substr(0, pos)); + input = input.substr(pos + 1); + } + temp.push_back(input); + size_t length = temp.size(); + for (size_t it = 0; it < length; ++it) { + auto result = find(g_doubleSegment.begin(), g_doubleSegment.end(), temp[it]); + if (result != g_doubleSegment.end()) { + if (path.empty() && it == length - 1) { + path.emplace_back(""); + flags.set(static_cast(BitsetStatusFlag::BIT6)); + } + if (path.empty()) { + continue; + } + path.pop_back(); + if (it == length - 1) { + path.emplace_back(""); + flags.set(static_cast(BitsetStatusFlag::BIT6)); + } + continue; + } + result = find(g_singlesegment.begin(), g_singlesegment.end(), temp[it]); + if (result != g_singlesegment.end() && it == length - 1) { + path.emplace_back(""); + flags.set(static_cast(BitsetStatusFlag::BIT6)); + continue; + } + if (result == g_singlesegment.end()) { + path.push_back(temp[it]); + flags.set(static_cast(BitsetStatusFlag::BIT6)); + } + } + } + + static void AnalysisPort(std::string input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + for (auto i : input) { + if (!isdigit(i)) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + int it = stoi(input); + const int maxPort = 65535; // 65535:Maximum port number + if (it > maxPort) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + flags.set(static_cast(BitsetStatusFlag::BIT5)); + for (auto i : g_head) { + if (i.first == urlinfo.scheme && i.second == it) { + urlinfo.port = -1; + flags.set(static_cast(BitsetStatusFlag::BIT5), 0); + return; + } + } + urlinfo.port = it; + } + + static void AnalysisOpaqueHost(std::string input, std::string& host, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + size_t strlen = input.size(); + for (size_t i = 0; i < strlen; ++i) { + char ch = input[i]; + auto result = find(g_specialcharacter.begin(), g_specialcharacter.end(), ch); + if (ch != '%' && (result != g_specialcharacter.end())) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + host = input; + flags.set(static_cast(BitsetStatusFlag::BIT4)); + } + + static std::string IPv6ZeroComperess(std::vector& tempIPV6, std::string& input, + int maxZeroIndex, int max) + { + for (int i = 0; i < maxZeroIndex; ++i) { + input += tempIPV6[i]; + if (i != maxZeroIndex - 1) { + input += ":"; + } + } + input += "::"; + size_t strlen = tempIPV6.size(); + for (size_t i = maxZeroIndex + max; i < strlen; ++i) { + input += tempIPV6[i]; + if (i != strlen - 1) { + input += ":"; + } + } + return input; + } + + static std::string IPv6NoComperess(std::vector& tempIPV6, std::string& input) + { + size_t strlen = tempIPV6.size(); + for (size_t i = 0; i < strlen; ++i) { + if (tempIPV6[i][0] == '?' && tempIPV6[i].size() == 1) { + input += ":"; + } else { + input += tempIPV6[i]; + if (i != tempIPV6.size() - 1) { + input += ":"; + } + } + } + return input; + } + + static std::string IPv6HostCompress(std::vector& tempIPV6, int flag) + { + std::string input; + if (flag == 1) { + return IPv6NoComperess(tempIPV6, input); + } + int max = 0; + int count = 0; + size_t maxZeroIndex = 0; + size_t strlen = tempIPV6.size(); + for (size_t i = 0; i < strlen;) { + if (tempIPV6[i] == "0" && (i + 1 < strlen && tempIPV6[i + 1] == "0")) { + int index = i; + while (i < strlen && tempIPV6[i] == "0") { + i++; + count++; + } + if (max < count) { + max = count; + maxZeroIndex = index; + } + } else { + count = 0; + i++; + } + } + if (count == 8) { // 8:If IPv6 is all 0 + return "::"; + } else if (max == 0) { + strlen = tempIPV6.size(); + for (size_t i = 0; i < strlen; ++i) { + input += tempIPV6[i]; + if (i != strlen - 1) { + input += ":"; + } + } + return input; + } else if (maxZeroIndex == 0) { + input += "::"; + strlen = tempIPV6.size(); + for (size_t i = max; i < strlen; ++i) { + input += tempIPV6[i] + ":"; + } + input.pop_back(); + return input; + } else { + return IPv6ZeroComperess(tempIPV6, input, maxZeroIndex, max); + } + } + + void DealWithtempIpv6(std::vector &tempIpv6, std::stringstream &ss, + std::string &numberHex, const int tempProt[4]) + { + tempIpv6.push_back(numberHex); + ss.clear(); + numberHex.clear(); + ss << std::hex << tempProt[2] * 0x100 + tempProt[3]; // 2: 3:subscript position + ss >> numberHex; + tempIpv6.push_back(numberHex); + ss.clear(); + numberHex.clear(); + tempIpv6.erase(tempIpv6.end() - 3); // 3:Remove redundant space + } + + void IPv6DealWithColon(int& flag, std::string& strInput, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t &pos) + { + flag = 1; + if (strInput.find("::", pos + 2) != std::string::npos) { // 2:Subscript Move Right2 + flags.set(static_cast(BitsetStatusFlag::BIT0)); + } + return; + } + + void IsFlagExist(size_t &pos, std::vector &temp, std::vector &tempEnd, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags, unsigned &numberFlag) + { + while (((pos = temp[numberFlag].find('.')) != std::string::npos)) { + tempEnd.push_back(temp[numberFlag].substr(0, pos)); + temp[numberFlag] = temp[numberFlag].substr(pos + 1); + } + tempEnd.push_back(temp[numberFlag]); + if (tempEnd.size() != 4) { // 4:The size is not 4 + flags.set(static_cast(BitsetStatusFlag::BIT0)); + } + } + void DealWithProt(std::vector &tempEnd, unsigned &val, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, + int &number, int tempProt[4]) + { + size_t strlen = tempEnd.size(); + for (size_t x = 0; x < strlen; ++x) { + val = stoi(tempEnd[x]); + if (val > 255) { // 255:The maximum value is 255 + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + tempProt[number] = val; + number++; + val = 0; + } + } + + void DealWithElse(std::vector &temp, size_t &i, unsigned &numberFlag, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, unsigned &val) + { + size_t strlen = temp[i].size(); + for (size_t j = 0; j < strlen; ++j) { + if (((temp[i].find('.')) != std::string::npos)) { + numberFlag = i; + if (temp.size() == i || temp.size() > 7) { // 7:The size cannot be greater than 7 + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + return; + } else if (IsHexDigit(temp[i][j])) { + val = val * 0x10 + AsciiToHex(temp[i][j]); + } + } + } + + void DealWithStringStream(std::stringstream &ss, unsigned &val, + std::string &numberHex, std::vector &tempIpv6) + { + ss << std::hex << val; + ss >> numberHex; + tempIpv6.push_back(numberHex); + ss.clear(); + numberHex.clear(); + val = 0; + } + + static void IPv6Host(std::string& input, std::string& host, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (input.size() == 0) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + std::string strInput = input; + std::stringstream ss; + std::string numberHex; + unsigned val = 0; + unsigned numberFlag = 0; + std::vector temp; + std::vector tempEnd; + std::vector tempIpv6; + size_t pos = 0; + int tempProt[4] = { 0 }; + int number = 0; + int flag = 0; + if ((pos = strInput.find("::", 0)) != std::string::npos) { + IPv6DealWithColon(flag, strInput, flags, pos); + } + while (((pos = strInput.find(':')) != std::string::npos)) { + temp.push_back(strInput.substr(0, pos)); + strInput = strInput.substr(pos + 1); + } + temp.push_back(strInput); + if (temp.size() > 8) { // 8:The incoming value does not meet the criteria + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + size_t length = temp.size(); + for (size_t i = 0; i < length; ++i) { + if (temp[i].empty()) { + tempIpv6.push_back("?"); + } else { + DealWithElse(temp, i, numberFlag, flags, val); + DealWithStringStream(ss, val, numberHex, tempIpv6); + } + } + if (numberFlag != 0) { + IsFlagExist(pos, temp, tempEnd, flags, numberFlag); + DealWithProt(tempEnd, val, flags, number, tempProt); + ss << std::hex << tempProt[0] * 0x100 + tempProt[1]; + ss >> numberHex; + DealWithtempIpv6(tempIpv6, ss, numberHex, tempProt); + } + strInput = IPv6HostCompress(tempIpv6, flag); + host = '[' + strInput + ']'; + flags.set(static_cast(BitsetStatusFlag::BIT4)); + flags.set(static_cast(BitsetStatusFlag::BIT10)); + } + + static bool CheckNunType(const char ch, const unsigned num) + { + enum class NUMERATION { + OCT = 8, // 8:Octal + DEC = 10, // 10:Decimal + HEX = 16 // 16:Hexadecimal + }; + if (NUMERATION(num) == NUMERATION::OCT) { + if (ch < '0' || ch > '7') { // 0~7:Octal + return false; + } + } else if (NUMERATION(num) == NUMERATION::DEC) { + if (ch < '0' || ch > '9') { // 0~9:Decimal + return false; + } + } else if (NUMERATION(num) == NUMERATION::HEX) { + if (!((ch >= '0' && ch <= '9') || // 0~9, a~f, A~F:Hexadecimal + (ch >= 'A' && ch <= 'F') || + (ch >= 'a' && ch <= 'f'))) { + return false; + } + } + return true; + } + + static int64_t AnalyseNum(std::string parts) + { + unsigned num = 10; // 10:Decimal + std::string partsBeg = parts.substr(0, 2); // 2:Take two digits to determine whether it is hexadecimal + size_t partsLen = parts.length(); + if (partsLen >= 2 && (partsBeg == "0X" || partsBeg == "0x")) { // 2:parts length + num = 16; // 16:Convert to hexadecimal + parts = parts.substr(2); // 2:delete '0x' + } else if (num == 10 && partsLen > 1 && parts.substr(0, 1) == "0") { // 10:Conversion to Decimal Coefficient + num = 8; // 8:Convert to octal + parts = parts.substr(1); + } + for (size_t i = 0; i < parts.length(); i++) { + bool ret = CheckNunType(parts[i], num); + if (!ret) { + return -1; + } + } + return strtoll(parts.c_str(), nullptr, num); + } + + static bool OverHex(std::string input) + { + size_t size = input.size(); + for (size_t i = 0; i < size; i++) { + return !IsHexDigit(input[i]); + } + return false; + } + + static bool NotAllNum(std::string input) + { + size_t size = input.size(); + for (size_t i = 0; i < size; i++) { + if (!isdigit(input[i])) { + return true; + } + } + return false; + } + + static bool AnalyseIPv4(const char *instr, std::string &host, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags) + { + int count = 0; + for (const char *ptr = instr; *ptr != '\0'; ptr++) { + if (*ptr == '.') { + if (++count > 3) { // 3:The IPV4 address has only four segments + return false; + } + } + } + if (count != 3) { // 3:The IPV4 address has only four segments + return false; + } + + size_t pos = 0; + std::vector strVec; + std::string input = static_cast(instr); + while (((pos = input.find('.')) != std::string::npos)) { + strVec.push_back(input.substr(0, pos)); + input = input.substr(pos + 1); + } + strVec.push_back(input); + size_t size = strVec.size(); + for (size_t i = 0; i < size; i++) { + if (strVec[i].empty()) { + return false; + } + std::string begStr = strVec[i].substr(0, 2); // 2:Intercept the first two characters + if ((begStr == "0x" || begStr == "0X") && OverHex(strVec[i].substr(2))) { // 2:Intercept + return false; + } else if ((begStr == "0x" || begStr == "0X") && !(OverHex(strVec[i].substr(2)))) { // 2:Intercept + continue; + } + if (NotAllNum(strVec[i])) { + return false; + } + } + for (size_t i = 0; i < size; i++) { + int64_t value = AnalyseNum(strVec[i].c_str()); + if ((value < 0) || (value > 255)) { // 255:Only handle numbers between 0 and 255 + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return false; + } else { + host += std::to_string(value); + if (i != size - 1) { + host += "."; + } + } + } + flags.set(static_cast(BitsetStatusFlag::BIT4)); + return true; + } + static void AnalysisHost(std::string& input, std::string& host, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool special) + { + if (input.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + if (input[0] == '[') { + if ((input[input.length() - 1]) == ']') { + size_t b = input.length(); + input = input.substr(1, b - 2); // 2:Truncating Strings + IPv6Host(input, host, flags); + return; + } else { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + if (!special) { + AnalysisOpaqueHost(input, host, flags); + return; + } + std::string decodeInput = DecodePercent(input.c_str(), input.length()); + size_t strlen = decodeInput.size(); + for (size_t pos = 0; pos < strlen; ++pos) { + char ch = decodeInput[pos]; + auto result = find(g_specialcharacter.begin(), g_specialcharacter.end(), ch); + if (result != g_specialcharacter.end()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + bool ipv4 = AnalyseIPv4(decodeInput.c_str(), host, flags); + if (ipv4) { + return; + } + host = decodeInput; + flags.set(static_cast(BitsetStatusFlag::BIT4)); + } + static bool ISFileNohost(const std::string& input) + { + if ((isalpha(input[0]) && (input[1] == ':' || input[1] == '|'))) { + return true; + } + return false; + } + static void AnalysisFilePath(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + std::vector temp; + size_t pos = 0; + while (((pos = input.find('/')) != std::string::npos) || ((pos = input.find('\\')) != std::string::npos)) { + temp.push_back(input.substr(0, pos)); + input = input.substr(pos + 1); + } + temp.push_back(input); + size_t length = temp.size(); + for (size_t i = 0; i < length; ++i) { + auto a = find(g_doubleSegment.begin(), g_doubleSegment.end(), temp[i]); + if (a != g_doubleSegment.end()) { + if ((urlinfo.path.size() == 1) && ISFileNohost(urlinfo.path[0]) && + urlinfo.path[0].size() == 2) { // 2:The interception length is 2 + urlinfo.path[0][1] = ':'; + } else if (!urlinfo.path.empty()) { + urlinfo.path.pop_back(); + } + if (i == temp.size() - 1) { + urlinfo.path.push_back(""); + } + continue; + } + a = find(g_singlesegment.begin(), g_singlesegment.end(), temp[i]); + if (a != g_singlesegment.end()) { + if (i == temp.size() - 1) { + urlinfo.path.push_back(""); + } + continue; + } + urlinfo.path.push_back(temp[i]); + flags.set(static_cast(BitsetStatusFlag::BIT6)); + } + std::string it = urlinfo.path[0]; + if (isalpha(it[0]) && (it[1] == ':' || it[1] == '|')) { + if (it.size() == 2) { // 2:The length is 2 + it[1] = ':'; + flags.set(static_cast(BitsetStatusFlag::BIT4), 0); + urlinfo.host.clear(); + } + } + } + + static void AnalysisFile(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + bool special = true; + if ((input[0] == '/' || input[0] == '\\') && (input[1] == '/' || input[1] == '\\')) { + std::string temp = input.substr(2); // 2:Intercept from 2 subscripts + size_t pos = 0; + if ((((pos = temp.find('/')) != std::string::npos) || + ((pos = temp.find('\\')) != std::string::npos)) && pos == 0) { + temp = temp.substr(1); + AnalysisFilePath(temp, urlinfo, flags); + } else if ((((pos = temp.find('/')) != std::string::npos) || + ((pos = temp.find('\\')) != std::string::npos)) && pos != 0) { + std::string strHost = temp.substr(0, pos); + std::string strPath = temp.substr(pos + 1); + if (!ISFileNohost(strHost)) { + AnalysisHost(strHost, urlinfo.host, flags, special); + } else if (!ISFileNohost(strHost) && flags.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + if (!ISFileNohost(strHost)) { + AnalysisFilePath(strPath, urlinfo, flags); + } else { + AnalysisFilePath(temp, urlinfo, flags); + } + } else { + if (!temp.empty() && flags.test(static_cast(BitsetStatusFlag::BIT0))) { + AnalysisHost(temp, urlinfo.host, flags, special); + } else if (!temp.empty() && !flags.test(static_cast(BitsetStatusFlag::BIT0))) { + AnalysisHost(temp, urlinfo.host, flags, special); + return; + } + } + } else { + if (input[0] == '/' || input[0] == '\\') { + input = input.substr(1); + } + AnalysisFilePath(input, urlinfo, flags); + } + } + + static void AnalysisFilescheme(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + std::string strPath = urlinfo.scheme + input; + urlinfo.scheme = "file:"; + flags.set(static_cast(BitsetStatusFlag::BIT1)); + AnalysisFilePath(strPath, urlinfo, flags); + } + + void AnalyInfoPath(std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags, + UrlData& urlinfo, std::string& input) + { + flags.set(static_cast(BitsetStatusFlag::BIT9)); + if (urlinfo.path.empty()) { + urlinfo.path.emplace_back(""); + } + urlinfo.path[0] = input; + flags.set(static_cast(BitsetStatusFlag::BIT6)); + return; + } + + void AnalyHostPath(std::string &strHost, std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, + UrlData& urlinfo) + { + size_t pos = 0; + if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { + std::string port = strHost.substr(pos + 1); + strHost = strHost.substr(0, pos); + AnalysisPort(port, urlinfo, flags); + if (flags.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + } + } + void AnalyStrHost(std::string &strHost, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags) + { + if (strHost.find('@') != std::string::npos) { + AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); + } + if (strHost.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + + static void AnalysisNoDefaultProtocol(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (urlinfo.scheme.size() == 2) { // 2:The length is 2 + AnalysisFilescheme(input, urlinfo, flags); + return; + } + if (input[0] == '/' && input[1] == '/') { + std::string hostandpath = input.substr(2); // 2:Intercept from 2 subscripts + if (hostandpath.empty()) { + return; + } + size_t i = 0; + bool special = false; + if (hostandpath.find('/') != std::string::npos) { + i = hostandpath.find('/'); + std::string strHost = hostandpath.substr(0, i); + std::string strPath = hostandpath.substr(i + 1); + if (strHost.find('@') != std::string::npos) { + AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); + } + if (strHost.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + size_t pos = 0; + if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { + std::string port = strHost.substr(pos + 1); + strHost = strHost.substr(0, pos); + AnalysisPort(port, urlinfo, flags); + } + if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos && + flags.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + AnalysisHost(strHost, urlinfo.host, flags, special); + AnalysisPath(strPath, urlinfo.path, flags, special); + } else { + std::string strHost = hostandpath; + AnalyStrHost(strHost, urlinfo, flags); + AnalyHostPath(strHost, flags, urlinfo); + AnalysisHost(strHost, urlinfo.host, flags, special); + } + } else if (input[1] == '/') { + std::string strPath = input.substr(1); + AnalysisPath(strPath, urlinfo.path, flags, false); + } else { + AnalyInfoPath(flags, urlinfo, input); + } + } + + static void AnalysisOnlyHost(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t pos) + { + std::string strHost = input; + if (strHost.find('@') != std::string::npos) { + AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); + } + if (strHost.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + if (strHost[strHost.size() - 1] != ']') { + if ((pos = strHost.find_last_of(':')) != std::string::npos) { + std::string port = strHost.substr(pos + 1); + strHost = strHost.substr(0, pos); + AnalysisPort(port, urlinfo, flags); + } + if ((pos = strHost.find_last_of(':')) != std::string::npos && + flags.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + } + AnalysisHost(strHost, urlinfo.host, flags, true); + } + void JudgePos(size_t &pos, size_t &length, std::string& input) + { + for (pos = 0; pos < length; pos++) { + if (input[pos] == '/' || input[pos] == '\\') { + break; + } + } + } + static void AnalysisHostAndPath(std::string& input, UrlData& urlinfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (flags.test(static_cast(BitsetStatusFlag::BIT1))) { + size_t pos = 0; + bool special = true; + size_t inputLen = input.size(); + for (; pos < inputLen;) { + if (input[pos] == '/' || input[pos] == '\\') { + pos++; + } else { + break; + } + } + input = input.substr(pos); + if (input.size() == 0) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } else if (input.size() != 0 && (input.find('/') != std::string::npos || + input.find('\\') != std::string::npos)) { + size_t length = input.size(); + JudgePos(pos, length, input); + std::string strHost = input.substr(0, pos); + std::string strPath = input.substr(pos + 1); + if (strHost.find('@') != std::string::npos) { + AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); + } + if (strHost.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { + std::string port = strHost.substr(pos + 1); + strHost = strHost.substr(0, pos); + AnalysisPort(port, urlinfo, flags); + } + if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos && + flags.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + AnalysisHost(strHost, urlinfo.host, flags, special); + AnalysisPath(strPath, urlinfo.path, flags, special); + } else if (input.size() != 0 && input.find('/') == std::string::npos && + input.find('\\') == std::string::npos) { + AnalysisOnlyHost(input, urlinfo, flags, pos); + } + } else { + AnalysisNoDefaultProtocol(input, urlinfo, flags); + } + } + + static void AnalysisInput(std::string& input, UrlData& urlData, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (input.find('#') != std::string::npos) { + size_t i = input.find('#'); + std::string fragment = input.substr(i); + AnalysisFragment(fragment, urlData.fragment, flags); + input = input.substr(0, i); + } + if (input.find('?') != std::string::npos) { + size_t i = input.find('?'); + std::string query = input.substr(i); + AnalysisQuery(query, urlData.query, flags); + input = input.substr(0, i); + } + bool special = (flags.test(static_cast(BitsetStatusFlag::BIT1)) ? true : false); + AnalysisPath(input, urlData.path, flags, special); + } + + static void BaseInfoToUrl(const UrlData& baseInfo, + const std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags, UrlData& urlData, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool inputIsEmpty) + { + urlData.scheme = baseInfo.scheme; + flags.set(static_cast(BitsetStatusFlag::BIT1), + baseflags.test(static_cast(BitsetStatusFlag::BIT1))); + urlData.host = baseInfo.host; + flags.set(static_cast(BitsetStatusFlag::BIT4)); + urlData.username = baseInfo.username; + flags.set(static_cast(BitsetStatusFlag::BIT2), + baseflags.test(static_cast(BitsetStatusFlag::BIT2))); + urlData.password = baseInfo.password; + flags.set(static_cast(BitsetStatusFlag::BIT3), + baseflags.test(static_cast(BitsetStatusFlag::BIT3))); + urlData.port = baseInfo.port; + flags.set(static_cast(BitsetStatusFlag::BIT5), + baseflags.test(static_cast(BitsetStatusFlag::BIT5))); + if (inputIsEmpty) { + urlData.path = baseInfo.path; + flags.set(static_cast(BitsetStatusFlag::BIT6), + baseflags.test(static_cast(BitsetStatusFlag::BIT6))); + urlData.query = baseInfo.query; + flags.set(static_cast(BitsetStatusFlag::BIT7), + baseflags.test(static_cast(BitsetStatusFlag::BIT7))); + urlData.fragment = baseInfo.fragment; + flags.set(static_cast(BitsetStatusFlag::BIT8), + baseflags.test(static_cast(BitsetStatusFlag::BIT8))); + } + flags.set(static_cast(BitsetStatusFlag::BIT9), + baseflags.test(static_cast(BitsetStatusFlag::BIT9))); + flags.set(static_cast(BitsetStatusFlag::BIT10), + baseflags.test(static_cast(BitsetStatusFlag::BIT10))); + } + + static void ShorteningPath(UrlData& baseData, bool isFile) + { + if (baseData.path.empty()) { + return; + } + if ((baseData.path.size() == 1) && isFile && + isalpha(baseData.path[0][0]) && (baseData.path[0][1] == ':')) { + return; + } + baseData.path.pop_back(); + } + + URL::URL(napi_env env, const std::string& input) + { + env_ = env; + std::string str = input; + DeleteC0OrSpace(str); + DeleteTabOrNewline(str); + InitOnlyInput(str, urlData_, flags_); + } + + void DelCont(std::string strBase, std::string &strInput, UrlData &baseInfo, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &baseflags) + { + DeleteC0OrSpace(strBase); + DeleteTabOrNewline(strBase); + DeleteC0OrSpace(strInput); + DeleteTabOrNewline(strInput); + URL::InitOnlyInput(strBase, baseInfo, baseflags); + } + + URL::URL(napi_env env, const std::string& input, const std::string& base) + { + env_ = env; + UrlData baseInfo; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags; + std::string strBase = base; + std::string strInput = input; + if (strBase.empty()) { + baseflags.set(static_cast(BitsetStatusFlag::BIT0)); + } + DelCont(strBase, strInput, baseInfo, baseflags); + if (baseflags.test(static_cast(BitsetStatusFlag::BIT0))) { + flags_.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } else if (!baseflags.test(static_cast(BitsetStatusFlag::BIT0))) { + InitOnlyInput(strInput, urlData_, flags_); + if (!flags_.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + if ((input[0] == '/') && (input[1] == '/' || (input[1] == '\\' && + baseflags.test(static_cast(BitsetStatusFlag::BIT1))))) { + std::string newInput = baseInfo.scheme + input; + flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); + InitOnlyInput(newInput, urlData_, flags_); + return; + } + if (!baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { + flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); + BaseInfoToUrl(baseInfo, baseflags, urlData_, flags_, input.empty()); + if (!input.empty() && input[0] == '/') { + strInput = input.substr(1); + AnalysisInput(strInput, urlData_, flags_); + } else if (!input.empty() && input[0] != '/') { + AnalysisInput(strInput, urlData_, flags_); + } + if (!input.empty() && input[0] != '/' && urlData_.path.empty()) { + urlData_.path = baseInfo.path; + flags_.set(static_cast(BitsetStatusFlag::BIT6), + baseflags.test(static_cast(BitsetStatusFlag::BIT6))); + } + if (!input.empty() && input[0] != '/' && !urlData_.path.empty()) { + bool isFile = ((urlData_.scheme == "file:") ? true : false); + ShorteningPath(baseInfo, isFile); + baseInfo.path.insert(baseInfo.path.end(), urlData_.path.begin(), urlData_.path.end()); + urlData_.path = baseInfo.path; + flags_.set(static_cast(BitsetStatusFlag::BIT6)); + } + } else if (baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { + flags_.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + } + + URL::URL(napi_env env, const std::string& input, const URL& base) + { + env_ = env; + std::string strInput = input; + UrlData baseInfo = base.urlData_; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags = base.flags_; + DeleteC0OrSpace(strInput); + DeleteTabOrNewline(strInput); + InitOnlyInput(strInput, urlData_, flags_); + if (!flags_.test(static_cast(BitsetStatusFlag::BIT0))) { + return; + } + if ((input[0] == '/') && (input[1] == '/' || (input[1] == '\\' && + baseflags.test(static_cast(BitsetStatusFlag::BIT1))))) { + std::string newInput = baseInfo.scheme + input; + flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); + InitOnlyInput(newInput, urlData_, flags_); + return; + } + if (!baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { + flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); + BaseInfoToUrl(baseInfo, baseflags, urlData_, flags_, input.empty()); + if (!input.empty() && input[0] == '/') { + strInput = input.substr(1); + AnalysisInput(strInput, urlData_, flags_); + } + if (!input.empty() && input[0] != '/') { + AnalysisInput(strInput, urlData_, flags_); + if (urlData_.path.empty()) { + urlData_.path = baseInfo.path; + flags_.set(static_cast(BitsetStatusFlag::BIT6), + baseflags.test(static_cast(BitsetStatusFlag::BIT6))); + } else { + bool isFile = ((urlData_.scheme == "file:") ? true : false); + ShorteningPath(baseInfo, isFile); + baseInfo.path.insert(baseInfo.path.end(), urlData_.path.begin(), urlData_.path.end()); + urlData_.path = baseInfo.path; + flags_.set(static_cast(BitsetStatusFlag::BIT6)); + } + } + } else if (baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { + flags_.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + + napi_value URL::GetHostname() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT4))) { + temp = urlData_.host.c_str(); + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetSearch() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT7))) { + if (urlData_.query.size() == 1) { + temp = ""; + } else { + temp = urlData_.query.c_str(); + } + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetUsername() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT2))) { + temp = urlData_.username.c_str(); + } else + temp = ""; + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetPassword() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT3))) { + temp = urlData_.password.c_str(); + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetFragment() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT8))) { + if (urlData_.fragment.size() == 1) { + temp = ""; + } else { + temp = urlData_.fragment.c_str(); + } + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetScheme() const + { + napi_value result; + const char *temp = nullptr; + if (!urlData_.scheme.empty()) { + temp = urlData_.scheme.c_str(); + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetPath() const + { + napi_value result; + std::string temp = "/"; + if (flags_.test(static_cast(BitsetStatusFlag::BIT6))) { + size_t length = urlData_.path.size(); + for (size_t i = 0; i < length; i++) { + if (i < length - 1) { + temp += urlData_.path[i] + "/"; + } else { + temp += urlData_.path[i]; + } + } + } else { + bool special = IsSpecial(urlData_.scheme); + if (!special) { + temp = ""; + } + } + NAPI_CALL(env_, napi_create_string_utf8(env_, temp.c_str(), temp.size(), &result)); + return result; + } + + + napi_value URL::GetPort() const + { + napi_value result; + const char *temp = nullptr; + if (flags_.test(static_cast(BitsetStatusFlag::BIT5))) { + temp = std::to_string(urlData_.port).c_str(); + } else { + temp = ""; + } + size_t templen = strlen(temp); + NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); + return result; + } + + napi_value URL::GetHost() const + { + napi_value result; + std::string temp1 = urlData_.host; + if (flags_.test(static_cast(BitsetStatusFlag::BIT5))) { + temp1 += ":"; + temp1 += std::to_string(urlData_.port); + } + NAPI_CALL(env_, napi_create_string_utf8(env_, temp1.c_str(), temp1.size(), &result)); + return result; + } + + napi_value URL::GetOnOrOff() const + { + napi_value result; + if (flags_.test(static_cast(BitsetStatusFlag::BIT0))) { + bool flag = false; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + } else { + bool flag = true; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + } + return result; + } + + napi_value URL::GetIsIpv6() const + { + napi_value result; + if (flags_.test(static_cast(BitsetStatusFlag::BIT10))) { + bool flag = true; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + } else { + bool flag = false; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + } + return result; + } + + void URL::SetHostname(const std::string& input) + { + if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { + return; + } + std::string strHost = input; + size_t length = strHost.size(); + for (size_t pos = 0; pos < length; pos++) { + if ((strHost[pos] == ':') || (strHost[pos] == '?') || (strHost[pos] == '#') || + (strHost[pos] == '/') || (strHost[pos] == '\\')) { + strHost = strHost.substr(0, pos); + break; + } + } + if (strHost.size() == 0) { + return; + } + bool special = IsSpecial(urlData_.scheme); + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; + std::string thisHostname = ""; + AnalysisHost(strHost, thisHostname, thisFlags, special); + if (thisFlags.test(static_cast(BitsetStatusFlag::BIT4))) { + if ((urlData_.scheme == "file:") && (thisHostname == "localhost")) { + thisHostname = ""; + } + urlData_.host = thisHostname; + flags_.set(static_cast(BitsetStatusFlag::BIT4)); + } + } + + void URL::SetHref(const std::string& input) + { + std::string str = input; + DeleteC0OrSpace(str); + DeleteTabOrNewline(str); + UrlData thisNewUrl; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisNewFlags; + InitOnlyInput(str, thisNewUrl, thisNewFlags); + if (!thisNewFlags.test(static_cast(BitsetStatusFlag::BIT0))) { + urlData_ = thisNewUrl; + flags_ = thisNewFlags; + } + } + + void URL::SetPath(const std::string& input) + { + std::string strPath = input; + if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { + return; + } + if (strPath.empty()) { + return; + } + std::string oldstr = "%3A"; + std::string newstr = ":"; + ReplaceSpecialSymbols(strPath, oldstr, newstr); + bool special = IsSpecial(urlData_.scheme); + if (urlData_.scheme == "file:") { + UrlData thisFileDate; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFileFlag; + if ((strPath[0] == '/') || (strPath[0] == '\\' && + flags_.test(static_cast(BitsetStatusFlag::BIT1)))) { + strPath = strPath.substr(1); + } + AnalysisFilePath(strPath, thisFileDate, thisFileFlag); + if (thisFileFlag.test(static_cast(BitsetStatusFlag::BIT6))) { + urlData_.path = thisFileDate.path; + flags_.set(static_cast(BitsetStatusFlag::BIT6)); + } + } else { + std::vector thisPath; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; + if ((strPath[0] == '/') || (strPath[0] == '\\' && + flags_.test(static_cast(BitsetStatusFlag::BIT1)))) { + strPath = strPath.substr(1); + } + AnalysisPath(strPath, thisPath, thisFlags, special); + if (thisFlags.test(static_cast(BitsetStatusFlag::BIT6))) { + urlData_.path = thisPath; + flags_.set(static_cast(BitsetStatusFlag::BIT6)); + } + } + } + + void SplitString(const std::string& input, std::string& strHost, std::string& port) + { + size_t strlen = input.size(); + for (size_t pos = 0; pos < strlen; pos++) { + if ((input[pos] == ':') || (input[pos] == '?') || (input[pos] == '#') || + (input[pos] == '/') || (input[pos] == '\\')) { + strHost = input.substr(0, pos); + if (input[pos] == ':') { + pos++; + port = input.substr(pos); + } + break; + } + } + } + + void URL::SetHost(const std::string& input) + { + if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { + return; + } + if (input.empty()) { + return; + } + std::string strHost = input; + std::string port = ""; + SplitString(input, strHost, port); + if (strHost.size() == 0) { + return; + } + bool special = IsSpecial(urlData_.scheme); + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> hostnameflags; + std::string thisHostname = ""; + AnalysisHost(strHost, thisHostname, hostnameflags, special); + if (hostnameflags.test(static_cast(BitsetStatusFlag::BIT4))) { + if ((urlData_.scheme == "file:") && (thisHostname == "localhost")) { + thisHostname = ""; + } + urlData_.host = thisHostname; + flags_.set(static_cast(BitsetStatusFlag::BIT4)); + } else { + return; + } + if (port.size() > 0) { + size_t strlen = port.size(); + for (size_t pos = 0; pos < strlen; pos++) { + if ((port[pos] == '?') || (port[pos] == '#') || (port[pos] == '/') || (port[pos] == '\\')) { + port = port.substr(0, pos); + break; + } + } + if (port.size() > 0) { + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; + UrlData thisport; + AnalysisPort(port, thisport, thisFlags); + if (thisFlags.test(static_cast(BitsetStatusFlag::BIT5))) { + flags_.set(static_cast(BitsetStatusFlag::BIT5)); + urlData_.port = thisport.port; + } + } + } + } + + void URL::SetPort(const std::string& input) + { + std::string port = input; + size_t portlen = port.size(); + for (size_t pos = 0; pos < portlen; pos++) { + if ((port[pos] == '?') || (port[pos] == '#') || (port[pos] == '/') || (port[pos] == '\\')) { + port = port.substr(0, pos); + break; + } + } + if (port.size() > 0) { + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; + UrlData thisport; + AnalysisPort(port, thisport, thisFlags); + if (thisFlags.test(static_cast(BitsetStatusFlag::BIT5))) { + flags_.set(static_cast(BitsetStatusFlag::BIT5)); + urlData_.port = thisport.port; + } + } + } + + void URL::SetSearch(const std::string& input) + { + std::string temp; + if (input.size() == 0) { + urlData_.query = ""; + flags_.set(static_cast(BitsetStatusFlag::BIT7), 0); + } else { + if (input[0] != '?') { + temp = "?"; + temp += input; + } else { + temp = input; + } + std::string oldstr = "#"; + std::string newstr = "%23"; + ReplaceSpecialSymbols(temp, oldstr, newstr); + AnalysisQuery(temp, urlData_.query, flags_); + } + } + + void URL::SetFragment(const std::string& input) + { + std::string temp; + if (input.size() == 0) { + urlData_.fragment = ""; + flags_.set(static_cast(BitsetStatusFlag::BIT8), 0); + } else { + if (input[0] != '#') { + temp = "#"; + temp += input; + } else { + temp = input; + } + AnalysisFragment(temp, urlData_.fragment, flags_); + } + } + + void URL::SetScheme(const std::string& input) + { + std::string strInput = input; + bool special = IsSpecial(urlData_.scheme); + bool inputIsSpecial = IsSpecial(input); + if ((special != inputIsSpecial) || ((input == "file") && + (flags_.test(static_cast(BitsetStatusFlag::BIT2)) || + flags_.test(static_cast(BitsetStatusFlag::BIT3)) || + flags_.test(static_cast(BitsetStatusFlag::BIT5))))) { + return; + } + std::string thisScheme = ""; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; + if (AnalysisScheme(strInput, thisScheme, thisFlags)) { + if (thisFlags.test(static_cast(BitsetStatusFlag::BIT1))) { + flags_.set(static_cast(BitsetStatusFlag::BIT1)); + } + urlData_.scheme = thisScheme; + } + } + + void URL::SetUsername(const std::string& input) + { + if (input.size() == 0) { + urlData_.username = ""; + flags_.set(static_cast(BitsetStatusFlag::BIT2), 0); + } else { + if (!input.empty()) { + std::string usname = input; + std::string oldstr = "@"; + std::string newstr = "%40"; + ReplaceSpecialSymbols(usname, oldstr, newstr); + oldstr = "/"; + newstr = "%2F"; + ReplaceSpecialSymbols(usname, oldstr, newstr); + urlData_.username = usname; + flags_.set(static_cast(BitsetStatusFlag::BIT2)); + } + } + } + + void URL::SetPassword(const std::string& input) + { + if (input.size() == 0) { + urlData_.password = ""; + flags_.set(static_cast(BitsetStatusFlag::BIT3), 0); + } else { + if (!input.empty()) { + std::string keyWord = input; + std::string oldstr = "@"; + std::string newstr = "%40"; + ReplaceSpecialSymbols(keyWord, oldstr, newstr); + oldstr = "/"; + newstr = "%2F"; + ReplaceSpecialSymbols(keyWord, oldstr, newstr); + urlData_.password = keyWord; + flags_.set(static_cast(BitsetStatusFlag::BIT3)); + } + } + } + + void URL::InitOnlyInput(std::string& input, UrlData& urlData, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) + { + if (input.empty()) { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + if (input.find(':') != std::string::npos) { + size_t pos = input.find(':'); + pos++; + std::string scheme = input.substr(0, pos); + if (!AnalysisScheme(scheme, urlData.scheme, flags)) { + return; + } + if (input.find('#') != std::string::npos) { + size_t i = input.find('#'); + std::string fragment = input.substr(i); + AnalysisFragment(fragment, urlData.fragment, flags); + input = input.substr(0, i); + } + if (input.find('?') != std::string::npos) { + size_t i = input.find('?'); + std::string query = input.substr(i); + AnalysisQuery(query, urlData.query, flags); + input = input.substr(0, i); + } + std::string str = input.substr(pos); + if (urlData.scheme == "file:") { + AnalysisFile(str, urlData, flags); + } else { + AnalysisHostAndPath(str, urlData, flags); + } + } else { + flags.set(static_cast(BitsetStatusFlag::BIT0)); + return; + } + } + + URLSearchParams::URLSearchParams(napi_env env) : env(env) + {} + std::wstring StrToWstr(const std::string& str) + { + char *p = setlocale(LC_ALL, ""); + if (p == nullptr) { + return L""; + } + std::wstring wstr = L""; + size_t len = str.size() + 1; + if (len > 0) { + auto wch = new wchar_t[len]; + mbstowcs(wch, str.c_str(), len); + wstr = wch; + delete[] wch; + p = setlocale(LC_ALL, ""); + if (p == nullptr) { + return L""; + } + return wstr; + } + return wstr; + } + + bool IsEscapeRange(const char charaEncode) + { + if ((charaEncode > 0 && charaEncode < '*') || + (charaEncode > '*' && charaEncode < '-') || + (charaEncode == '/') || + (charaEncode > '9' && charaEncode < 'A') || + (charaEncode > 'Z' && charaEncode < '_') || + (charaEncode == '`') || + (charaEncode > 'z')) { + return true; + } + return false; + } + + size_t CharToUnicode(std::string str, size_t &i) + { + size_t bytOfSpeChar = 3; // 3:Bytes of special characters in Linux + std::string subStr = str.substr(i, bytOfSpeChar); + i += 2; // 2:Searching for the number and number of keys and values + std::wstring wstr = StrToWstr(subStr.c_str()); + wchar_t wch = wstr[0]; + auto charaEncode = static_cast(wch); + return charaEncode; + } + std::string ReviseStr(std::string str, std::string *reviseChar) + { + const size_t lenStr = str.length(); + if (lenStr == 0) { + return ""; + } + std::string output = ""; + size_t numOfAscii = 128; // 128:Number of ASCII characters + size_t i = 0; + for (; i < lenStr; i++) { + auto charaEncode = static_cast(str[i]); + if (charaEncode < 0 || charaEncode >= numOfAscii) { + charaEncode = CharToUnicode(str, i); + } + if (charaEncode >= 0 && charaEncode < numOfAscii) { + // 2:Defines the escape range of ASCII characters + if (IsEscapeRange(charaEncode)) { + output += reviseChar[charaEncode]; + } else { + output += str.substr(i, 1); + } + } else if (charaEncode <= 0x000007FF) { // Convert the Unicode code into two bytes + std::string output1 = reviseChar[0x000000C0 | + (charaEncode / 64)]; // 64:Acquisition method of the first byte + std::string output2 = reviseChar[numOfAscii | + (charaEncode & 0x0000003F)]; // Acquisition method of the second byte + output += output1 + output2; + } else if ((charaEncode >= 0x0000E000) || + (charaEncode <= 0x0000D7FF)) { // Convert the Unicode code into three bytes + std::string output1 = reviseChar[0x000000E0 | + (charaEncode / 4096)]; // 4096:Acquisition method of the first byte + std::string output2 = reviseChar[numOfAscii | + ((charaEncode / 64) & 0x0000003F)]; // 64:method of the second byte + std::string output3 = reviseChar[numOfAscii | + (charaEncode & 0x0000003F)]; // Acquisition method of the third byte + output += output1 + output2 + output3; + } else { + const size_t charaEncode1 = static_cast(str[++i]) & 1023; // 1023:Convert codes + charaEncode = 65536 + (((charaEncode & 1023) << 10) | + charaEncode1); // 65536:Specific transcoding method + std::string output1 = reviseChar[0x000000F0 | + (charaEncode / 262144)]; // 262144:Acquisition method of the first byte + std::string output2 = reviseChar[numOfAscii | + ((charaEncode / 4096) & 0x0000003F)]; // 4096:Acquisition method of the second byte + std::string output3 = reviseChar[numOfAscii | + ((charaEncode / 64) & 0x0000003F)]; // 64:Acquisition method of the third byte + std::string output4 = reviseChar[numOfAscii | + (charaEncode & 0x0000003F)]; // Acquisition method of the fourth byte + output += output1 + output2 + output3 + output4; + } + } + return output; + } + + napi_value URLSearchParams::ToString() + { + std::string output = ""; + std::string reviseChar[256] = {""}; // 256:Array length + for (size_t i = 0; i < 256; ++i) { // 256:Array length + size_t j = i; + std::stringstream ioss; + std::string str1 = ""; + ioss << std::hex << j; + ioss >> str1; + transform(str1.begin(), str1.end(), str1.begin(), ::toupper); + if (i < 16) { // 16:Total number of 0-F + reviseChar[i] = '%' + ("0" + str1); + } else { + reviseChar[i] = '%' + str1; + } + } + reviseChar[0x20] = "+"; // 0x20:ASCII value of spaces + const size_t lenStr = searchParams.size(); + if (lenStr == 0) { + napi_value result = nullptr; + napi_create_string_utf8(env, output.c_str(), output.size(), &result); + return result; + } + std::string firstStrKey = ReviseStr(searchParams[0], reviseChar); + std::string firstStrValue = ReviseStr(searchParams[1], reviseChar); + output = firstStrKey + "=" + firstStrValue; + if (lenStr % 2 == 0) { // 2:Divisible by 2 + size_t i = 2; // 2:Initial Position + for (; i < lenStr; i += 2) { // 2:Searching for the number and number of keys and values + std::string strKey = ReviseStr(searchParams[i], reviseChar); + std::string strValue = ReviseStr(searchParams[i + 1], reviseChar); + output += +"&" + strKey + "=" + strValue; + } + } + napi_value result = nullptr; + napi_create_string_utf8(env, output.c_str(), output.size(), &result); + return result; + } + void URLSearchParams::HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it) + { + std::wstring::iterator iter = inputStr.begin(); + advance(iter, std::distance(iter, it)); + while (iter != inputStr.end()) { + char16_t ch = *iter; + if (!((ch & 0xF800) == 0xD800)) { + ++iter; + continue; + } else if ((ch & 0x400) != 0 || iter == inputStr.end() - 1) { + *iter = 0xFFFD; + } else { + char16_t dh = *(iter + 1); + if ((dh & 0xFC00) == 0xDC00) { + ++iter; + } else { + *iter = 0xFFFD; + } + } + ++iter; + } + } + std::string URLSearchParams::ToUSVString(std::string inputStr) + { + size_t strLen = strlen(inputStr.c_str()); + wchar_t *strPtr = nullptr; + std::wstring winput = L""; + int strSize = mbstowcs(strPtr, inputStr.c_str(), 0) + 1; + if (strSize > 0) { + strPtr = new wchar_t[strSize]; + mbstowcs(strPtr, inputStr.c_str(), strLen); + winput = strPtr; + } + const char *expr = "(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])"; + size_t exprLen = strlen(expr); + wchar_t *exprPtr = nullptr; + int exprSize = mbstowcs(exprPtr, expr, 0) + 1; + if (exprSize > 0) { + exprPtr = new wchar_t[exprSize]; + mbstowcs(exprPtr, expr, exprLen); + } + std::wregex wexpr(exprPtr); + delete[] exprPtr; + std::wsmatch result; + delete[] strPtr; + std::wstring::const_iterator iterStart = winput.begin(); + std::wstring::const_iterator iterEnd = winput.end(); + if (!regex_search(iterStart, iterEnd, result, wexpr)) { + return inputStr; + } + HandleIllegalChar(winput, result[0].first); + size_t inputLen = wcslen(winput.c_str()); + char *rePtr = nullptr; + std::string reStr = ""; + int reSize = wcstombs(rePtr, winput.c_str(), 0) + 1; + if (reSize > 0) { + rePtr = new char[reSize]; + if (memset_s(rePtr, reSize, 0, reSize) != 0) { + HILOG_ERROR("ToUSVString memset_s failed"); + delete[] rePtr; + return reStr; + } else { + wcstombs(rePtr, winput.c_str(), inputLen); + reStr = rePtr; + } + } + delete[] rePtr; + return reStr; + } + napi_value URLSearchParams::Get(napi_value buffer) + { + char *name = nullptr; + size_t nameSize = 0; + std::string temp = ""; + napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); + if (nameSize > 0) { + name = new char[nameSize + 1]; + napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); + temp = name; + } + std::string sname = ToUSVString(temp); + delete[] name; + napi_value result = nullptr; + if (searchParams.size() == 0) { + return result; + } + size_t size = searchParams.size() - 1; + for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values + if (searchParams[i] == sname) { + std::string str = searchParams[i + 1]; + napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &result); + return result; + } + } + return result; + } + napi_value URLSearchParams::GetAll(napi_value buffer) + { + char *name = nullptr; + size_t nameSize = 0; + std::string sname = ""; + napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); + if (nameSize > 0) { + name = new char[nameSize + 1]; + napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); + sname = ToUSVString(name); + } + delete[] name; + napi_value result = nullptr; + napi_value napiStr = nullptr; + NAPI_CALL(env, napi_create_array(env, &result)); + size_t flag = 0; + if (searchParams.size() == 0) { + return result; + } + size_t size = searchParams.size() - 1; + for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values + if (searchParams[i] == sname) { + napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &napiStr); + napi_status status = napi_set_element(env, result, flag, napiStr); + if (status != napi_ok) { + HILOG_INFO("set element error"); + } + flag++; + } + } + return result; + } + void URLSearchParams::Append(napi_value buffer, napi_value temp) + { + char *name = nullptr; + size_t nameSize = 0; + std::string tempName = ""; + std::string tempValue = ""; + napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); + if (nameSize > 0) { + name = new char[nameSize + 1]; + napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); + tempName = name; + } + char *value = nullptr; + size_t valueSize = 0; + napi_get_value_string_utf8(env, temp, nullptr, 0, &valueSize); + if (valueSize > 0) { + value = new char[valueSize + 1]; + napi_get_value_string_utf8(env, temp, value, valueSize + 1, &valueSize); + tempValue = value; + } + searchParams.push_back(tempName); + searchParams.push_back(tempValue); + delete[] name; + delete[] value; + } + void URLSearchParams::Delete(napi_value buffer) + { + char *name = nullptr; + size_t nameSize = 0; + std::string sname = ""; + napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); + if (nameSize > 0) { + name = new char[nameSize + 1]; + napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); + sname = ToUSVString(name); + } + delete[] name; + for (std::vector::iterator iter = searchParams.begin(); iter != searchParams.end();) { + if (*iter == sname) { + iter = searchParams.erase(iter, iter + 2); // 2:Searching for the number and number of keys and values + } else { + iter += 2; // 2:Searching for the number and number of keys and values + } + } + } + napi_value URLSearchParams::Entries() const + { + napi_value resend = nullptr; + napi_value firNapiStr = nullptr; + napi_value secNapiStr = nullptr; + napi_create_array(env, &resend); + if (searchParams.size() == 0) { + return resend; + } + size_t size = searchParams.size() - 1; + for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values + napi_value result = nullptr; + napi_create_array(env, &result); + + napi_create_string_utf8(env, searchParams[i].c_str(), searchParams[i].length(), &firNapiStr); + napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &secNapiStr); + napi_set_element(env, result, 0, firNapiStr); + napi_set_element(env, result, 1, secNapiStr); + napi_set_element(env, resend, i / 2, result); // 2:Find the number of keys + } + return resend; + } + void URLSearchParams::ForEach(napi_value function, napi_value thisVar) + { + if (searchParams.size() == 0) { + return; + } + size_t size = searchParams.size() - 1; + for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values + napi_value returnVal = nullptr; + size_t argc = 3; + napi_value global = nullptr; + napi_get_global(env, &global); + napi_value key = nullptr; + napi_create_string_utf8(env, searchParams[i].c_str(), strlen(searchParams[i].c_str()), &key); + napi_value value = nullptr; + napi_create_string_utf8(env, searchParams[i + 1].c_str(), strlen(searchParams[i + 1].c_str()), &value); + napi_value argv[3] = {key, value, thisVar}; + napi_call_function(env, global, function, argc, argv, &returnVal); + } + } + napi_value URLSearchParams::IsHas(napi_value name) const + { + char *buffer = nullptr; + size_t bufferSize = 0; + std::string buf = ""; + napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize); + if (bufferSize > 0) { + buffer = new char[bufferSize + 1]; + napi_get_value_string_utf8(env, name, buffer, bufferSize + 1, &bufferSize); + buf = buffer; + } + bool flag = false; + napi_value result = nullptr; + size_t lenStr = searchParams.size(); + for (size_t i = 0; i != lenStr; i += 2) { // 2:Searching for the number and number of keys and values + if (searchParams[i] == buf) { + flag = true; + napi_get_boolean(env, flag, &result); + return result; + } + } + delete []buffer; + napi_get_boolean(env, flag, &result); + return result; + } + void URLSearchParams::Set(napi_value name, napi_value value) + { + char *buffer0 = nullptr; + size_t bufferSize0 = 0; + std::string cppName = ""; + std::string cppValue = ""; + napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize0); + if (bufferSize0 > 0) { + buffer0 = new char[bufferSize0 + 1]; + napi_get_value_string_utf8(env, name, buffer0, bufferSize0 + 1, &bufferSize0); + cppName = buffer0; + delete[] buffer0; + } + char *buffer1 = nullptr; + size_t bufferSize1 = 0; + napi_get_value_string_utf8(env, value, nullptr, 0, &bufferSize1); + if (bufferSize1 > 0) { + buffer1 = new char[bufferSize1 + 1]; + napi_get_value_string_utf8(env, value, buffer1, bufferSize1 + 1, &bufferSize1); + cppValue = buffer1; + delete[] buffer1; + } + bool flag = false; + for (std::vector::iterator it = searchParams.begin(); it < searchParams.end() - 1;) { + if (*it == cppName) { + if (!flag) { + *(it + 1) = cppValue; + flag = true; + it += 2; // 2:Searching for the number and number of keys and values + } else { + it = searchParams.erase(it, it + 2); // 2:Searching for the number and number of keys and values + } + } else { + it += 2; // 2:Searching for the number and number of keys and values + } + } + if (!flag) { + searchParams.push_back(cppName); + searchParams.push_back(cppValue); + } + } + void URLSearchParams::Sort() + { + unsigned int len = searchParams.size(); + if (len <= 2 && (len % 2 != 0)) { // 2: Iterate over key-value pairs + return; + } + unsigned int i = 0; + for (; i < len - 2; i += 2) { // 2:Iterate over key-value pairs + unsigned int j = i + 2; // 2:Iterate over key-value pairs + for (; j < len; j += 2) { // 2:Iterate over key-value pairs + bool tmp = (searchParams[i] > searchParams[j]); + if (tmp) { + const std::string curKey = searchParams[i]; + const std::string curVal = searchParams[i + 1]; + searchParams[i] = searchParams[j]; + searchParams[i + 1] = searchParams[j + 1]; + searchParams[j] = curKey; + searchParams[j + 1] = curVal; + } + } + } + } + napi_value URLSearchParams::IterByKeys() + { + std::vector toKeys; + napi_value result = nullptr; + napi_value napiStr = nullptr; + napi_create_array(env, &result); + size_t stepSize = 2; // 2:Searching for the number and number of keys and values + size_t lenStr = searchParams.size(); + if (lenStr % 2 == 0) { // 2:Get the number of values + for (auto it = searchParams.begin(); it != searchParams.end(); it += stepSize) { + toKeys.push_back(*it); + } + size_t lenToKeys = toKeys.size(); + for (size_t i = 0; i < lenToKeys; i++) { + napi_create_string_utf8(env, toKeys[i].c_str(), toKeys[i].length(), &napiStr); + napi_set_element(env, result, i, napiStr); + } + } + return result; + } + napi_value URLSearchParams::IterByValues() + { + std::vector toKeys; + napi_value result = nullptr; + napi_value napiStr = nullptr; + napi_create_array(env, &result); + size_t stepSize = 2; // 2:Searching for the number and number of keys and values + size_t lenStr = searchParams.size(); + if (lenStr % 2 == 0) { // 2:Get the number of values + for (auto it = searchParams.begin(); + it != searchParams.end(); + it += stepSize) { + toKeys.push_back(*(it + 1)); + } + size_t lenToKeys = toKeys.size(); + for (size_t i = 0; i < lenToKeys; i++) { + napi_create_string_utf8(env, toKeys[i].c_str(), toKeys[i].length(), &napiStr); + napi_set_element(env, result, i, napiStr); + } + } + return result; + } + void URLSearchParams::SetArray(const std::vector vec) + { + searchParams = vec; + } + napi_value URLSearchParams::GetArray() const + { + napi_value arr = nullptr; + napi_create_array(env, &arr); + size_t length = searchParams.size(); + for (size_t i = 0; i < length; i++) { + napi_value result = nullptr; + napi_create_string_utf8(env, searchParams[i].c_str(), searchParams[i].size(), &result); + napi_set_element(env, arr, i, result); + } + return arr; + } +} // namespace \ No newline at end of file diff --git a/api/js_url.h b/api/js_url.h new file mode 100755 index 0000000000000000000000000000000000000000..f306f3e8c7b9da42bc496b331267c78c07ca100b --- /dev/null +++ b/api/js_url.h @@ -0,0 +1,120 @@ + /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef COMPILERUNTIME_JS_API_URL_H +#define COMPILERUNTIME_JS_API_URL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS::Api { + enum class BitsetStatusFlag { + BIT0 = 0, // 0:Bit 0 Set to true,The URL analysis failed + BIT1 = 1, // 1:Bit 1 Set to true,The protocol is the default protocol + BIT2 = 2, // 2:Bit 2 Set to true,The URL has username + BIT3 = 3, // 3:Bit 3 Set to true,The URL has password + BIT4 = 4, // 4:Bit 4 Set to true,The URL has hostname + BIT5 = 5, // 5:Bit 5 Set to true,The URL Port is the specially + BIT6 = 6, // 6:Bit 6 Set to true,The URL has pathname + BIT7 = 7, // 7:Bit 7 Set to true,The URL has query + BIT8 = 8, // 8:Bit 8 Set to true,The URL has fragment + BIT9 = 9, // 9:Bit 9 Set to true,The URL Can not be base + BIT10 = 10, // 10:Bit 10 Set to true,The host is IPV6 + BIT_STATUS_11 = 11 // 11:Each bit of a BIT represents a different parsing state. + }; + + struct UrlData { + int port = -1; + std::vector path; + std::string password = ""; + std::string scheme = ""; + std::string query = ""; + std::string username = ""; + std::string fragment = ""; + std::string host = ""; + }; + + class URL { + public: + URL(napi_env env, const std::string& input); + URL(napi_env env, const std::string& input, const std::string& base); + URL(napi_env env, const std::string& input, const URL& base); + + napi_value GetHostname() const; + void SetHostname(const std::string& input); + void SetUsername(const std::string& input); + void SetPassword(const std::string& input); + void SetScheme(const std::string& input); + void SetFragment(const std::string& input); + void SetSearch(const std::string& input); + void SetHost(const std::string& input); + void SetPort(const std::string& input); + void SetHref(const std::string& input); + void SetPath(const std::string& input); + + napi_value GetSearch() const; + napi_value GetUsername() const; + napi_value GetPassword() const; + napi_value GetFragment() const; + napi_value GetScheme() const; + napi_value GetPath() const; + napi_value GetPort() const; + napi_value GetOnOrOff() const; + napi_value GetIsIpv6() const; + napi_value GetHost() const; + + static void InitOnlyInput(std::string& input, UrlData& urlData, + std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags); + virtual ~URL() {} + private: + UrlData urlData_; + std::bitset(BitsetStatusFlag::BIT_STATUS_11)> flags_; + // bitset<11>:Similar to bool array, each bit status represents the real-time status of current URL parsing + napi_env env_ = nullptr; + }; + + class URLSearchParams { + public: + explicit URLSearchParams(napi_env env); + virtual ~URLSearchParams() {} + napi_value IsHas(napi_value name) const; + napi_value Get(napi_value buffer); + napi_value GetAll(napi_value buffer); + void Append(napi_value buffer, napi_value temp); + void Delete(napi_value buffer); + void ForEach(napi_value function, napi_value thisVar); + napi_value Entries() const; + void Set(napi_value name, napi_value value); + void Sort(); + napi_value ToString(); + napi_value IterByKeys(); + napi_value IterByValues(); + void SetArray(std::vector input); + napi_value GetArray() const; + std::vector StringParmas(std::string Stringpar); + private: + std::string ToUSVString(std::string inputStr); + void HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it); + std::vector searchParams; + napi_env env; + }; +} // namespace +#endif /* COMPILERUNTIME_JS_API_URL_H */ diff --git a/api/native_module_api.cpp b/api/native_module_api.cpp new file mode 100755 index 0000000000000000000000000000000000000000..1a2b1abbad5ef6d84c3055a50679132ded7bd917 --- /dev/null +++ b/api/native_module_api.cpp @@ -0,0 +1,1183 @@ + /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "js_uri.h" +#include "js_url.h" +#include "utils/log.h" + +extern const char _binary_js_api_js_start[]; +extern const char _binary_js_api_js_end[]; +namespace OHOS::Api { + napi_value g_uriClass = nullptr; + static napi_value UriConstructor(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + void *data = nullptr; + size_t argc = 1; + napi_value argv[1] = { 0 }; + Uri *object = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + if (valuetype == napi_string) { + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + object = new Uri(env, type); + delete[] type; + } else { + napi_throw_error(env, nullptr, "parameter type is error"); + } + NAPI_CALL(env, napi_wrap(env, thisVar, object, + [](napi_env env, void *data, void *hint) { + auto object = (Uri*)data; + if (object != nullptr) { + delete object; + } + }, nullptr, nullptr)); + return thisVar; + } + + static napi_value Normalize(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string normalizeUri = muri->Normalize(); + size_t argc = 1; + napi_value args[1] = { 0 }; + napi_value result = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, normalizeUri.c_str(), normalizeUri.size(), args)); + NAPI_CALL(env, napi_new_instance(env, g_uriClass, argc, args, &result)); + return result; + } + + static napi_value Equals(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + size_t argc = 1; + napi_value argv[1] = { 0 }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + Uri *other = nullptr; + NAPI_CALL(env, napi_unwrap(env, argv[0], (void**)&other)); + + bool flag = muri->Equals(*other); + NAPI_CALL(env, napi_get_boolean(env, flag, &result)); + return result; + } + + static napi_value IsAbsolute(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + bool flag = muri->IsAbsolute(); + NAPI_CALL(env, napi_get_boolean(env, flag, &result)); + return result; + } + + static napi_value IsFailed(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->IsFailed(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value UriToString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->ToString(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetScheme(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetScheme(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetAuthority(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetAuthority(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetSsp(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetSsp(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetUserinfo(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetUserinfo(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetHost(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetHost(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetPort(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetPort(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetPath(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetPath(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetQuery(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetQuery(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static napi_value GetFragment(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + Uri *muri = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&muri)); + std::string temp = muri->GetFragment(); + size_t templen = temp.size(); + NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); + return result; + } + + static void UrlStructor(napi_env &env, napi_callback_info &info, URL *&object) + { + napi_value thisVar = nullptr; + size_t argc = 2; + napi_value argv[2] = { 0 }; + void *data = nullptr; + napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data); + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + napi_valuetype valuetype1; + napi_valuetype valuetype2; + std::string input = ""; + napi_typeof(env, argv[0], &valuetype1); + if (valuetype1 == napi_string) { + char *tem = nullptr; + size_t temlen = 0; + napi_get_value_string_utf8(env, argv[0], nullptr, 0, &temlen); + if (temlen > 0) { + tem = new char[temlen + 1]; + napi_get_value_string_utf8(env, argv[0], tem, temlen + 1, &temlen); + input = tem; + delete[] tem; + } + napi_typeof(env, argv[1], &valuetype2); + if (valuetype2 == napi_string) { + std::string base = ""; + char *type1 = nullptr; + size_t typelen1 = 0; + napi_get_value_string_utf8(env, argv[1], nullptr, 0, &typelen1); + if (typelen1 > 0) { + type1 = new char[typelen1 + 1]; + napi_get_value_string_utf8(env, argv[1], type1, typelen1 + 1, &typelen1); + base = type1; + delete[] type1; + } + object = new URL(env, input, base); + } else if (valuetype2 == napi_object) { + URL *temp = nullptr; + napi_unwrap(env, argv[1], (void**)&temp); + object = new URL(env, input, *temp); + } else { + HILOG_INFO("secondParameter error"); + } + } else { + HILOG_INFO("firstParameter error"); + } + return; + } + + static napi_value UrlConstructor(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + void *data = nullptr; + size_t argc = 0; + napi_value argv[2] = { 0 }; + URL *object = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data)); + if (argc == 1) { + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + if (valuetype == napi_string) { + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + delete[] type; + } + object = new URL(env, input); + } else { + HILOG_INFO("Parameter error"); + } + } else if (argc == 2) { // 2:When the input parameter is set to 2 + UrlStructor(env, info, object); + } + napi_wrap( + env, thisVar, object, + [](napi_env env, void *data, void *hint) { + auto object = (URL*)data; + if (object != nullptr) { + delete object; + } + }, + nullptr, nullptr); + return thisVar; + } + + static napi_value GetHostname(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetHostname(); + return retVal; + } + + static napi_value GetSearch(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetSearch(); + return retVal; + } + + static napi_value GetUsername(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetUsername(); + return retVal; + } + + static napi_value GetPassword(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetPassword(); + return retVal; + } + + static napi_value GetUrlFragment(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetFragment(); + return retVal; + } + + static napi_value GetUrlScheme(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetScheme(); + return retVal; + } + + static napi_value GetUrlPort(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetPort(); + return retVal; + } + + static napi_value GetUrlHost(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetHost(); + return retVal; + } + + static napi_value GetUrlPath(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetPath(); + return retVal; + } + + static napi_value GetOnOrOff(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetOnOrOff(); + return retVal; + } + + static napi_value GetIsIpv6(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetIsIpv6(); + return retVal; + } + + static napi_value SetHref(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetHref(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetHostname(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetHostname(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUrlPort(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetPort(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUrlHost(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetHost(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetSearch(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetSearch(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUrlScheme(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetScheme(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUrlFragment(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetFragment(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUsername(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetUsername(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetUrlPath(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetPath(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SetPassword(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + char *type = nullptr; + size_t typelen = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); + if (typelen > 0) { + type = new char[typelen + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); + input = type; + } + if (type != nullptr) { + delete[] type; + type = nullptr; + } + URL *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetPassword(input); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value SeachParamsConstructor(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + void *data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data)); + auto object = new URLSearchParams(env); + napi_wrap( + env, thisVar, object, + [](napi_env env, void *data, void *hint) { + auto obj = (URLSearchParams*)data; + if (obj != nullptr) { + delete obj; + } + }, + nullptr, nullptr); + return thisVar; + } + + static napi_value SetArray(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + uint32_t length = 0; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + napi_get_array_length(env, argv[0], &length); + std::vector vec; + size_t arraySize = 0; + napi_value napiStr = nullptr; + for (size_t i = 0; i < length; i++) { + char *cstr = nullptr; + napi_get_element(env, argv[0], i, &napiStr); + napi_get_value_string_utf8(env, napiStr, nullptr, 0, &arraySize); + if (arraySize > 0) { + cstr = new char[arraySize + 1]; + napi_get_value_string_utf8(env, napiStr, cstr, arraySize + 1, &arraySize); + vec.push_back(cstr); + delete []cstr; + cstr = nullptr; + } else { + vec.push_back(""); + } + } + URLSearchParams *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + murl->SetArray(vec); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; + } + + static napi_value GetArray(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + URLSearchParams *murl = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); + napi_value retVal = murl->GetArray(); + return retVal; + } + + static napi_value Get(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 1; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + if (argc != 1) { + HILOG_INFO("One arg needs to be specified"); + return nullptr; + } + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->Get(args); + return result; + } + + static napi_value GetAll(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 1; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + if (argc != 1) { + HILOG_INFO("One arg needs to be specified"); + return nullptr; + } + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->GetAll(args); + return result; + } + + static napi_value Append(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 2; + napi_value args[2] = { 0 }; + void *data = nullptr; + napi_get_cb_info(env, info, &argc, args, &thisVar, &data); + if (argc != 2) { // 2:If the input parameter is not set to 2, + HILOG_INFO("Two args needs to be specified"); + return nullptr; + } + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + object->Append(args[0], args[1]); + return nullptr; + } + + static napi_value Delete(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 1; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + if (argc != 1) { + HILOG_INFO("One arg needs to be specified"); + return nullptr; + } + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + object->Delete(args); + return nullptr; + } + + static napi_value ForEach(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 1; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + object->ForEach(args, thisVar); + return nullptr; + } + + static napi_value Entries(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 0; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->Entries(); + return result; + } + + static napi_value IsHas(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 1; + napi_value args = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); + URLSearchParams *object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->IsHas(args); + return result; + } + + static napi_value Set(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 2; + napi_value args[2] = { 0 }; + napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + object->Set(args[0], args[1]); + return nullptr; + } + + static napi_value Sort(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 0; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + object->Sort(); + return nullptr; + } + + static napi_value ToString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 0; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->ToString(); + return result; + } + + static napi_value IterByKeys(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 0; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->IterByKeys(); + return result; + } + + static napi_value IterByValues(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t argc = 0; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); + URLSearchParams *object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = object->IterByValues(); + return result; + } + + static void IsPlusSign(size_t &strLastPos, size_t &iteaor, std::string &buf, std::string &stringParm) + { + if (strLastPos < iteaor) { + buf += stringParm.substr(strLastPos, iteaor - strLastPos); + } + buf += ""; + strLastPos = iteaor + 1; + return; + } + static void IsEqualSign(size_t &strLastPos, size_t &iteaor, + std::string &buf, std::string &stringParm, std::vector &seachParasVec) + { + if (strLastPos < iteaor) { + buf += stringParm.substr(strLastPos, iteaor - strLastPos); + } + seachParasVec.push_back(buf); + buf = ""; + strLastPos = iteaor + 1; + return; + } + + static void IsAddressSign(size_t &strLastPos, size_t &iteaor, std::string &buf, + std::string &stringParm, std::vector &seachParasVec) + { + if (strLastPos < iteaor) { + buf += stringParm.substr(strLastPos, iteaor - strLastPos); + } + seachParasVec.push_back(buf); + return; + } + static void DealParmsString(size_t &strLastPos, size_t &iteaor, std::string &buf, + std::string &stringParm, std::vector &seachParasVec) + { + if (strLastPos < iteaor) { + buf += stringParm.substr(strLastPos, iteaor - strLastPos); + } + seachParasVec.push_back(buf); + } + static void IsEqualCode(size_t &strStartPos, size_t &iteaor, size_t &strLastPos) + { + if (strStartPos == iteaor) { + strLastPos = iteaor + 1; + strStartPos = iteaor + 1; + } + return; + } + static std::vector StringParsing(std::string stringParm) + { + std::vector seachParasVec; + size_t strStartPos = 0; + size_t strLastPos = 0; + bool isHasSpace = false; + std::string buf = ""; + size_t iteaor = 0; + for (iteaor = 0; iteaor < stringParm.length(); iteaor++) { + char code = stringParm[iteaor]; + switch (code) { + case '&': + { + IsEqualCode(strStartPos, iteaor, strLastPos); + IsAddressSign(strLastPos, iteaor, buf, stringParm, seachParasVec); + if (!isHasSpace) { + seachParasVec.push_back(""); + } + isHasSpace = false; + buf = ""; + strLastPos = iteaor + 1; + strStartPos = iteaor + 1; + break; + } + case '=': + { + if (isHasSpace) { + break; + } + IsEqualSign(strLastPos, iteaor, buf, stringParm, seachParasVec); + isHasSpace = true; + break; + } + case '+': + IsPlusSign(strLastPos, iteaor, buf, stringParm); + break; + default:break; + } + } + if (strStartPos == iteaor) { + return seachParasVec; + } + DealParmsString(strLastPos, iteaor, buf, stringParm, seachParasVec); + if (!isHasSpace) { + seachParasVec.push_back(""); + } + return seachParasVec; + } + + static napi_value StringParmas(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value argv[1] = {0}; + size_t argc = 1; + std::string input = ""; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + char *type = nullptr; + size_t typelen = 0; + napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen); + if (typelen > 0) { + type = new char[typelen + 1]; + napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen); + input = type; + delete[] type; + } + std::vector seachParasmsString; + seachParasmsString = StringParsing(input); + napi_value arr = nullptr; + napi_create_array(env, &arr); + for (size_t i = 0; i < seachParasmsString.size(); i++) { + napi_value result = nullptr; + napi_create_string_utf8(env, seachParasmsString[i].c_str(), seachParasmsString[i].size(), &result); + napi_set_element(env, arr, i, result); + } + return arr; + } + + static napi_value SeachParamsInit(napi_env env, napi_value exports) + { + const char *seachParamsClassName = "URLSearchParams"; + napi_value seachParamsInitClass = nullptr; + static napi_property_descriptor UrlDesc[] = { + DECLARE_NAPI_FUNCTION("has", IsHas), + DECLARE_NAPI_FUNCTION("set", Set), + DECLARE_NAPI_FUNCTION("sort", Sort), + DECLARE_NAPI_FUNCTION("toString", ToString), + DECLARE_NAPI_FUNCTION("keys", IterByKeys), + DECLARE_NAPI_FUNCTION("values", IterByValues), + DECLARE_NAPI_FUNCTION("get", Get), + DECLARE_NAPI_FUNCTION("getAll", GetAll), + DECLARE_NAPI_FUNCTION("append", Append), + DECLARE_NAPI_FUNCTION("delete", Delete), + DECLARE_NAPI_FUNCTION("forEach", ForEach), + DECLARE_NAPI_FUNCTION("entries", Entries), + DECLARE_NAPI_GETTER_SETTER("array", GetArray, SetArray), + }; + NAPI_CALL(env, napi_define_class(env, seachParamsClassName, strlen(seachParamsClassName), + SeachParamsConstructor, nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]), + UrlDesc, &seachParamsInitClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("URLSearchParams1", seachParamsInitClass) + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; + }; + + static napi_value UrlInit(napi_env env, napi_value exports) + { + const char *urlClassName = "Url"; + napi_value urlClass = nullptr; + static napi_property_descriptor UrlDesc[] = { + DECLARE_NAPI_GETTER_SETTER("hostname", GetHostname, SetHostname), + DECLARE_NAPI_FUNCTION("href", SetHref), + DECLARE_NAPI_GETTER_SETTER("search", GetSearch, SetSearch), + DECLARE_NAPI_GETTER_SETTER("username", GetUsername, SetUsername), + DECLARE_NAPI_GETTER_SETTER("password", GetPassword, SetPassword), + DECLARE_NAPI_GETTER_SETTER("host", GetUrlHost, SetUrlHost), + DECLARE_NAPI_GETTER_SETTER("hash", GetUrlFragment, SetUrlFragment), + DECLARE_NAPI_GETTER_SETTER("protocol", GetUrlScheme, SetUrlScheme), + DECLARE_NAPI_GETTER_SETTER("pathname", GetUrlPath, SetUrlPath), + DECLARE_NAPI_GETTER_SETTER("port", GetUrlPort, SetUrlPort), + DECLARE_NAPI_GETTER("onOrOff", GetOnOrOff), + DECLARE_NAPI_GETTER("GetIsIpv6", GetIsIpv6), + }; + NAPI_CALL(env, napi_define_class(env, urlClassName, strlen(urlClassName), UrlConstructor, + nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]), UrlDesc, &urlClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("Url", urlClass) + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; + } + + static napi_value UriInit(napi_env env, napi_value exports) + { + const char *uriClassName = "uri"; + napi_value uriClass = nullptr; + static napi_property_descriptor uriDesc[] = { + DECLARE_NAPI_FUNCTION("normalize", Normalize), + DECLARE_NAPI_FUNCTION("equals", Equals), + DECLARE_NAPI_FUNCTION("isAbsolute", IsAbsolute), + DECLARE_NAPI_FUNCTION("toString", UriToString), + DECLARE_NAPI_GETTER("scheme", GetScheme), + DECLARE_NAPI_GETTER("authority", GetAuthority), + DECLARE_NAPI_GETTER("ssp", GetSsp), + DECLARE_NAPI_GETTER("userinfo", GetUserinfo), + DECLARE_NAPI_GETTER("host", GetHost), + DECLARE_NAPI_GETTER("port", GetPort), + DECLARE_NAPI_GETTER("path", GetPath), + DECLARE_NAPI_GETTER("query", GetQuery), + DECLARE_NAPI_GETTER("fragment", GetFragment), + DECLARE_NAPI_GETTER("isFailed", IsFailed), + }; + NAPI_CALL(env, napi_define_class(env, uriClassName, strlen(uriClassName), UriConstructor, + nullptr, sizeof(uriDesc) / sizeof(uriDesc[0]), uriDesc, &uriClass)); + g_uriClass = uriClass; + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("Uri", uriClass) + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; + } + + static napi_value Init(napi_env env, napi_value exports) + { + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("stringParmas", StringParmas), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + SeachParamsInit(env, exports); + UrlInit(env, exports); + UriInit(env, exports); + return exports; + } + + extern "C" + __attribute__((visibility("default"))) void NAPI_api_GetJSCode(const char **buf, int *bufLen) + { + if (buf != nullptr) { + *buf = _binary_js_api_js_start; + } + + if (bufLen != nullptr) { + *bufLen = _binary_js_api_js_end - _binary_js_api_js_start; + } + } + + static napi_module ApiModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "api", + .nm_priv = ((void*)0), + .reserved = {0}, + }; + extern "C" __attribute__((constructor)) void RegisterModule() + { + napi_module_register(&ApiModule); + } +} // namespace \ No newline at end of file diff --git a/convertxml/BUILD.gn b/convertxml/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..a2ac7c536b7250ae16d2459827d607085065270f --- /dev/null +++ b/convertxml/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +base_output_path = get_label_info(":js_convertxml", "target_out_dir") +js_xml_obj_path = base_output_path + "/convertxml.o" +gen_js_obj("js_convertxml") { + input = "//base/compileruntime/js_api_module/convertxml/js_convertxml.js" + output = js_xml_obj_path +} + +ohos_shared_library("convertxml") { + include_dirs = [ + "//third_party/icu/icu4c/source/common", + "//third_party/node/src", + "//third_party/libxml2/include", + "//foundation/ace/napi/interfaces/kits", + "//base/compileruntime/js_api_module/convertxml", + ] + + sources = [ + "js_convertxml.cpp", + "native_module_convertxml.cpp", + ] + + deps = [ + ":js_convertxml", + "//base/compileruntime/js_api_module/convertxml/:js_convertxml", + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/icu/icu4c:static_icuuc", + "//third_party/libxml2:xml2", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } + subsystem_name = "ccruntime" + part_name = "jsapi_api" + + relative_install_dir = "module" +} + +group("convertxml_packages") { + deps = [ ":convertxml" ] +} diff --git a/convertxml/js_convertxml.cpp b/convertxml/js_convertxml.cpp new file mode 100755 index 0000000000000000000000000000000000000000..ba50cbd6fdeee1240cf77daa09e9de77eeb699be --- /dev/null +++ b/convertxml/js_convertxml.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "js_convertxml.h" +#include "securec.h" +#include "utils/log.h" + +ConvertXml::ConvertXml(napi_env env): env_(env) +{ + m_SpaceType = SpaceType::T_INIT; + m_strSpace = ""; + m_iSpace = 0; +} +std::string ConvertXml::GetNodeType(xmlElementType enumType) +{ + std::string strResult = ""; + switch (enumType) { + case xmlElementType::XML_ELEMENT_NODE: + strResult = "element"; + break; + case xmlElementType::XML_ATTRIBUTE_NODE: + strResult = "attribute"; + break; + case xmlElementType::XML_TEXT_NODE: + strResult = "text"; + break; + case xmlElementType::XML_CDATA_SECTION_NODE: + strResult = "cdata"; + break; + case xmlElementType::XML_ENTITY_REF_NODE: + strResult = "entity_ref"; + break; + case xmlElementType::XML_ENTITY_NODE: + strResult = "entity"; + break; + case xmlElementType::XML_PI_NODE: + strResult = "instruction"; + break; + case xmlElementType::XML_COMMENT_NODE: + strResult = "comment"; + break; + case xmlElementType::XML_DOCUMENT_NODE: + strResult = "document"; + break; + case xmlElementType::XML_DOCUMENT_TYPE_NODE: + strResult = "document_type"; + break; + case xmlElementType::XML_DOCUMENT_FRAG_NODE: + strResult = "document_frag"; + break; + case xmlElementType::XML_DTD_NODE: + strResult = "doctype"; + break; +#ifdef LIBXML_DOCB_ENABLED + case xmlElementType::XML_DOCB_DOCUMENT_NODE: + strResult = "docb_document"; + break; +#endif + default: + break; + } + return strResult; +} + +void ConvertXml::SetKeyValue(napi_value &object, std::string strKey, std::string strValue) +{ + napi_value attrValue = nullptr; + napi_create_string_utf8(env_, strValue.c_str(), NAPI_AUTO_LENGTH, &attrValue); + napi_set_named_property(env_, object, strKey.c_str(), attrValue); +} +std::string ConvertXml::Trim(std::string strXmltrim) +{ + if (strXmltrim.empty()) { + return ""; + } + size_t i = 0; + size_t strlen = strXmltrim.size(); + for (; i < strlen;) { + if (strXmltrim[i] == ' ') { + i++; + } else { + break; + } + } + strXmltrim = strXmltrim.substr(i); + strlen = strXmltrim.size(); + for (i = strlen - 1; i != 0; i--) { + if (strXmltrim[i] == ' ') { + strXmltrim.pop_back(); + } else { + break; + } + } + return strXmltrim; +} + +void ConvertXml::GetPrevNodeList(xmlNodePtr curNode) +{ + while (curNode->prev != nullptr) { + curNode = curNode->prev; + napi_value elementsObject = nullptr; + napi_create_object(env_, &elementsObject); + SetKeyValue(elementsObject, m_Options.type, GetNodeType(curNode->type)); + if (curNode->type == xmlElementType::XML_PI_NODE) { + SetKeyValue(elementsObject, m_Options.name, (char*)curNode->name); + SetKeyValue(elementsObject, m_Options.instruction, (const char*)xmlNodeGetContent(curNode)); + } + if (curNode->type == xmlElementType::XML_COMMENT_NODE) { + SetKeyValue(elementsObject, m_Options.comment, (const char*)xmlNodeGetContent(curNode)); + } + if (curNode->type == xmlElementType::XML_DTD_NODE) { + SetKeyValue(elementsObject, m_Options.doctype, (char*)curNode->name); + } + m_prevObj.push_back(elementsObject); + } +} + +void ConvertXml::SetAttributes(xmlNodePtr curNode, napi_value &elementsObject) +{ + xmlAttr *attr = curNode->properties; + if (attr && !m_Options.ignoreAttributes) { + napi_value attrTitleObj = nullptr; + napi_create_object(env_, &attrTitleObj); + while (attr) { + SetKeyValue(attrTitleObj, (const char*)attr->name, (const char*)attr->children->content); + attr = attr->next; + } + napi_set_named_property(env_, elementsObject, m_Options.attributes.c_str(), attrTitleObj); + } +} + +void ConvertXml::SetXmlElementType(xmlNodePtr curNode, napi_value &elementsObject) +{ + if (curNode->type == xmlElementType::XML_PI_NODE && !m_Options.ignoreInstruction) { + SetKeyValue(elementsObject, m_Options.instruction.c_str(), (const char*)xmlNodeGetContent(curNode)); + } else if (curNode->type == xmlElementType::XML_COMMENT_NODE && !m_Options.ignoreComment) { + SetKeyValue(elementsObject, m_Options.comment.c_str(), (const char*)xmlNodeGetContent(curNode)); + } else if (curNode->type == xmlElementType::XML_CDATA_SECTION_NODE && !m_Options.ignoreCdata) { + SetKeyValue(elementsObject, m_Options.cdata, (const char*)xmlNodeGetContent(curNode)); + } +} +void ConvertXml::SetNodeInfo(xmlNodePtr curNode, napi_value &elementsObject) +{ + if (curNode->type == xmlElementType::XML_PI_NODE) { + SetKeyValue(elementsObject, m_Options.type, m_Options.instruction); + } else { + SetKeyValue(elementsObject, m_Options.type, GetNodeType(curNode->type)); + } + SetKeyValue(elementsObject, m_Options.type, GetNodeType(curNode->type)); + if ((curNode->type != xmlElementType::XML_COMMENT_NODE) && + (curNode->type != xmlElementType::XML_CDATA_SECTION_NODE)) { + SetKeyValue(elementsObject, m_Options.name, (char*)curNode->name); + } +} + +void ConvertXml::SetEndInfo(xmlNodePtr curNode, napi_value &elementsObject, bool &bFlag, bool &bText, int32_t index) +{ + SetKeyValue(elementsObject, m_Options.type, GetNodeType(curNode->type)); + if (curNode->type == xmlElementType::XML_ELEMENT_NODE) { + SetKeyValue(elementsObject, m_Options.name.c_str(), (const char*)curNode->name); + bFlag = true; + } else if (curNode->type == xmlElementType::XML_TEXT_NODE) { + if (m_Options.trim) { + SetKeyValue(elementsObject, m_Options.text, Trim((const char*)xmlNodeGetContent(curNode))); + } else { + SetKeyValue(elementsObject, m_Options.text, (const char*)xmlNodeGetContent(curNode)); + } + if (!m_Options.ignoreText) { + bFlag = true; + } + if (index != 0) { + bText = false; + } + } +} + +void ConvertXml::SetPrevInfo(napi_value &recvElement, int flag, int32_t &index1) +{ + if (!m_prevObj.empty() && !flag) { + for (int i = (m_prevObj.size() - 1); i >= 0; --i) { + napi_set_element(env_, recvElement, index1++, m_prevObj[i]); + } + } +} + +void ConvertXml::GetXMLInfo(xmlNodePtr curNode, napi_value &object, int flag) +{ + napi_value elements = nullptr; + napi_create_array(env_, &elements); + napi_value recvElement; + napi_create_array(env_, &recvElement); + xmlNodePtr pNode = curNode; + int32_t index = 0; + int32_t index1 = 0; + bool bFlag = false; + bool bText = true; + while (pNode != nullptr) { + bFlag = false; + bText = true; + napi_value elementsObject = nullptr; + napi_create_object(env_, &elementsObject); + if (flag == 0 || (index % 2 != 0)) { // 2:pNode + SetNodeInfo(pNode, elementsObject); + } + SetAttributes(pNode, elementsObject); + napi_value tempElement = nullptr; + napi_create_array(env_, &tempElement); + napi_value elementObj = nullptr; + napi_create_object(env_, &elementObj); + if (xmlNodeGetContent(pNode) != nullptr) { + if (pNode->children != nullptr) { + curNode = pNode->children; + GetXMLInfo(curNode, elementsObject, 1); + bFlag = true; + } else if (index % 2 != 0) { // 2:pNode + SetXmlElementType(pNode, elementsObject); + bFlag = true; + } else if (pNode->next == nullptr) { + SetEndInfo(pNode, elementsObject, bFlag, bText, index); + } + } + SetPrevInfo(recvElement, flag, index1); + if (elementsObject != nullptr && bFlag && bText) { + napi_set_element(env_, recvElement, index1++, elementsObject); + elementsObject = nullptr; + } + index++; + pNode = pNode->next; + } + if (bFlag) { + napi_set_named_property(env_, object, m_Options.elements.c_str(), recvElement); + } +} + +napi_value ConvertXml::convert(std::string strXml) +{ + xmlDocPtr doc = NULL; + xmlNodePtr curNode = NULL; + napi_status status = napi_ok; + size_t len = strXml.size(); + doc = xmlParseMemory(strXml.c_str(), len); + if (!doc) { + xmlFreeDoc(doc); + } + napi_value object = nullptr; + status = napi_create_object(env_, &object); + if (status != napi_ok) { + return NULL; + } + napi_value subObject = nullptr; + napi_value subSubObject = nullptr; + napi_value napiKey = nullptr; + napi_create_object(env_, &subSubObject); + napi_create_object(env_, &subObject); + napi_create_string_utf8(env_, (const char*)doc->version, NAPI_AUTO_LENGTH, &napiKey); + napi_set_named_property(env_, subSubObject, "version", napiKey); + napi_create_string_utf8(env_, (const char*)doc->encoding, NAPI_AUTO_LENGTH, &napiKey); + napi_set_named_property(env_, subSubObject, "encoding", napiKey); + if (!m_Options.ignoreDeclaration) { + napi_set_named_property(env_, subObject, m_Options.attributes.c_str(), subSubObject); + napi_set_named_property(env_, object, m_Options.declaration.c_str(), subObject); + } + curNode = xmlDocGetRootElement(doc); + GetPrevNodeList(curNode); + GetXMLInfo(curNode, object, 0); + napi_value iTemp = nullptr; + switch (m_SpaceType) { + case (SpaceType::T_INT32): + napi_create_int32(env_, m_iSpace, &iTemp); + napi_set_named_property(env_, object, "spaces", iTemp); + break; + case (SpaceType::T_STRING): + SetKeyValue(object, "spaces", m_strSpace); + break; + case (SpaceType::T_INIT): + SetKeyValue(object, "spaces", m_strSpace); + break; + default: + break; + } + return object; +} + +napi_status ConvertXml::DealNapiStrValue(napi_value napi_StrValue, std::string &result) +{ + char *buffer = nullptr; + size_t bufferSize = 0; + napi_status status = napi_ok; + status = napi_get_value_string_utf8(env_, napi_StrValue, buffer, -1, &bufferSize); + if (status != napi_ok) { + return status; + } + buffer = new char[bufferSize + 1]; + napi_get_value_string_utf8(env_, napi_StrValue, buffer, bufferSize + 1, &bufferSize); + + if (buffer != nullptr) { + result = buffer; + delete []buffer; + buffer = nullptr; + } + return status; +} + +void ConvertXml::DealSpaces(napi_value napi_obj) +{ + napi_value recvTemp = nullptr; + napi_get_named_property(env_, napi_obj, "spaces", &recvTemp); + napi_valuetype valuetype = napi_undefined; + napi_typeof(env_, recvTemp, &valuetype); + if (valuetype == napi_string) { + DealNapiStrValue(recvTemp, m_strSpace); + m_SpaceType = SpaceType::T_STRING; + } else if (valuetype == napi_number) { + int32_t iTemp; + if (napi_get_value_int32(env_, recvTemp, &iTemp) == napi_ok) { + m_iSpace = iTemp; + m_SpaceType = SpaceType::T_INT32; + } + } +} + +void ConvertXml::DealIgnore(napi_value napi_obj) +{ + std::vectorvctIgnore = { "compact", "trim", "ignoreDeclaration", "ignoreInstruction", + "ignoreAttributes", "ignoreComment", "ignoreCdata", "ignoreDoctype", "ignoreText" }; + for (size_t i = 0; i < vctIgnore.size(); ++i) { + napi_value recvTemp = nullptr; + bool bRecv = false; + napi_get_named_property(env_, napi_obj, vctIgnore[i].c_str(), &recvTemp); + if ((napi_get_value_bool(env_, recvTemp, &bRecv)) == napi_ok) { + switch (i) { + case 0: + m_Options.compact = bRecv; + break; + case 1: // 1:trim + m_Options.trim = bRecv; + break; + case 2: // 2:ignoreDeclaration + m_Options.ignoreDeclaration = bRecv; + break; + case 3: // 3:ignoreInstruction + m_Options.ignoreInstruction = bRecv; + break; + case 4: // 4:ignoreAttributes + m_Options.ignoreAttributes = bRecv; + break; + case 5: // 5:ignoreComment + m_Options.ignoreComment = bRecv; + break; + case 6: // 6:ignoreCdata + m_Options.ignoreCdata = bRecv; + break; + case 7: // 7:ignoreDoctype + m_Options.ignoreDoctype = bRecv; + break; + case 8: // 8:ignoreText + m_Options.ignoreText = bRecv; + break; + default: + break; + } + } + } +} + +void ConvertXml::SetDefaultKey(size_t i, std::string strRecv) +{ + switch (i) { + case 0: + m_Options.declaration = strRecv; + break; + case 1: + m_Options.instruction = strRecv; + break; + case 2: // 2:attributes + m_Options.attributes = strRecv; + break; + case 3: // 3:text + m_Options.text = strRecv; + break; + case 4: // 4:cdata + m_Options.cdata = strRecv; + break; + case 5: // 5:doctype + m_Options.doctype = strRecv; + break; + case 6: // 6:comment + m_Options.comment = strRecv; + break; + case 7: // 7:parent + m_Options.parent = strRecv; + break; + case 8: // 8:type + m_Options.type = strRecv; + break; + case 9: // 9:name + m_Options.name = strRecv; + break; + case 10: // 10:elements + m_Options.elements = strRecv; + break; + default: + break; + } +} + +void ConvertXml::DealOptions(napi_value napi_obj) +{ + std::vectorvctOptions = { "declarationKey", "instructionKey", "attributesKey", "textKey", + "cdataKey", "doctypeKey", "commentKey", "parentKey", "typeKey", "nameKey", "elementsKey" }; + for (size_t i = 0; i < vctOptions.size(); ++i) { + napi_value recvTemp = nullptr; + std::string strRecv = ""; + napi_get_named_property(env_, napi_obj, vctOptions[i].c_str(), &recvTemp); + if ((DealNapiStrValue(recvTemp, strRecv)) == napi_ok) { + SetDefaultKey(i, strRecv); + } + } + DealIgnore(napi_obj); + DealSpaces(napi_obj); +} diff --git a/convertxml/js_convertxml.h b/convertxml/js_convertxml.h new file mode 100755 index 0000000000000000000000000000000000000000..2fb94b2f13e5021e5af958962fd0cddd19e96d25 --- /dev/null +++ b/convertxml/js_convertxml.h @@ -0,0 +1,90 @@ + /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FOUNDATION_ACE_CCRUNTIME_CONVERT_XML_CLASS_H +#define FOUNDATION_ACE_CCRUNTIME_CONVERT_XML_CLASS_H + +#include +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "libxml/parser.h" +#include "libxml/tree.h" + +enum class SpaceType { + T_INT32, + T_STRING, + T_INIT = -1 +}; + +struct Options { + std::string declaration = "_declaration"; + std::string instruction = "_instruction"; + std::string attributes = "_attributes"; + std::string text = "_text"; + std::string cdata = "_cdata"; + std::string doctype = "_doctype"; + std::string comment = "_comment"; + std::string parent = "_parent"; + std::string type = "_type"; + std::string name = "_name"; + std::string elements = "_elements"; + bool compact = false; + bool trim = false; + bool nativetype = false; + bool nativetypeattributes = false; + bool addparent = false; + bool alwaysArray = false; + bool alwaysChildren = false; + bool instructionHasAttributes = false; + bool ignoreDeclaration = false; + bool ignoreInstruction = false; + bool ignoreAttributes = false; + bool ignoreComment = false; + bool ignoreCdata = false; + bool ignoreDoctype = false; + bool ignoreText = false; + bool spaces = false; +}; + +class ConvertXml { +public: + explicit ConvertXml(napi_env env); + virtual ~ConvertXml() {} + void SetAttributes(xmlNodePtr curNode, napi_value &elementsObject); + void SetXmlElementType(xmlNodePtr curNode, napi_value &elementsObject); + void SetNodeInfo(xmlNodePtr curNode, napi_value &elementsObject); + void SetEndInfo(xmlNodePtr curNode, napi_value &elementsObject, bool &bFlag, bool &bText, int32_t index); + void GetXMLInfo(xmlNodePtr curNode, napi_value &object, int flag = 0); + napi_value convert(std::string strXml); + std::string GetNodeType(xmlElementType enumType); + napi_status DealNapiStrValue(napi_value napi_StrValue, std::string &result); + void SetKeyValue(napi_value &object, std::string strKey, std::string strValue); + void DealOptions(napi_value napi_obj); + std::string Trim(std::string strXmltrim); + void GetPrevNodeList(xmlNodePtr curNode); + void DealSpaces(napi_value napi_obj); + void DealIgnore(napi_value napi_obj); + void SetPrevInfo(napi_value &recvElement, int flag, int32_t &index1); + void SetDefaultKey(size_t i, std::string strRecv); +private: + napi_env env_; + SpaceType m_SpaceType; + int32_t m_iSpace; + std::string m_strSpace; + Options m_Options; + std::vector m_prevObj; +}; +#endif \ No newline at end of file diff --git a/convertxml/js_convertxml.js b/convertxml/js_convertxml.js new file mode 100755 index 0000000000000000000000000000000000000000..a0305b036471c70e26b7e2e989878f63a6464e36 --- /dev/null +++ b/convertxml/js_convertxml.js @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; +const convertXml = requireInternal("ConvertXML"); +class ConvertXml { + convertxmlclass; + constructor() { + this.convertxmlclass = new convertXml.ConvertXml(); + } + convert(strXml, options) { + let converted = this.convertxmlclass.convert(strXml, options); + let space = 0; + if (converted.hasOwnProperty("spaces")) { + space = converted.spaces; + delete converted.spaces; + } + return JSON.stringify(converted, null, space); + } +} + +export default { + ConvertXml : ConvertXml +} + + diff --git a/convertxml/native_module_convertxml.cpp b/convertxml/native_module_convertxml.cpp new file mode 100755 index 0000000000000000000000000000000000000000..96b73c4a06371e617fd1ce4449a6ffaeb7320dc0 --- /dev/null +++ b/convertxml/native_module_convertxml.cpp @@ -0,0 +1,116 @@ + /* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "js_convertxml.h" +#include "utils/log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +extern const char _binary_js_convertxml_js_start[]; +extern const char _binary_js_convertxml_js_end[]; + +static napi_value ConvertXmlConstructor(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + void *data = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data); + auto objectInfo = new ConvertXml(env); + napi_wrap( + env, thisVar, objectInfo, + [](napi_env env, void *data, void *hint) { + auto obj = (ConvertXml*)data; + if (obj != nullptr) { + delete obj; + } + }, + nullptr, nullptr); + return thisVar; +} + +static napi_value Convert(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t requireMaxArgc = 2; + size_t requireMinArgc = 1; + size_t argc = 2; + napi_value args[2] = {nullptr}; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); + NAPI_ASSERT(env, argc <= requireMaxArgc, "Wrong number of arguments(Over)"); + NAPI_ASSERT(env, argc >= requireMinArgc, "Wrong number of arguments(Less)"); + std::string strXml; + napi_valuetype valuetype; + ConvertXml *object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + if (args[0] == nullptr) { + NAPI_CALL(env, napi_throw_error(env, "", "parameter is empty")); + } else { + NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); + object->DealNapiStrValue(args[0], strXml); + } + if (args[1] != nullptr) { + object->DealOptions(args[1]); + } + napi_value result = object->convert(strXml); + HILOG_INFO("LHC....Convert start011"); + return result; +} + + +static napi_value ConvertXmlInit(napi_env env, napi_value exports) +{ + HILOG_INFO("LHC....ConvertXmlInit start02"); + const char *ConvertXmlClassName = "ConvertXml"; + napi_value ConvertXmlClass = nullptr; + static napi_property_descriptor ConvertXmlDesc[] = { + DECLARE_NAPI_FUNCTION("convert", Convert) + }; + NAPI_CALL(env, napi_define_class(env, ConvertXmlClassName, strlen(ConvertXmlClassName), ConvertXmlConstructor, + nullptr, sizeof(ConvertXmlDesc) / sizeof(ConvertXmlDesc[0]), ConvertXmlDesc, + &ConvertXmlClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("ConvertXml", ConvertXmlClass) + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + HILOG_INFO("LHC....ConvertXmlInit end02"); + return exports; +} + +extern "C" +__attribute__((visibility("default"))) void NAPI_convertxml_GetJSCode(const char **buf, int *bufLen) +{ + if (buf != nullptr) { + *buf = _binary_js_convertxml_js_start; + } + + if (bufLen != nullptr) { + *bufLen = _binary_js_convertxml_js_end - _binary_js_convertxml_js_start; + } +} + +static napi_module ConvertXmlModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = ConvertXmlInit, + .nm_modname = "ConvertXML", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__ ((constructor)) void RegisterModule() +{ + napi_module_register(&ConvertXmlModule); +} + diff --git a/ohos.build b/ohos.build old mode 100644 new mode 100755 index d27627fd0320be21340ab96d952511fa25166896..1997a40bdde91941369a399a07d3bf0589ecf327 --- a/ohos.build +++ b/ohos.build @@ -1,13 +1,14 @@ { "subsystem": "ccruntime", "parts": { - "jsapi_url": { + "jsapi_api": { "variants": [ "wearable", "phone" ], "module_list": [ - "//base/compileruntime/js_api_module/url:url_packages" + "//base/compileruntime/js_api_module/api:api_packages", + "//base/compileruntime/js_api_module/convertxml:convertxml_packages" ], "inner_kits": [ ], diff --git a/url/js_url.cpp b/url/js_url.cpp deleted file mode 100644 index 644e5f7a87e34c97bbfae9880176bdcf655b6111..0000000000000000000000000000000000000000 --- a/url/js_url.cpp +++ /dev/null @@ -1,2119 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "js_url.h" -#include -#include -#include -#include "securec.h" -#include "utils/log.h" - -static std::map g_head = { - {"ftp:", 21}, {"file:", -1}, {"gopher:", 70}, {"http:", 80}, - {"https:", 443}, {"ws:", 80}, {"wss:", 443} -}; - -static std::vector g_doubleSegment = { - "..", ".%2e", ".%2E", "%2e.", "%2E.", - "%2e%2e", "%2E%2E", "%2e%2E", "%2E%2e" -}; - -static std::vector g_singlesegment = { ".", "%2e", "%2E" }; - -static std::vector g_specialcharacter = { - '\0', '\t', '\n', '\r', ' ', '#', '%', '/', ':', '?', - '@', '[', '\\', ']' -}; - -static void ReplaceSpecialSymbols(std::string& input, std::string& oldstr, std::string& newstr) -{ - size_t oldlen = oldstr.size(); - while (true) { - size_t pos = 0; - if ((pos = input.find(oldstr)) != std::string::npos) { - input.replace(pos, oldlen, newstr); - } else { - break; - } - } -} - -template -bool IsASCIITabOrNewline(const T ch) -{ - return (ch == '\t' || ch == '\n' || ch == '\r'); -} - -template -bool IsHexDigit(const T ch) -{ - if (isdigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { - return true; - } - return false; -} - -static unsigned AsciiToHex(const unsigned char pram) -{ - if (pram >= '0' && pram <= '9') { - return pram - '0'; - } - if (pram >= 'A' && pram <= 'F') { - return pram - 'A' + 10; // 10:Convert to hexadecimal - } - if (pram >= 'a' && pram <= 'f') { - return pram - 'a' + 10; // 10:Convert to hexadecimal - } - return static_cast(-1); -} - -static std::string DecodePercent(const char *input, size_t len) -{ - std::string temp; - if (len == 0) { - return temp; - } - temp.reserve(len); - const char* it = input; - const char* end = input + len; - while (it < end) { - const char ch = it[0]; - size_t left = end - it - 1; - if (ch != '%' || left < 2 || (ch == '%' && (!IsHexDigit(it[1]) || // 2:The length is less than 2 - !IsHexDigit(it[2])))) { // 2:The number of characters is less than 2 - temp += ch; - it++; - continue; - } else { - unsigned first = AsciiToHex(it[1]); - unsigned second = AsciiToHex(it[2]); // 2:Subscript 2 - char pram = static_cast(first * 16 + second); // 16:Convert hex - temp += pram; - it += 3; // 3:Move the pointer to the right by 3 digits. - } - } - return temp; -} - -static void DeleteC0OrSpace(std::string& str) -{ - if (str.empty()) { - return; - } - size_t i = 0; - size_t strlen = str.size(); - for (; i < strlen;) { - if (str[i] >= '\0' && str[i] <= ' ') { - i++; - } else { - break; - } - } - str = str.substr(i); - strlen = str.size(); - for (i = strlen - 1; i != 0; i--) { - if (str[i] >= '\0' && str[i] <= ' ') { - str.pop_back(); - } else { - break; - } - } -} - -static void DeleteTabOrNewline(std::string& str1) -{ - for (auto item = str1.begin(); item != str1.end();) { - if (IsASCIITabOrNewline(*item)) { - item = str1.erase(item); - } else { - ++item; - } - } -} - -static bool IsSpecial(std::string scheme) -{ - auto temp = g_head.count(scheme); - if (temp > 0) { - return true; - } - return false; -} - -static bool AnalysisScheme(std::string& input, std::string& scheme, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (!isalpha(input[0])) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return false; - } else { - size_t strlen = input.size(); - for (size_t i = 0; i < strlen - 1; ++i) { - if ((isalnum(input[i]) || input[i] == '+' || input[i] == '-' || input[i] == '.') && isupper(input[i])) { - input[i] = tolower(input[i]); - } - if (!isalnum(input[i]) && input[i] != '+' && input[i] != '-' && input[i] != '.') { - flags.set(static_cast(BitsetStatusFlag::BIT0)); // 0:Bit 0 Set to true,The URL analysis failed - return false; - } - } - scheme = input; - if (IsSpecial(scheme)) { - flags.set(static_cast(BitsetStatusFlag::BIT1)); - } - return true; - } -} - -static void AnalysisFragment(const std::string& input, std::string& fragment, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - fragment = input; - flags.set(static_cast(BitsetStatusFlag::BIT8)); -} - -static void AnalysisQuery(const std::string& input, std::string& query, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - query = input; - flags.set(static_cast(BitsetStatusFlag::BIT7)); -} -static void AnalysisUsernameAndPasswd(std::string& input, std::string& username, std::string& password, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - int pos = input.size() - 1; - for (; pos >= 0; pos--) { - if (input[pos] == '@') { - break; - } - } - std::string userAndPasswd = input.substr(0, pos); - input = input.substr(pos + 1); - if (userAndPasswd.empty()) { - return; - } - if (userAndPasswd.find('@') != std::string::npos) { - while (true) { - size_t i = 0; - if ((i = userAndPasswd.find('@')) != std::string::npos) { - userAndPasswd = userAndPasswd.replace(i, 1, "%40"); - } else { - break; - } - } - } - - if (userAndPasswd.find(':') != std::string::npos) { - size_t i = userAndPasswd.find(':'); - std::string user = userAndPasswd.substr(0, i); - std::string keyWord = userAndPasswd.substr(i + 1); - if (!user.empty()) { - username = user; - flags.set(static_cast(BitsetStatusFlag::BIT2)); - } - if (!keyWord.empty()) { - password = keyWord; - flags.set(static_cast(BitsetStatusFlag::BIT3)); - } - } else { - username = userAndPasswd; - flags.set(static_cast(BitsetStatusFlag::BIT2)); - } -} - -static void AnalysisPath(std::string& input, std::vector& path, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool isSpecial) -{ - std::vector temp; - size_t pos = 0; - while (((pos = input.find('/')) != std::string::npos) || - ((pos = input.find('\\')) != std::string::npos && isSpecial)) { - temp.push_back(input.substr(0, pos)); - input = input.substr(pos + 1); - } - temp.push_back(input); - size_t length = temp.size(); - for (size_t it = 0; it < length; ++it) { - auto result = find(g_doubleSegment.begin(), g_doubleSegment.end(), temp[it]); - if (result != g_doubleSegment.end()) { - if (path.empty() && it == length - 1) { - path.emplace_back(""); - flags.set(static_cast(BitsetStatusFlag::BIT6)); - } - if (path.empty()) { - continue; - } - path.pop_back(); - if (it == length - 1) { - path.emplace_back(""); - flags.set(static_cast(BitsetStatusFlag::BIT6)); - } - continue; - } - result = find(g_singlesegment.begin(), g_singlesegment.end(), temp[it]); - if (result != g_singlesegment.end() && it == length - 1) { - path.emplace_back(""); - flags.set(static_cast(BitsetStatusFlag::BIT6)); - continue; - } - if (result == g_singlesegment.end()) { - path.push_back(temp[it]); - flags.set(static_cast(BitsetStatusFlag::BIT6)); - } - } -} - -static void AnalysisPort(std::string input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - for (auto i : input) { - if (!isdigit(i)) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - } - int it = stoi(input); - const int maxPort = 65535; // 65535:Maximum port number - if (it > maxPort) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - flags.set(static_cast(BitsetStatusFlag::BIT5)); - for (auto i : g_head) { - if (i.first == urlinfo.scheme && i.second == it) { - urlinfo.port = -1; - flags.set(static_cast(BitsetStatusFlag::BIT5), 0); - return; - } - } - urlinfo.port = it; -} - -static void AnalysisOpaqueHost(std::string input, std::string& host, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - size_t strlen = input.size(); - for (size_t i = 0; i < strlen; ++i) { - char ch = input[i]; - auto result = find(g_specialcharacter.begin(), g_specialcharacter.end(), ch); - if (ch != '%' && (result != g_specialcharacter.end())) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - } - host = input; - flags.set(static_cast(BitsetStatusFlag::BIT4)); -} - -static std::string IPv6ZeroComperess(std::vector& tempIPV6, std::string& input, - int maxZeroIndex, int max) -{ - for (int i = 0; i < maxZeroIndex; ++i) { - input += tempIPV6[i]; - if (i != maxZeroIndex - 1) { - input += ":"; - } - } - input += "::"; - size_t strlen = tempIPV6.size(); - for (size_t i = maxZeroIndex + max; i < strlen; ++i) { - input += tempIPV6[i]; - if (i != strlen - 1) { - input += ":"; - } - } - return input; -} - -static std::string IPv6NoComperess(std::vector& tempIPV6, std::string& input) -{ - size_t strlen = tempIPV6.size(); - for (size_t i = 0; i < strlen; ++i) { - if (tempIPV6[i][0] == '?' && tempIPV6[i].size() == 1) { - input += ":"; - } else { - input += tempIPV6[i]; - if (i != tempIPV6.size() - 1) { - input += ":"; - } - } - } - return input; -} - -static std::string IPv6HostCompress(std::vector& tempIPV6, int flag) -{ - std::string input; - if (flag == 1) { - return IPv6NoComperess(tempIPV6, input); - } - int max = 0; - int count = 0; - size_t maxZeroIndex = 0; - size_t strlen = tempIPV6.size(); - for (size_t i = 0; i < strlen;) { - if (tempIPV6[i] == "0" && (i + 1 < strlen && tempIPV6[i + 1] == "0")) { - int index = i; - while (i < strlen && tempIPV6[i] == "0") { - i++; - count++; - } - if (max < count) { - max = count; - maxZeroIndex = index; - } - } else { - count = 0; - i++; - } - } - if (count == 8) { // 8:If IPv6 is all 0 - return "::"; - } else if (max == 0) { - strlen = tempIPV6.size(); - for (size_t i = 0; i < strlen; ++i) { - input += tempIPV6[i]; - if (i != strlen - 1) { - input += ":"; - } - } - return input; - } else if (maxZeroIndex == 0) { - input += "::"; - strlen = tempIPV6.size(); - for (size_t i = max; i < strlen; ++i) { - input += tempIPV6[i] + ":"; - } - input.pop_back(); - return input; - } else { - return IPv6ZeroComperess(tempIPV6, input, maxZeroIndex, max); - } -} - -void DealWithtempIpv6(std::vector &tempIpv6, std::stringstream &ss, - std::string &numberHex, const int tempProt[4]) -{ - tempIpv6.push_back(numberHex); - ss.clear(); - numberHex.clear(); - ss << std::hex << tempProt[2] * 0x100 + tempProt[3]; // 2: 3:subscript position - ss >> numberHex; - tempIpv6.push_back(numberHex); - ss.clear(); - numberHex.clear(); - tempIpv6.erase(tempIpv6.end() - 3); // 3:Remove redundant space -} - -void IPv6DealWithColon(int& flag, std::string& strInput, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t &pos) -{ - flag = 1; - if (strInput.find("::", pos + 2) != std::string::npos) { // 2:Subscript Move Right2 - flags.set(static_cast(BitsetStatusFlag::BIT0)); - } - return; -} - -void IsFlagExist(size_t &pos, std::vector &temp, std::vector &tempEnd, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags, unsigned &numberFlag) -{ - while (((pos = temp[numberFlag].find('.')) != std::string::npos)) { - tempEnd.push_back(temp[numberFlag].substr(0, pos)); - temp[numberFlag] = temp[numberFlag].substr(pos + 1); - } - tempEnd.push_back(temp[numberFlag]); - if (tempEnd.size() != 4) { // 4:The size is not 4 - flags.set(static_cast(BitsetStatusFlag::BIT0)); - } -} -void DealWithProt(std::vector &tempEnd, unsigned &val, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, - int &number, int tempProt[4]) -{ - size_t strlen = tempEnd.size(); - for (size_t x = 0; x < strlen; ++x) { - val = stoi(tempEnd[x]); - if (val > 255) { // 255:The maximum value is 255 - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - tempProt[number] = val; - number++; - val = 0; - } -} - -void DealWithElse(std::vector &temp, size_t &i, unsigned &numberFlag, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, unsigned &val) -{ - size_t strlen = temp[i].size(); - for (size_t j = 0; j < strlen; ++j) { - if (((temp[i].find('.')) != std::string::npos)) { - numberFlag = i; - if (temp.size() == i || temp.size() > 7) { // 7:The size cannot be greater than 7 - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - return; - } else if (IsHexDigit(temp[i][j])) { - val = val * 0x10 + AsciiToHex(temp[i][j]); - } - } -} - -void DealWithStringStream(std::stringstream &ss, unsigned &val, - std::string &numberHex, std::vector &tempIpv6) -{ - ss << std::hex << val; - ss >> numberHex; - tempIpv6.push_back(numberHex); - ss.clear(); - numberHex.clear(); - val = 0; -} - -static void IPv6Host(std::string& input, std::string& host, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (input.size() == 0) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - std::string strInput = input; - std::stringstream ss; - std::string numberHex; - unsigned val = 0; - unsigned numberFlag = 0; - std::vector temp; - std::vector tempEnd; - std::vector tempIpv6; - size_t pos = 0; - int tempProt[4] = { 0 }; - int number = 0; - int flag = 0; - if ((pos = strInput.find("::", 0)) != std::string::npos) { - IPv6DealWithColon(flag, strInput, flags, pos); - } - while (((pos = strInput.find(':')) != std::string::npos)) { - temp.push_back(strInput.substr(0, pos)); - strInput = strInput.substr(pos + 1); - } - temp.push_back(strInput); - if (temp.size() > 8) { // 8:The incoming value does not meet the criteria - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - size_t length = temp.size(); - for (size_t i = 0; i < length; ++i) { - if (temp[i].empty()) { - tempIpv6.push_back("?"); - } else { - DealWithElse(temp, i, numberFlag, flags, val); - DealWithStringStream(ss, val, numberHex, tempIpv6); - } - } - if (numberFlag != 0) { - IsFlagExist(pos, temp, tempEnd, flags, numberFlag); - DealWithProt(tempEnd, val, flags, number, tempProt); - ss << std::hex << tempProt[0] * 0x100 + tempProt[1]; - ss >> numberHex; - DealWithtempIpv6(tempIpv6, ss, numberHex, tempProt); - } - strInput = IPv6HostCompress(tempIpv6, flag); - host = '[' + strInput + ']'; - flags.set(static_cast(BitsetStatusFlag::BIT4)); - flags.set(static_cast(BitsetStatusFlag::BIT10)); -} - -static bool CheckNunType(const char ch, const unsigned num) -{ - enum class NUMERATION { - OCT = 8, // 8:Octal - DEC = 10, // 10:Decimal - HEX = 16 // 16:Hexadecimal - }; - if (NUMERATION(num) == NUMERATION::OCT) { - if (ch < '0' || ch > '7') { // 0~7:Octal - return false; - } - } else if (NUMERATION(num) == NUMERATION::DEC) { - if (ch < '0' || ch > '9') { // 0~9:Decimal - return false; - } - } else if (NUMERATION(num) == NUMERATION::HEX) { - if (!((ch >= '0' && ch <= '9') || // 0~9, a~f, A~F:Hexadecimal - (ch >= 'A' && ch <= 'F') || - (ch >= 'a' && ch <= 'f'))) { - return false; - } - } - return true; -} - -static int64_t AnalyseNum(std::string parts) -{ - unsigned num = 10; // 10:Decimal - std::string partsBeg = parts.substr(0, 2); // 2:Take two digits to determine whether it is hexadecimal - size_t partsLen = parts.length(); - if (partsLen >= 2 && (partsBeg == "0X" || partsBeg == "0x")) { // 2:parts length - num = 16; // 16:Convert to hexadecimal - parts = parts.substr(2); // 2:delete '0x' - } else if (num == 10 && partsLen > 1 && parts.substr(0, 1) == "0") { // 10:Conversion to Decimal Coefficient - num = 8; // 8:Convert to octal - parts = parts.substr(1); - } - for (size_t i = 0; i < parts.length(); i++) { - bool ret = CheckNunType(parts[i], num); - if (!ret) { - return -1; - } - } - return strtoll(parts.c_str(), nullptr, num); -} - -static bool OverHex(std::string input) -{ - size_t size = input.size(); - for (size_t i = 0; i < size; i++) { - return !IsHexDigit(input[i]); - } - return false; -} - -static bool NotAllNum(std::string input) -{ - size_t size = input.size(); - for (size_t i = 0; i < size; i++) { - if (!isdigit(input[i])) { - return true; - } - } - return false; -} - -static bool AnalyseIPv4(const char *instr, std::string &host, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags) -{ - int count = 0; - for (const char* ptr = instr; *ptr != '\0'; ptr++) { - if (*ptr == '.') { - if (++count > 3) { // 3:The IPV4 address has only four segments - return false; - } - } - } - if (count != 3) { // 3:The IPV4 address has only four segments - return false; - } - - size_t pos = 0; - std::vector strVec; - std::string input = static_cast(instr); - while (((pos = input.find('.')) != std::string::npos)) { - strVec.push_back(input.substr(0, pos)); - input = input.substr(pos + 1); - } - strVec.push_back(input); - size_t size = strVec.size(); - for (size_t i = 0; i < size; i++) { - if (strVec[i].empty()) { - return false; - } - std::string begStr = strVec[i].substr(0, 2); // 2:Intercept the first two characters - if ((begStr == "0x" || begStr == "0X") && OverHex(strVec[i].substr(2))) { // 2:Intercept - return false; - } else if ((begStr == "0x" || begStr == "0X") && !(OverHex(strVec[i].substr(2)))) { // 2:Intercept - continue; - } - if (NotAllNum(strVec[i])) { - return false; - } - } - for (size_t i = 0; i < size; i++) { - int64_t value = AnalyseNum(strVec[i].c_str()); - if ((value < 0) || (value > 255)) { // 255:Only handle numbers between 0 and 255 - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return false; - } else { - host += std::to_string(value); - if (i != size - 1) { - host += "."; - } - } - } - flags.set(static_cast(BitsetStatusFlag::BIT4)); - return true; -} -static void AnalysisHost(std::string& input, std::string& host, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool special) -{ - if (input.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - if (input[0] == '[') { - if ((input[input.length() - 1]) == ']') { - size_t b = input.length(); - input = input.substr(1, b - 2); // 2:Truncating Strings - IPv6Host(input, host, flags); - return; - } else { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - } - if (!special) { - AnalysisOpaqueHost(input, host, flags); - return; - } - std::string decodeInput = DecodePercent(input.c_str(), input.length()); - size_t strlen = decodeInput.size(); - for (size_t pos = 0; pos < strlen; ++pos) { - char ch = decodeInput[pos]; - auto result = find(g_specialcharacter.begin(), g_specialcharacter.end(), ch); - if (result != g_specialcharacter.end()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - } - bool ipv4 = AnalyseIPv4(decodeInput.c_str(), host, flags); - if (ipv4) { - return; - } - host = decodeInput; - flags.set(static_cast(BitsetStatusFlag::BIT4)); -} -static bool ISFileNohost(const std::string& input) -{ - if ((isalpha(input[0]) && (input[1] == ':' || input[1] == '|'))) { - return true; - } - return false; -} -static void AnalysisFilePath(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - std::vector temp; - size_t pos = 0; - while (((pos = input.find('/')) != std::string::npos) || ((pos = input.find('\\')) != std::string::npos)) { - temp.push_back(input.substr(0, pos)); - input = input.substr(pos + 1); - } - temp.push_back(input); - size_t length = temp.size(); - for (size_t i = 0; i < length; ++i) { - auto a = find(g_doubleSegment.begin(), g_doubleSegment.end(), temp[i]); - if (a != g_doubleSegment.end()) { - if ((urlinfo.path.size() == 1) && ISFileNohost(urlinfo.path[0]) && - urlinfo.path[0].size() == 2) { // 2:The interception length is 2 - urlinfo.path[0][1] = ':'; - } else if (!urlinfo.path.empty()) { - urlinfo.path.pop_back(); - } - if (i == temp.size() - 1) { - urlinfo.path.push_back(""); - } - continue; - } - a = find(g_singlesegment.begin(), g_singlesegment.end(), temp[i]); - if (a != g_singlesegment.end()) { - if (i == temp.size() - 1) { - urlinfo.path.push_back(""); - } - continue; - } - urlinfo.path.push_back(temp[i]); - flags.set(static_cast(BitsetStatusFlag::BIT6)); - } - std::string it = urlinfo.path[0]; - if (isalpha(it[0]) && (it[1] == ':' || it[1] == '|')) { - if (it.size() == 2) { // 2:The length is 2 - it[1] = ':'; - flags.set(static_cast(BitsetStatusFlag::BIT4), 0); - urlinfo.host.clear(); - } - } -} - -static void AnalysisFile(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - bool special = true; - if ((input[0] == '/' || input[0] == '\\') && (input[1] == '/' || input[1] == '\\')) { - std::string temp = input.substr(2); // 2:Intercept from 2 subscripts - size_t pos = 0; - if ((((pos = temp.find('/')) != std::string::npos) || - ((pos = temp.find('\\')) != std::string::npos)) && pos == 0) { - temp = temp.substr(1); - AnalysisFilePath(temp, urlinfo, flags); - } else if ((((pos = temp.find('/')) != std::string::npos) || - ((pos = temp.find('\\')) != std::string::npos)) && pos != 0) { - std::string strHost = temp.substr(0, pos); - std::string strPath = temp.substr(pos + 1); - if (!ISFileNohost(strHost)) { - AnalysisHost(strHost, urlinfo.host, flags, special); - } else if (!ISFileNohost(strHost) && flags.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - if (!ISFileNohost(strHost)) { - AnalysisFilePath(strPath, urlinfo, flags); - } else { - AnalysisFilePath(temp, urlinfo, flags); - } - } else { - if (!temp.empty() && flags.test(static_cast(BitsetStatusFlag::BIT0))) { - AnalysisHost(temp, urlinfo.host, flags, special); - } else if (!temp.empty() && !flags.test(static_cast(BitsetStatusFlag::BIT0))) { - AnalysisHost(temp, urlinfo.host, flags, special); - return; - } - } - } else { - if (input[0] == '/' || input[0] == '\\') { - input = input.substr(1); - } - AnalysisFilePath(input, urlinfo, flags); - } -} - -static void AnalysisFilescheme(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - std::string strPath = urlinfo.scheme + input; - urlinfo.scheme = "file:"; - flags.set(static_cast(BitsetStatusFlag::BIT1)); - AnalysisFilePath(strPath, urlinfo, flags); -} - -void AnalyInfoPath(std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags, - UrlData& urlinfo, std::string& input) -{ - flags.set(static_cast(BitsetStatusFlag::BIT9)); - if (urlinfo.path.empty()) { - urlinfo.path.emplace_back(""); - } - urlinfo.path[0] = input; - flags.set(static_cast(BitsetStatusFlag::BIT6)); - return; -} - -void AnalyHostPath(std::string &strHost, std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, - UrlData& urlinfo) -{ - size_t pos = 0; - if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { - std::string port = strHost.substr(pos + 1); - strHost = strHost.substr(0, pos); - AnalysisPort(port, urlinfo, flags); - if (flags.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - } -} -void AnalyStrHost(std::string &strHost, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &flags) -{ - if (strHost.find('@') != std::string::npos) { - AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); - } - if (strHost.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } -} - -static void AnalysisNoDefaultProtocol(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (urlinfo.scheme.size() == 2) { // 2:The length is 2 - AnalysisFilescheme(input, urlinfo, flags); - return; - } - if (input[0] == '/' && input[1] == '/') { - std::string hostandpath = input.substr(2); // 2:Intercept from 2 subscripts - if (hostandpath.empty()) { - return; - } - size_t i = 0; - bool special = false; - if (hostandpath.find('/') != std::string::npos) { - i = hostandpath.find('/'); - std::string strHost = hostandpath.substr(0, i); - std::string strPath = hostandpath.substr(i + 1); - if (strHost.find('@') != std::string::npos) { - AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); - } - if (strHost.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - size_t pos = 0; - if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { - std::string port = strHost.substr(pos + 1); - strHost = strHost.substr(0, pos); - AnalysisPort(port, urlinfo, flags); - } - if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos && - flags.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - AnalysisHost(strHost, urlinfo.host, flags, special); - AnalysisPath(strPath, urlinfo.path, flags, special); - } else { - std::string strHost = hostandpath; - AnalyStrHost(strHost, urlinfo, flags); - AnalyHostPath(strHost, flags, urlinfo); - AnalysisHost(strHost, urlinfo.host, flags, special); - } - } else if (input[1] == '/') { - std::string strPath = input.substr(1); - AnalysisPath(strPath, urlinfo.path, flags, false); - } else { - AnalyInfoPath(flags, urlinfo, input); - } -} - -static void AnalysisOnlyHost(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t pos) -{ - std::string strHost = input; - if (strHost.find('@') != std::string::npos) { - AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); - } - if (strHost.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - if (strHost[strHost.size() - 1] != ']') { - if ((pos = strHost.find_last_of(':')) != std::string::npos) { - std::string port = strHost.substr(pos + 1); - strHost = strHost.substr(0, pos); - AnalysisPort(port, urlinfo, flags); - } - if ((pos = strHost.find_last_of(':')) != std::string::npos && - flags.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - } - AnalysisHost(strHost, urlinfo.host, flags, true); -} -void JudgePos(size_t &pos, size_t &length, std::string& input) -{ - for (pos = 0; pos < length; pos++) { - if (input[pos] == '/' || input[pos] == '\\') { - break; - } - } -} -static void AnalysisHostAndPath(std::string& input, UrlData& urlinfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (flags.test(static_cast(BitsetStatusFlag::BIT1))) { - size_t pos = 0; - bool special = true; - size_t inputLen = input.size(); - for (; pos < inputLen;) { - if (input[pos] == '/' || input[pos] == '\\') { - pos++; - } else { - break; - } - } - input = input.substr(pos); - if (input.size() == 0) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } else if (input.size() != 0 && (input.find('/') != std::string::npos || - input.find('\\') != std::string::npos)) { - size_t length = input.size(); - JudgePos(pos, length, input); - std::string strHost = input.substr(0, pos); - std::string strPath = input.substr(pos + 1); - if (strHost.find('@') != std::string::npos) { - AnalysisUsernameAndPasswd(strHost, urlinfo.username, urlinfo.password, flags); - } - if (strHost.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos) { - std::string port = strHost.substr(pos + 1); - strHost = strHost.substr(0, pos); - AnalysisPort(port, urlinfo, flags); - } - if (strHost[strHost.size() - 1] != ']' && (pos = strHost.find_last_of(':')) != std::string::npos && - flags.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - AnalysisHost(strHost, urlinfo.host, flags, special); - AnalysisPath(strPath, urlinfo.path, flags, special); - } else if (input.size() != 0 && input.find('/') == std::string::npos && - input.find('\\') == std::string::npos) { - AnalysisOnlyHost(input, urlinfo, flags, pos); - } - } else { - AnalysisNoDefaultProtocol(input, urlinfo, flags); - } -} - -static void AnalysisInput(std::string& input, UrlData& urlData, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (input.find('#') != std::string::npos) { - size_t i = input.find('#'); - std::string fragment = input.substr(i); - AnalysisFragment(fragment, urlData.fragment, flags); - input = input.substr(0, i); - } - if (input.find('?') != std::string::npos) { - size_t i = input.find('?'); - std::string query = input.substr(i); - AnalysisQuery(query, urlData.query, flags); - input = input.substr(0, i); - } - bool special = (flags.test(static_cast(BitsetStatusFlag::BIT1)) ? true : false); - AnalysisPath(input, urlData.path, flags, special); -} - -static void BaseInfoToUrl(const UrlData& baseInfo, - const std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags, UrlData& urlData, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool inputIsEmpty) -{ - urlData.scheme = baseInfo.scheme; - flags.set(static_cast(BitsetStatusFlag::BIT1), - baseflags.test(static_cast(BitsetStatusFlag::BIT1))); - urlData.host = baseInfo.host; - flags.set(static_cast(BitsetStatusFlag::BIT4)); - urlData.username = baseInfo.username; - flags.set(static_cast(BitsetStatusFlag::BIT2), - baseflags.test(static_cast(BitsetStatusFlag::BIT2))); - urlData.password = baseInfo.password; - flags.set(static_cast(BitsetStatusFlag::BIT3), - baseflags.test(static_cast(BitsetStatusFlag::BIT3))); - urlData.port = baseInfo.port; - flags.set(static_cast(BitsetStatusFlag::BIT5), - baseflags.test(static_cast(BitsetStatusFlag::BIT5))); - if (inputIsEmpty) { - urlData.path = baseInfo.path; - flags.set(static_cast(BitsetStatusFlag::BIT6), - baseflags.test(static_cast(BitsetStatusFlag::BIT6))); - urlData.query = baseInfo.query; - flags.set(static_cast(BitsetStatusFlag::BIT7), - baseflags.test(static_cast(BitsetStatusFlag::BIT7))); - urlData.fragment = baseInfo.fragment; - flags.set(static_cast(BitsetStatusFlag::BIT8), - baseflags.test(static_cast(BitsetStatusFlag::BIT8))); - } - flags.set(static_cast(BitsetStatusFlag::BIT9), - baseflags.test(static_cast(BitsetStatusFlag::BIT9))); - flags.set(static_cast(BitsetStatusFlag::BIT10), - baseflags.test(static_cast(BitsetStatusFlag::BIT10))); -} - -static void ShorteningPath(UrlData& baseData, bool isFile) -{ - if (baseData.path.empty()) { - return; - } - if ((baseData.path.size() == 1) && isFile && - isalpha(baseData.path[0][0]) && (baseData.path[0][1] == ':')) { - return; - } - baseData.path.pop_back(); -} - -URL::URL(napi_env env, const std::string& input) -{ - env_ = env; - std::string str = input; - DeleteC0OrSpace(str); - DeleteTabOrNewline(str); - InitOnlyInput(str, urlData_, flags_); -} - -void DelCont(std::string strBase, std::string &strInput, UrlData &baseInfo, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> &baseflags) -{ - DeleteC0OrSpace(strBase); - DeleteTabOrNewline(strBase); - DeleteC0OrSpace(strInput); - DeleteTabOrNewline(strInput); - URL::InitOnlyInput(strBase, baseInfo, baseflags); -} - -URL::URL(napi_env env, const std::string& input, const std::string& base) -{ - env_ = env; - UrlData baseInfo; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags; - std::string strBase = base; - std::string strInput = input; - if (strBase.empty()) { - baseflags.set(static_cast(BitsetStatusFlag::BIT0)); - } - DelCont(strBase, strInput, baseInfo, baseflags); - if (baseflags.test(static_cast(BitsetStatusFlag::BIT0))) { - flags_.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } else if (!baseflags.test(static_cast(BitsetStatusFlag::BIT0))) { - InitOnlyInput(strInput, urlData_, flags_); - if (!flags_.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - if ((input[0] == '/') && (input[1] == '/' || (input[1] == '\\' && - baseflags.test(static_cast(BitsetStatusFlag::BIT1))))) { - std::string newInput = baseInfo.scheme + input; - flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); - InitOnlyInput(newInput, urlData_, flags_); - return; - } - if (!baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { - flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); - BaseInfoToUrl(baseInfo, baseflags, urlData_, flags_, input.empty()); - if (!input.empty() && input[0] == '/') { - strInput = input.substr(1); - AnalysisInput(strInput, urlData_, flags_); - } else if (!input.empty() && input[0] != '/') { - AnalysisInput(strInput, urlData_, flags_); - } - if (!input.empty() && input[0] != '/' && urlData_.path.empty()) { - urlData_.path = baseInfo.path; - flags_.set(static_cast(BitsetStatusFlag::BIT6), - baseflags.test(static_cast(BitsetStatusFlag::BIT6))); - } - if (!input.empty() && input[0] != '/' && !urlData_.path.empty()) { - bool isFile = ((urlData_.scheme == "file:") ? true : false); - ShorteningPath(baseInfo, isFile); - baseInfo.path.insert(baseInfo.path.end(), urlData_.path.begin(), urlData_.path.end()); - urlData_.path = baseInfo.path; - flags_.set(static_cast(BitsetStatusFlag::BIT6)); - } - } else if (baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { - flags_.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - } -} - -URL::URL(napi_env env, const std::string& input, const URL& base) -{ - env_ = env; - std::string strInput = input; - UrlData baseInfo = base.urlData_; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> baseflags = base.flags_; - DeleteC0OrSpace(strInput); - DeleteTabOrNewline(strInput); - InitOnlyInput(strInput, urlData_, flags_); - if (!flags_.test(static_cast(BitsetStatusFlag::BIT0))) { - return; - } - if ((input[0] == '/') && (input[1] == '/' || (input[1] == '\\' && - baseflags.test(static_cast(BitsetStatusFlag::BIT1))))) { - std::string newInput = baseInfo.scheme + input; - flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); - InitOnlyInput(newInput, urlData_, flags_); - return; - } - if (!baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { - flags_.set(static_cast(BitsetStatusFlag::BIT0), 0); - BaseInfoToUrl(baseInfo, baseflags, urlData_, flags_, input.empty()); - if (!input.empty() && input[0] == '/') { - strInput = input.substr(1); - AnalysisInput(strInput, urlData_, flags_); - } - if (!input.empty() && input[0] != '/') { - AnalysisInput(strInput, urlData_, flags_); - if (urlData_.path.empty()) { - urlData_.path = baseInfo.path; - flags_.set(static_cast(BitsetStatusFlag::BIT6), - baseflags.test(static_cast(BitsetStatusFlag::BIT6))); - } else { - bool isFile = ((urlData_.scheme == "file:") ? true : false); - ShorteningPath(baseInfo, isFile); - baseInfo.path.insert(baseInfo.path.end(), urlData_.path.begin(), urlData_.path.end()); - urlData_.path = baseInfo.path; - flags_.set(static_cast(BitsetStatusFlag::BIT6)); - } - } - } else if (baseflags.test(static_cast(BitsetStatusFlag::BIT9))) { - flags_.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } -} - -napi_value URL::GetHostname() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT4))) { - temp = urlData_.host.c_str(); - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetSearch() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT7))) { - if (urlData_.query.size() == 1) { - temp = ""; - } else { - temp = urlData_.query.c_str(); - } - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetUsername() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT2))) { - temp = urlData_.username.c_str(); - } else - temp = ""; - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetPassword() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT3))) { - temp = urlData_.password.c_str(); - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetFragment() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT8))) { - if (urlData_.fragment.size() == 1) { - temp = ""; - } else { - temp = urlData_.fragment.c_str(); - } - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetScheme() const -{ - napi_value result; - const char* temp = nullptr; - if (!urlData_.scheme.empty()) { - temp = urlData_.scheme.c_str(); - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetPath() const -{ - napi_value result; - std::string temp = "/"; - if (flags_.test(static_cast(BitsetStatusFlag::BIT6))) { - size_t length = urlData_.path.size(); - for (size_t i = 0; i < length; i++) { - if (i < length - 1) { - temp += urlData_.path[i] + "/"; - } else { - temp += urlData_.path[i]; - } - } - } else { - bool special = IsSpecial(urlData_.scheme); - if (!special) { - temp = ""; - } - } - NAPI_CALL(env_, napi_create_string_utf8(env_, temp.c_str(), temp.size(), &result)); - return result; -} - - -napi_value URL::GetPort() const -{ - napi_value result; - const char* temp = nullptr; - if (flags_.test(static_cast(BitsetStatusFlag::BIT5))) { - temp = std::to_string(urlData_.port).c_str(); - } else { - temp = ""; - } - size_t templen = strlen(temp); - NAPI_CALL(env_, napi_create_string_utf8(env_, temp, templen, &result)); - return result; -} - -napi_value URL::GetHost() const -{ - napi_value result; - std::string temp1 = urlData_.host; - if (flags_.test(static_cast(BitsetStatusFlag::BIT5))) { - temp1 += ":"; - temp1 += std::to_string(urlData_.port); - } - NAPI_CALL(env_, napi_create_string_utf8(env_, temp1.c_str(), temp1.size(), &result)); - return result; -} - -napi_value URL::GetOnOrOff() const -{ - napi_value result; - if (flags_.test(static_cast(BitsetStatusFlag::BIT0))) { - bool flag = false; - NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); - } else { - bool flag = true; - NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); - } - return result; -} - -napi_value URL::GetIsIpv6() const -{ - napi_value result; - if (flags_.test(static_cast(BitsetStatusFlag::BIT10))) { - bool flag = true; - NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); - } else { - bool flag = false; - NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); - } - return result; -} - -void URL::SetHostname(const std::string& input) -{ - if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { - return; - } - std::string strHost = input; - size_t length = strHost.size(); - for (size_t pos = 0; pos < length; pos++) { - if ((strHost[pos] == ':') || (strHost[pos] == '?') || (strHost[pos] == '#') || - (strHost[pos] == '/') || (strHost[pos] == '\\')) { - strHost = strHost.substr(0, pos); - break; - } - } - if (strHost.size() == 0) { - return; - } - bool special = IsSpecial(urlData_.scheme); - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; - std::string thisHostname = ""; - AnalysisHost(strHost, thisHostname, thisFlags, special); - if (thisFlags.test(static_cast(BitsetStatusFlag::BIT4))) { - if ((urlData_.scheme == "file:") && (thisHostname == "localhost")) { - thisHostname = ""; - } - urlData_.host = thisHostname; - flags_.set(static_cast(BitsetStatusFlag::BIT4)); - } -} - -void URL::SetHref(const std::string& input) -{ - std::string str = input; - DeleteC0OrSpace(str); - DeleteTabOrNewline(str); - UrlData thisNewUrl; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisNewFlags; - InitOnlyInput(str, thisNewUrl, thisNewFlags); - if (!thisNewFlags.test(static_cast(BitsetStatusFlag::BIT0))) { - urlData_ = thisNewUrl; - flags_ = thisNewFlags; - } -} - -void URL::SetPath(const std::string& input) -{ - std::string strPath = input; - if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { - return; - } - if (strPath.empty()) { - return; - } - std::string oldstr = "%3A"; - std::string newstr = ":"; - ReplaceSpecialSymbols(strPath, oldstr, newstr); - bool special = IsSpecial(urlData_.scheme); - if (urlData_.scheme == "file:") { - UrlData thisFileDate; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFileFlag; - if ((strPath[0] == '/') || (strPath[0] == '\\' && - flags_.test(static_cast(BitsetStatusFlag::BIT1)))) { - strPath = strPath.substr(1); - } - AnalysisFilePath(strPath, thisFileDate, thisFileFlag); - if (thisFileFlag.test(static_cast(BitsetStatusFlag::BIT6))) { - urlData_.path = thisFileDate.path; - flags_.set(static_cast(BitsetStatusFlag::BIT6)); - } - } else { - std::vector thisPath; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; - if ((strPath[0] == '/') || (strPath[0] == '\\' && - flags_.test(static_cast(BitsetStatusFlag::BIT1)))) { - strPath = strPath.substr(1); - } - AnalysisPath(strPath, thisPath, thisFlags, special); - if (thisFlags.test(static_cast(BitsetStatusFlag::BIT6))) { - urlData_.path = thisPath; - flags_.set(static_cast(BitsetStatusFlag::BIT6)); - } - } -} - -void SplitString(const std::string& input, std::string& strHost, std::string& port) -{ - size_t strlen = input.size(); - for (size_t pos = 0; pos < strlen; pos++) { - if ((input[pos] == ':') || (input[pos] == '?') || (input[pos] == '#') || - (input[pos] == '/') || (input[pos] == '\\')) { - strHost = input.substr(0, pos); - if (input[pos] == ':') { - pos++; - port = input.substr(pos); - } - break; - } - } -} - -void URL::SetHost(const std::string& input) -{ - if (flags_.test(static_cast(BitsetStatusFlag::BIT9))) { - return; - } - if (input.empty()) { - return; - } - std::string strHost = input; - std::string port = ""; - SplitString(input, strHost, port); - if (strHost.size() == 0) { - return; - } - bool special = IsSpecial(urlData_.scheme); - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> hostnameflags; - std::string thisHostname = ""; - AnalysisHost(strHost, thisHostname, hostnameflags, special); - if (hostnameflags.test(static_cast(BitsetStatusFlag::BIT4))) { - if ((urlData_.scheme == "file:") && (thisHostname == "localhost")) { - thisHostname = ""; - } - urlData_.host = thisHostname; - flags_.set(static_cast(BitsetStatusFlag::BIT4)); - } else { - return; - } - if (port.size() > 0) { - size_t strlen = port.size(); - for (size_t pos = 0; pos < strlen; pos++) { - if ((port[pos] == '?') || (port[pos] == '#') || (port[pos] == '/') || (port[pos] == '\\')) { - port = port.substr(0, pos); - break; - } - } - if (port.size() > 0) { - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; - UrlData thisport; - AnalysisPort(port, thisport, thisFlags); - if (thisFlags.test(static_cast(BitsetStatusFlag::BIT5))) { - flags_.set(static_cast(BitsetStatusFlag::BIT5)); - urlData_.port = thisport.port; - } - } - } -} - -void URL::SetPort(const std::string& input) -{ - std::string port = input; - size_t portlen = port.size(); - for (size_t pos = 0; pos < portlen; pos++) { - if ((port[pos] == '?') || (port[pos] == '#') || (port[pos] == '/') || (port[pos] == '\\')) { - port = port.substr(0, pos); - break; - } - } - if (port.size() > 0) { - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; - UrlData thisport; - AnalysisPort(port, thisport, thisFlags); - if (thisFlags.test(static_cast(BitsetStatusFlag::BIT5))) { - flags_.set(static_cast(BitsetStatusFlag::BIT5)); - urlData_.port = thisport.port; - } - } -} - -void URL::SetSearch(const std::string& input) -{ - std::string temp; - if (input.size() == 0) { - urlData_.query = ""; - flags_.set(static_cast(BitsetStatusFlag::BIT7), 0); - } else { - if (input[0] != '?') { - temp = "?"; - temp += input; - } else { - temp = input; - } - std::string oldstr = "#"; - std::string newstr = "%23"; - ReplaceSpecialSymbols(temp, oldstr, newstr); - AnalysisQuery(temp, urlData_.query, flags_); - } -} - -void URL::SetFragment(const std::string& input) -{ - std::string temp; - if (input.size() == 0) { - urlData_.fragment = ""; - flags_.set(static_cast(BitsetStatusFlag::BIT8), 0); - } else { - if (input[0] != '#') { - temp = "#"; - temp += input; - } else { - temp = input; - } - AnalysisFragment(temp, urlData_.fragment, flags_); - } -} - -void URL::SetScheme(const std::string& input) -{ - std::string strInput = input; - bool special = IsSpecial(urlData_.scheme); - bool inputIsSpecial = IsSpecial(input); - if ((special != inputIsSpecial) || ((input == "file") && - (flags_.test(static_cast(BitsetStatusFlag::BIT2)) || - flags_.test(static_cast(BitsetStatusFlag::BIT3)) || - flags_.test(static_cast(BitsetStatusFlag::BIT5))))) { - return; - } - std::string thisScheme = ""; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> thisFlags; - if (AnalysisScheme(strInput, thisScheme, thisFlags)) { - if (thisFlags.test(static_cast(BitsetStatusFlag::BIT1))) { - flags_.set(static_cast(BitsetStatusFlag::BIT1)); - } - urlData_.scheme = thisScheme; - } -} - -void URL::SetUsername(const std::string& input) -{ - if (input.size() == 0) { - urlData_.username = ""; - flags_.set(static_cast(BitsetStatusFlag::BIT2), 0); - } else { - if (!input.empty()) { - std::string usname = input; - std::string oldstr = "@"; - std::string newstr = "%40"; - ReplaceSpecialSymbols(usname, oldstr, newstr); - oldstr = "/"; - newstr = "%2F"; - ReplaceSpecialSymbols(usname, oldstr, newstr); - urlData_.username = usname; - flags_.set(static_cast(BitsetStatusFlag::BIT2)); - } - } -} - -void URL::SetPassword(const std::string& input) -{ - if (input.size() == 0) { - urlData_.password = ""; - flags_.set(static_cast(BitsetStatusFlag::BIT3), 0); - } else { - if (!input.empty()) { - std::string keyWord = input; - std::string oldstr = "@"; - std::string newstr = "%40"; - ReplaceSpecialSymbols(keyWord, oldstr, newstr); - oldstr = "/"; - newstr = "%2F"; - ReplaceSpecialSymbols(keyWord, oldstr, newstr); - urlData_.password = keyWord; - flags_.set(static_cast(BitsetStatusFlag::BIT3)); - } - } -} - -void URL::InitOnlyInput(std::string& input, UrlData& urlData, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags) -{ - if (input.empty()) { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } - if (input.find(':') != std::string::npos) { - size_t pos = input.find(':'); - pos++; - std::string scheme = input.substr(0, pos); - if (!AnalysisScheme(scheme, urlData.scheme, flags)) { - return; - } - if (input.find('#') != std::string::npos) { - size_t i = input.find('#'); - std::string fragment = input.substr(i); - AnalysisFragment(fragment, urlData.fragment, flags); - input = input.substr(0, i); - } - if (input.find('?') != std::string::npos) { - size_t i = input.find('?'); - std::string query = input.substr(i); - AnalysisQuery(query, urlData.query, flags); - input = input.substr(0, i); - } - std::string str = input.substr(pos); - if (urlData.scheme == "file:") { - AnalysisFile(str, urlData, flags); - } else { - AnalysisHostAndPath(str, urlData, flags); - } - } else { - flags.set(static_cast(BitsetStatusFlag::BIT0)); - return; - } -} - -URLSearchParams::URLSearchParams(napi_env env) : env(env) -{} -std::wstring StrToWstr(const std::string& str) -{ - setlocale(LC_ALL, ""); - std::wstring wstr = L""; - size_t len = str.size() + 1; - if (len > 0) { - auto wch = new wchar_t[len]; - mbstowcs(wch, str.c_str(), len); - wstr = wch; - delete[] wch; - setlocale(LC_ALL, ""); - return wstr; - } - return wstr; -} - -bool IsEscapeRange(const char charaEncode) -{ - if ((charaEncode > 0 && charaEncode < '*') || - (charaEncode > '*' && charaEncode < '-') || - (charaEncode == '/') || - (charaEncode > '9' && charaEncode < 'A') || - (charaEncode > 'Z' && charaEncode < '_') || - (charaEncode == '`') || - (charaEncode > 'z')) { - return true; - } - return false; -} - -size_t CharToUnicode(std::string str, size_t &i) -{ - size_t bytOfSpeChar = 3; // 3:Bytes of special characters in Linux - std::string subStr = str.substr(i, bytOfSpeChar); - i += 2; // 2:Searching for the number and number of keys and values - std::wstring wstr = StrToWstr(subStr.c_str()); - wchar_t wch = wstr[0]; - auto charaEncode = static_cast(wch); - return charaEncode; -} -std::string ReviseStr(std::string str, std::string* reviseChar) -{ - const size_t lenStr = str.length(); - if (lenStr == 0) { - return ""; - } - std::string output = ""; - size_t numOfAscii = 128; // 128:Number of ASCII characters - size_t i = 0; - for (; i < lenStr; i++) { - auto charaEncode = static_cast(str[i]); - if (charaEncode < 0 || charaEncode >= numOfAscii) { - charaEncode = CharToUnicode(str, i); - } - if (charaEncode >= 0 && charaEncode < numOfAscii) { - // 2:Defines the escape range of ASCII characters - if (IsEscapeRange(charaEncode)) { - output += reviseChar[charaEncode]; - } else { - output += str.substr(i, 1); - } - } else if (charaEncode <= 0x000007FF) { // Convert the Unicode code into two bytes - std::string output1 = reviseChar[0x000000C0 | - (charaEncode / 64)]; // 64:Acquisition method of the first byte - std::string output2 = reviseChar[numOfAscii | - (charaEncode & 0x0000003F)]; // Acquisition method of the second byte - output += output1 + output2; - } else if ((charaEncode >= 0x0000E000) || - (charaEncode <= 0x0000D7FF)) { // Convert the Unicode code into three bytes - std::string output1 = reviseChar[0x000000E0 | - (charaEncode / 4096)]; // 4096:Acquisition method of the first byte - std::string output2 = reviseChar[numOfAscii | - ((charaEncode / 64) & 0x0000003F)]; // 64:method of the second byte - std::string output3 = reviseChar[numOfAscii | - (charaEncode & 0x0000003F)]; // Acquisition method of the third byte - output += output1 + output2 + output3; - } else { - const size_t charaEncode1 = static_cast(str[++i]) & 1023; // 1023:Convert codes - charaEncode = 65536 + (((charaEncode & 1023) << 10) | - charaEncode1); // 65536:Specific transcoding method - std::string output1 = reviseChar[0x000000F0 | - (charaEncode / 262144)]; // 262144:Acquisition method of the first byte - std::string output2 = reviseChar[numOfAscii | - ((charaEncode / 4096) & 0x0000003F)]; // 4096:Acquisition method of the second byte - std::string output3 = reviseChar[numOfAscii | - ((charaEncode / 64) & 0x0000003F)]; // 64:Acquisition method of the third byte - std::string output4 = reviseChar[numOfAscii | - (charaEncode & 0x0000003F)]; // Acquisition method of the fourth byte - output += output1 + output2 + output3 + output4; - } - } - return output; -} - -napi_value URLSearchParams::ToString() -{ - std::string output = ""; - std::string reviseChar[256] = {""}; // 256:Array length - for (size_t i = 0; i < 256; ++i) { // 256:Array length - size_t j = i; - std::stringstream ioss; - std::string str1 = ""; - ioss << std::hex << j; - ioss >> str1; - transform(str1.begin(), str1.end(), str1.begin(), ::toupper); - if (i < 16) { // 16:Total number of 0-F - reviseChar[i] = '%' + ("0" + str1); - } else { - reviseChar[i] = '%' + str1; - } - } - reviseChar[0x20] = "+"; // 0x20:ASCII value of spaces - const size_t lenStr = searchParams.size(); - if (lenStr == 0) { - napi_value result = nullptr; - napi_create_string_utf8(env, output.c_str(), output.size(), &result); - return result; - } - std::string firstStrKey = ReviseStr(searchParams[0], reviseChar); - std::string firstStrValue = ReviseStr(searchParams[1], reviseChar); - output = firstStrKey + "=" + firstStrValue; - if (lenStr % 2 == 0) { // 2:Divisible by 2 - size_t i = 2; // 2:Initial Position - for (; i < lenStr; i += 2) { // 2:Searching for the number and number of keys and values - std::string strKey = ReviseStr(searchParams[i], reviseChar); - std::string strValue = ReviseStr(searchParams[i + 1], reviseChar); - output += +"&" + strKey + "=" + strValue; - } - } - napi_value result = nullptr; - napi_create_string_utf8(env, output.c_str(), output.size(), &result); - return result; -} -void URLSearchParams::HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it) -{ - std::wstring::iterator iter = inputStr.begin(); - advance(iter, std::distance(iter, it)); - while (iter != inputStr.end()) { - char16_t ch = *iter; - if (!((ch & 0xF800) == 0xD800)) { - ++iter; - continue; - } else if ((ch & 0x400) != 0 || iter == inputStr.end() - 1) { - *iter = 0xFFFD; - } else { - char16_t dh = *(iter + 1); - if ((dh & 0xFC00) == 0xDC00) { - ++iter; - } else { - *iter = 0xFFFD; - } - } - ++iter; - } -} -std::string URLSearchParams::ToUSVString(std::string inputStr) -{ - size_t strLen = strlen(inputStr.c_str()); - wchar_t* strPtr = nullptr; - std::wstring winput = L""; - int strSize = mbstowcs(strPtr, inputStr.c_str(), 0) + 1; - if (strSize > 0) { - strPtr = new wchar_t[strSize]; - mbstowcs(strPtr, inputStr.c_str(), strLen); - winput = strPtr; - } - const char* expr = "(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])"; - size_t exprLen = strlen(expr); - wchar_t* exprPtr = nullptr; - int exprSize = mbstowcs(exprPtr, expr, 0) + 1; - if (exprSize > 0) { - exprPtr = new wchar_t[exprSize]; - mbstowcs(exprPtr, expr, exprLen); - } - std::wregex wexpr(exprPtr); - delete[] exprPtr; - std::wsmatch result; - delete[] strPtr; - std::wstring::const_iterator iterStart = winput.begin(); - std::wstring::const_iterator iterEnd = winput.end(); - if (!regex_search(iterStart, iterEnd, result, wexpr)) { - return inputStr; - } - HandleIllegalChar(winput, result[0].first); - size_t inputLen = wcslen(winput.c_str()); - char* rePtr = nullptr; - std::string reStr = ""; - int reSize = wcstombs(rePtr, winput.c_str(), 0) + 1; - if (reSize > 0) { - rePtr = new char[reSize]; - if (memset_s(rePtr, reSize, 0, reSize) != 0) { - HILOG_ERROR("ToUSVString memset_s failed"); - delete[] rePtr; - return reStr; - } else { - wcstombs(rePtr, winput.c_str(), inputLen); - reStr = rePtr; - } - } - delete[] rePtr; - return reStr; -} -napi_value URLSearchParams::Get(napi_value buffer) -{ - char* name = nullptr; - size_t nameSize = 0; - std::string temp = ""; - napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); - if (nameSize > 0) { - name = new char[nameSize + 1]; - napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); - temp = name; - } - std::string sname = ToUSVString(temp); - delete[] name; - napi_value result = nullptr; - if (searchParams.size() == 0) { - return result; - } - size_t size = searchParams.size() - 1; - for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values - if (searchParams[i] == sname) { - std::string str = searchParams[i + 1]; - napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &result); - return result; - } - } - return result; -} -napi_value URLSearchParams::GetAll(napi_value buffer) -{ - char* name = nullptr; - size_t nameSize = 0; - std::string sname = ""; - napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); - if (nameSize > 0) { - name = new char[nameSize + 1]; - napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); - sname = ToUSVString(name); - } - delete[] name; - napi_value result = nullptr; - napi_value napiStr = nullptr; - NAPI_CALL(env, napi_create_array(env, &result)); - size_t flag = 0; - if (searchParams.size() == 0) { - return result; - } - size_t size = searchParams.size() - 1; - for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values - if (searchParams[i] == sname) { - napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &napiStr); - napi_status status = napi_set_element(env, result, flag, napiStr); - if (status != napi_ok) { - HILOG_INFO("set element error"); - } - flag++; - } - } - return result; -} -void URLSearchParams::Append(napi_value buffer, napi_value temp) -{ - char* name = nullptr; - size_t nameSize = 0; - std::string tempName = ""; - std::string tempValue = ""; - napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); - if (nameSize > 0) { - name = new char[nameSize + 1]; - napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); - tempName = name; - } - char* value = nullptr; - size_t valueSize = 0; - napi_get_value_string_utf8(env, temp, nullptr, 0, &valueSize); - if (valueSize > 0) { - value = new char[valueSize + 1]; - napi_get_value_string_utf8(env, temp, value, valueSize + 1, &valueSize); - tempValue = value; - } - searchParams.push_back(tempName); - searchParams.push_back(tempValue); - delete[] name; - delete[] value; -} -void URLSearchParams::Delete(napi_value buffer) -{ - char* name = nullptr; - size_t nameSize = 0; - std::string sname = ""; - napi_get_value_string_utf8(env, buffer, nullptr, 0, &nameSize); - if (nameSize > 0) { - name = new char[nameSize + 1]; - napi_get_value_string_utf8(env, buffer, name, nameSize + 1, &nameSize); - sname = ToUSVString(name); - } - delete[] name; - for (std::vector::iterator iter = searchParams.begin(); iter != searchParams.end();) { - if (*iter == sname) { - iter = searchParams.erase(iter, iter + 2); // 2:Searching for the number and number of keys and values - } else { - iter += 2; // 2:Searching for the number and number of keys and values - } - } -} -napi_value URLSearchParams::Entries() const -{ - napi_value resend = nullptr; - napi_value firNapiStr = nullptr; - napi_value secNapiStr = nullptr; - napi_create_array(env, &resend); - if (searchParams.size() == 0) { - return resend; - } - size_t size = searchParams.size() - 1; - for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values - napi_value result = nullptr; - napi_create_array(env, &result); - - napi_create_string_utf8(env, searchParams[i].c_str(), searchParams[i].length(), &firNapiStr); - napi_create_string_utf8(env, searchParams[i + 1].c_str(), searchParams[i + 1].length(), &secNapiStr); - napi_set_element(env, result, 0, firNapiStr); - napi_set_element(env, result, 1, secNapiStr); - napi_set_element(env, resend, i / 2, result); // 2:Find the number of keys - } - return resend; -} -void URLSearchParams::ForEach(napi_value function, napi_value thisVar) -{ - if (searchParams.size() == 0) { - return; - } - size_t size = searchParams.size() - 1; - for (size_t i = 0; i < size; i += 2) { // 2:Searching for the number and number of keys and values - napi_value returnVal = nullptr; - size_t argc = 3; - napi_value global = nullptr; - napi_get_global(env, &global); - napi_value key = nullptr; - napi_create_string_utf8(env, searchParams[i].c_str(), strlen(searchParams[i].c_str()), &key); - napi_value value = nullptr; - napi_create_string_utf8(env, searchParams[i + 1].c_str(), strlen(searchParams[i + 1].c_str()), &value); - napi_value argv[3] = {key, value, thisVar}; - napi_call_function(env, global, function, argc, argv, &returnVal); - } -} -napi_value URLSearchParams::IsHas(napi_value name) const -{ - char* buffer = nullptr; - size_t bufferSize = 0; - std::string buf = ""; - napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize); - if (bufferSize > 0) { - buffer = new char[bufferSize + 1]; - napi_get_value_string_utf8(env, name, buffer, bufferSize + 1, &bufferSize); - buf = buffer; - } - bool flag = false; - napi_value result = nullptr; - size_t lenStr = searchParams.size(); - for (size_t i = 0; i != lenStr; i += 2) { // 2:Searching for the number and number of keys and values - if (searchParams[i] == buf) { - flag = true; - napi_get_boolean(env, flag, &result); - return result; - } - } - delete []buffer; - napi_get_boolean(env, flag, &result); - return result; -} -void URLSearchParams::Set(napi_value name, napi_value value) -{ - char* buffer0 = nullptr; - size_t bufferSize0 = 0; - std::string cppName = ""; - std::string cppValue = ""; - napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize0); - if (bufferSize0 > 0) { - buffer0 = new char[bufferSize0 + 1]; - napi_get_value_string_utf8(env, name, buffer0, bufferSize0 + 1, &bufferSize0); - cppName = buffer0; - delete[] buffer0; - } - char* buffer1 = nullptr; - size_t bufferSize1 = 0; - napi_get_value_string_utf8(env, value, nullptr, 0, &bufferSize1); - if (bufferSize1 > 0) { - buffer1 = new char[bufferSize1 + 1]; - napi_get_value_string_utf8(env, value, buffer1, bufferSize1 + 1, &bufferSize1); - cppValue = buffer1; - delete[] buffer1; - } - bool flag = false; - for (std::vector::iterator it = searchParams.begin(); it < searchParams.end() - 1;) { - if (*it == cppName) { - if (!flag) { - *(it + 1) = cppValue; - flag = true; - it += 2; // 2:Searching for the number and number of keys and values - } else { - it = searchParams.erase(it, it + 2); // 2:Searching for the number and number of keys and values - } - } else { - it += 2; // 2:Searching for the number and number of keys and values - } - } - if (!flag) { - searchParams.push_back(cppName); - searchParams.push_back(cppValue); - } -} -void URLSearchParams::Sort() -{ - unsigned int len = searchParams.size(); - if (len <= 2 && (len % 2 != 0)) { // 2: Iterate over key-value pairs - return; - } - unsigned int i = 0; - for (; i < len - 2; i += 2) { // 2:Iterate over key-value pairs - unsigned int j = i + 2; // 2:Iterate over key-value pairs - for (; j < len; j += 2) { // 2:Iterate over key-value pairs - bool tmp = (searchParams[i] > searchParams[j]); - if (tmp) { - const std::string curKey = searchParams[i]; - const std::string curVal = searchParams[i + 1]; - searchParams[i] = searchParams[j]; - searchParams[i + 1] = searchParams[j + 1]; - searchParams[j] = curKey; - searchParams[j + 1] = curVal; - } - } - } -} -napi_value URLSearchParams::IterByKeys() -{ - std::vector toKeys; - napi_value result = nullptr; - napi_value napiStr = nullptr; - napi_create_array(env, &result); - size_t stepSize = 2; // 2:Searching for the number and number of keys and values - size_t lenStr = searchParams.size(); - if (lenStr % 2 == 0) { // 2:Get the number of values - for (std::vector::iterator it = searchParams.begin(); it != searchParams.end(); it += stepSize) { - toKeys.push_back(*it); - } - size_t lenToKeys = toKeys.size(); - for (size_t i = 0; i < lenToKeys; i++) { - napi_create_string_utf8(env, toKeys[i].c_str(), toKeys[i].length(), &napiStr); - napi_set_element(env, result, i, napiStr); - } - } - return result; -} -napi_value URLSearchParams::IterByValues() -{ - std::vector toKeys; - napi_value result = nullptr; - napi_value napiStr = nullptr; - napi_create_array(env, &result); - size_t stepSize = 2; // 2:Searching for the number and number of keys and values - size_t lenStr = searchParams.size(); - if (lenStr % 2 == 0) { // 2:Get the number of values - for (std::vector::iterator it = searchParams.begin(); it != searchParams.end(); it += stepSize) { - toKeys.push_back(*(it + 1)); - } - size_t lenToKeys = toKeys.size(); - for (size_t i = 0; i < lenToKeys; i++) { - napi_create_string_utf8(env, toKeys[i].c_str(), toKeys[i].length(), &napiStr); - napi_set_element(env, result, i, napiStr); - } - } - return result; -} -void URLSearchParams::SetArray(const std::vector vec) -{ - searchParams = vec; -} -napi_value URLSearchParams::GetArray() const -{ - napi_value arr = nullptr; - napi_create_array(env, &arr); - size_t length = searchParams.size(); - for (size_t i = 0; i < length; i++) { - napi_value result = nullptr; - napi_create_string_utf8(env, searchParams[i].c_str(), searchParams[i].size(), &result); - napi_set_element(env, arr, i, result); - } - return arr; -} \ No newline at end of file diff --git a/url/js_url.h b/url/js_url.h deleted file mode 100644 index 29c306456897eccd0989493e164def24a695e7b7..0000000000000000000000000000000000000000 --- a/url/js_url.h +++ /dev/null @@ -1,119 +0,0 @@ - /* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef COMPILERUNTIME_JS_API_URL_H -#define COMPILERUNTIME_JS_API_URL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -enum class BitsetStatusFlag { - BIT0 = 0, // 0:Bit 0 Set to true,The URL analysis failed - BIT1 = 1, // 1:Bit 1 Set to true,The protocol is the default protocol - BIT2 = 2, // 2:Bit 2 Set to true,The URL has username - BIT3 = 3, // 3:Bit 3 Set to true,The URL has password - BIT4 = 4, // 4:Bit 4 Set to true,The URL has hostname - BIT5 = 5, // 5:Bit 5 Set to true,The URL Port is the specially - BIT6 = 6, // 6:Bit 6 Set to true,The URL has pathname - BIT7 = 7, // 7:Bit 7 Set to true,The URL has query - BIT8 = 8, // 8:Bit 8 Set to true,The URL has fragment - BIT9 = 9, // 9:Bit 9 Set to true,The URL Can not be base - BIT10 = 10, // 10:Bit 10 Set to true,The host is IPV6 - BIT_STATUS_11 = 11 // 11:Each bit of a BIT represents a different parsing state. -}; - -struct UrlData { - int port = -1; - std::vector path; - std::string password = ""; - std::string scheme = ""; - std::string query = ""; - std::string username = ""; - std::string fragment = ""; - std::string host = ""; -}; - -class URL { -public: - URL(napi_env env, const std::string& input); - URL(napi_env env, const std::string& input, const std::string& base); - URL(napi_env env, const std::string& input, const URL& base); - - napi_value GetHostname() const; - void SetHostname(const std::string& input); - void SetUsername(const std::string& input); - void SetPassword(const std::string& input); - void SetScheme(const std::string& input); - void SetFragment(const std::string& input); - void SetSearch(const std::string& input); - void SetHost(const std::string& input); - void SetPort(const std::string& input); - void SetHref(const std::string& input); - void SetPath(const std::string& input); - - napi_value GetSearch() const; - napi_value GetUsername() const; - napi_value GetPassword() const; - napi_value GetFragment() const; - napi_value GetScheme() const; - napi_value GetPath() const; - napi_value GetPort() const; - napi_value GetOnOrOff() const; - napi_value GetIsIpv6() const; - napi_value GetHost() const; - - static void InitOnlyInput(std::string& input, UrlData& urlData, - std::bitset(BitsetStatusFlag::BIT_STATUS_11)>& flags); - virtual ~URL() {} -private: - UrlData urlData_; - std::bitset(BitsetStatusFlag::BIT_STATUS_11)> flags_; - // bitset<11>:Similar to bool array, each bit status represents the real-time status of current URL parsing - napi_env env_ = nullptr; -}; - -class URLSearchParams { -public: - explicit URLSearchParams(napi_env env); - virtual ~URLSearchParams() {} - napi_value IsHas(napi_value name) const; - napi_value Get(napi_value buffer); - napi_value GetAll(napi_value buffer); - void Append(napi_value buffer, napi_value temp); - void Delete(napi_value buffer); - void ForEach(napi_value function, napi_value thisVar); - napi_value Entries() const; - void Set(napi_value name, napi_value value); - void Sort(); - napi_value ToString(); - napi_value IterByKeys(); - napi_value IterByValues(); - void SetArray(std::vector input); - napi_value GetArray() const; - std::vector StringParmas(std::string Stringpar); -private: - std::string ToUSVString(std::string inputStr); - void HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it); - std::vector searchParams; - napi_env env; -}; -#endif /* COMPILERUNTIME_JS_API_URL_H */ diff --git a/url/native_module_url.cpp b/url/native_module_url.cpp deleted file mode 100644 index c08aa9929315aecf166b56b22e5578c5caba01f5..0000000000000000000000000000000000000000 --- a/url/native_module_url.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "utils/log.h" -#include "js_url.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -extern const char _binary_js_url_js_start[]; -extern const char _binary_js_url_js_end[]; - -static void UrlStructor(napi_env &env, napi_callback_info &info, URL* &object) -{ - napi_value thisVar = nullptr; - size_t argc = 2; - napi_value argv[2] = { 0 }; - void* data = nullptr; - napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data); - napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); - napi_valuetype valuetype1; - napi_valuetype valuetype2; - std::string input = ""; - napi_typeof(env, argv[0], &valuetype1); - if (valuetype1 == napi_string) { - char* tem = nullptr; - size_t temlen = 0; - napi_get_value_string_utf8(env, argv[0], nullptr, 0, &temlen); - if (temlen > 0) { - tem = new char[temlen + 1]; - napi_get_value_string_utf8(env, argv[0], tem, temlen + 1, &temlen); - input = tem; - delete[] tem; - } - napi_typeof(env, argv[1], &valuetype2); - if (valuetype2 == napi_string) { - std::string base = ""; - char* type1 = nullptr; - size_t typelen1 = 0; - napi_get_value_string_utf8(env, argv[1], nullptr, 0, &typelen1); - if (typelen1 > 0) { - type1 = new char[typelen1 + 1]; - napi_get_value_string_utf8(env, argv[1], type1, typelen1 + 1, &typelen1); - base = type1; - delete[] type1; - } - object = new URL(env, input, base); - } else if (valuetype2 == napi_object) { - URL* temp = nullptr; - napi_unwrap(env, argv[1], (void**)&temp); - object = new URL(env, input, *temp); - } else { - HILOG_INFO("secondParameter error"); - } - } else { - HILOG_INFO("firstParameter error"); - } - return; -} - -static napi_value UrlConstructor(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - void* data = nullptr; - size_t argc = 0; - napi_value argv[2] = { 0 }; - URL* object = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data)); - if (argc == 1) { - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); - napi_valuetype valuetype; - NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); - if (valuetype == napi_string) { - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - delete[] type; - } - object = new URL(env, input); - } else { - HILOG_INFO("Parameter error"); - } - } else if (argc == 2) { // 2:When the input parameter is set to 2 - UrlStructor(env, info, object); - } - napi_wrap( - env, thisVar, object, - [](napi_env env, void* data, void* hint) { - auto object = (URL*)data; - if (object != nullptr) { - delete object; - } - }, - nullptr, nullptr); - return thisVar; -} - -static napi_value GetHostname(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetHostname(); - return retVal; -} - -static napi_value GetSearch(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetSearch(); - return retVal; -} - -static napi_value GetUsername(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetUsername(); - return retVal; -} - -static napi_value GetPassword(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetPassword(); - return retVal; -} - -static napi_value GetFragment(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetFragment(); - return retVal; -} - -static napi_value GetScheme(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetScheme(); - return retVal; -} - -static napi_value GetPort(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetPort(); - return retVal; -} - -static napi_value GetHost(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetHost(); - return retVal; -} - -static napi_value GetPath(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetPath(); - return retVal; -} - -static napi_value GetOnOrOff(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetOnOrOff(); - return retVal; -} - -static napi_value GetIsIpv6(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetIsIpv6(); - return retVal; -} - -static napi_value SetHref(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetHref(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetHostname(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetHostname(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetPort(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetPort(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetHost(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetHost(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetSearch(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetSearch(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetScheme(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetScheme(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetFragment(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetFragment(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetUsername(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetUsername(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetPath(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetPath(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SetPassword(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); - char* type = nullptr; - size_t typelen = 0; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen)); - if (typelen > 0) { - type = new char[typelen + 1]; - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen)); - input = type; - } - if (type != nullptr) { - delete[] type; - type = nullptr; - } - URL* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetPassword(input); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value SeachParamsConstructor(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - void* data = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data)); - auto object = new URLSearchParams(env); - napi_wrap( - env, thisVar, object, - [](napi_env env, void* data, void* hint) { - auto object = (URLSearchParams*)data; - if (object != nullptr) { - delete object; - } - }, - nullptr, nullptr); - return thisVar; -} - -static napi_value SetArray(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - uint32_t length = 0; - napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); - napi_get_array_length(env, argv[0], &length); - std::vector vec; - size_t arraySize = 0; - napi_value napiStr = nullptr; - for (size_t i = 0; i < length; i++) { - char* cstr = nullptr; - napi_get_element(env, argv[0], i, &napiStr); - napi_get_value_string_utf8(env, napiStr, nullptr, 0, &arraySize); - if (arraySize > 0) { - cstr = new char[arraySize + 1]; - napi_get_value_string_utf8(env, napiStr, cstr, arraySize + 1, &arraySize); - vec.push_back(cstr); - delete []cstr; - cstr = nullptr; - } else { - vec.push_back(""); - } - } - URLSearchParams* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - murl->SetArray(vec); - napi_value result = nullptr; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -static napi_value GetArray(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - URLSearchParams* murl = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&murl)); - napi_value retVal = murl->GetArray(); - return retVal; -} - -static napi_value Get(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 1; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - if (argc != 1) { - HILOG_INFO("One arg needs to be specified"); - return nullptr; - } - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->Get(args); - return result; -} - -static napi_value GetAll(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 1; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - if (argc != 1) { - HILOG_INFO("One arg needs to be specified"); - return nullptr; - } - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->GetAll(args); - return result; -} - -static napi_value Append(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 2; - napi_value args[2] = { 0 }; - void* data = nullptr; - napi_get_cb_info(env, info, &argc, args, &thisVar, &data); - if (argc != 2) { // 2:If the input parameter is not set to 2, - HILOG_INFO("Two args needs to be specified"); - return nullptr; - } - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - object->Append(args[0], args[1]); - return nullptr; -} - -static napi_value Delete(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 1; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - if (argc != 1) { - HILOG_INFO("One arg needs to be specified"); - return nullptr; - } - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - object->Delete(args); - return nullptr; -} - -static napi_value ForEach(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 1; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - object->ForEach(args, thisVar); - return nullptr; -} - -static napi_value Entries(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 0; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->Entries(); - return result; -} - -static napi_value IsHas(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 1; - napi_value args = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); - URLSearchParams* object = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); - napi_value result = object->IsHas(args); - return result; -} - -static napi_value Set(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 2; - napi_value args[2] = { 0 }; - napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - object->Set(args[0], args[1]); - return nullptr; -} - -static napi_value Sort(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 0; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - object->Sort(); - return nullptr; -} - -static napi_value ToString(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 0; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->ToString(); - return result; -} - -static napi_value IterByKeys(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 0; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->IterByKeys(); - return result; -} - -static napi_value IterByValues(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - size_t argc = 0; - napi_value args = nullptr; - napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr); - URLSearchParams* object = nullptr; - napi_unwrap(env, thisVar, (void**)&object); - napi_value result = object->IterByValues(); - return result; -} - -static void IsPlusSign(size_t &strLastPos, size_t &iteaor, std::string &buf, std::string &stringParm) -{ - if (strLastPos < iteaor) { - buf += stringParm.substr(strLastPos, iteaor - strLastPos); - } - buf += ""; - strLastPos = iteaor + 1; - return; -} -static void IsEqualSign(size_t &strLastPos, size_t &iteaor, - std::string &buf, std::string &stringParm, std::vector &seachParasVec) -{ - if (strLastPos < iteaor) { - buf += stringParm.substr(strLastPos, iteaor - strLastPos); - } - seachParasVec.push_back(buf); - buf = ""; - strLastPos = iteaor + 1; - return; -} - -static void IsAddressSign(size_t &strLastPos, size_t &iteaor, std::string &buf, - std::string &stringParm, std::vector &seachParasVec) -{ - if (strLastPos < iteaor) { - buf += stringParm.substr(strLastPos, iteaor - strLastPos); - } - seachParasVec.push_back(buf); - return; -} -static void DealParmsString(size_t &strLastPos, size_t &iteaor, std::string &buf, - std::string &stringParm, std::vector &seachParasVec) -{ - if (strLastPos < iteaor) { - buf += stringParm.substr(strLastPos, iteaor - strLastPos); - } - seachParasVec.push_back(buf); -} -static void IsEqualCode(size_t &strStartPos, size_t &iteaor, size_t &strLastPos) -{ - if (strStartPos == iteaor) { - strLastPos = iteaor + 1; - strStartPos = iteaor + 1; - } - return; -} -static std::vector StringParsing(std::string stringParm) -{ - std::vector seachParasVec; - size_t strStartPos = 0; - size_t strLastPos = 0; - bool isHasSpace = false; - std::string buf = ""; - size_t iteaor = 0; - for (iteaor = 0; iteaor < stringParm.length(); iteaor++) { - char code = stringParm[iteaor]; - switch (code) { - case '&': - { - IsEqualCode(strStartPos, iteaor, strLastPos); - IsAddressSign(strLastPos, iteaor, buf, stringParm, seachParasVec); - if (!isHasSpace) { - seachParasVec.push_back(""); - } - isHasSpace = false; - buf = ""; - strLastPos = iteaor + 1; - strStartPos = iteaor + 1; - break; - } - case '=': - { - if (isHasSpace) { - break; - } - IsEqualSign(strLastPos, iteaor, buf, stringParm, seachParasVec); - isHasSpace = true; - break; - } - case '+': - IsPlusSign(strLastPos, iteaor, buf, stringParm); - break; - default:break; - } - } - if (strStartPos == iteaor) { - return seachParasVec; - } - DealParmsString(strLastPos, iteaor, buf, stringParm, seachParasVec); - if (!isHasSpace) { - seachParasVec.push_back(""); - } - return seachParasVec; -} - -static napi_value StringParmas(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - napi_value argv[1] = {0}; - size_t argc = 1; - std::string input = ""; - napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); - char* type = nullptr; - size_t typelen = 0; - napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen); - if (typelen > 0) { - type = new char[typelen + 1]; - napi_get_value_string_utf8(env, argv[0], type, typelen + 1, &typelen); - input = type; - delete[] type; - } - std::vector seachParasmsString; - seachParasmsString = StringParsing(input); - napi_value arr = nullptr; - napi_create_array(env, &arr); - for (size_t i = 0; i < seachParasmsString.size(); i++) { - napi_value result = nullptr; - napi_create_string_utf8(env, seachParasmsString[i].c_str(), seachParasmsString[i].size(), &result); - napi_set_element(env, arr, i, result); - } - return arr; -} - -static napi_value SeachParamsInit(napi_env env, napi_value exports) -{ - const char *seachParamsClassName = "URLSearchParams"; - napi_value seachParamsInitClass = nullptr; - static napi_property_descriptor UrlDesc[] = { - DECLARE_NAPI_FUNCTION("has", IsHas), - DECLARE_NAPI_FUNCTION("set", Set), - DECLARE_NAPI_FUNCTION("sort", Sort), - DECLARE_NAPI_FUNCTION("toString", ToString), - DECLARE_NAPI_FUNCTION("keys", IterByKeys), - DECLARE_NAPI_FUNCTION("values", IterByValues), - DECLARE_NAPI_FUNCTION("get", Get), - DECLARE_NAPI_FUNCTION("getAll", GetAll), - DECLARE_NAPI_FUNCTION("append", Append), - DECLARE_NAPI_FUNCTION("delete", Delete), - DECLARE_NAPI_FUNCTION("forEach", ForEach), - DECLARE_NAPI_FUNCTION("entries", Entries), - DECLARE_NAPI_GETTER_SETTER("array", GetArray, SetArray), - }; - NAPI_CALL(env, napi_define_class(env, seachParamsClassName, strlen(seachParamsClassName), SeachParamsConstructor, - nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]), UrlDesc, &seachParamsInitClass)); - static napi_property_descriptor desc[] = { - DECLARE_NAPI_PROPERTY("URLSearchParams1", seachParamsInitClass) - }; - napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); - return exports; -}; - -static napi_value UrlInit(napi_env env, napi_value exports) -{ - const char *urlClassName = "Url"; - napi_value urlClass = nullptr; - static napi_property_descriptor UrlDesc[] = { - DECLARE_NAPI_GETTER_SETTER("hostname", GetHostname, SetHostname), - DECLARE_NAPI_FUNCTION("href", SetHref), - DECLARE_NAPI_GETTER_SETTER("search", GetSearch, SetSearch), - DECLARE_NAPI_GETTER_SETTER("username", GetUsername, SetUsername), - DECLARE_NAPI_GETTER_SETTER("password", GetPassword, SetPassword), - DECLARE_NAPI_GETTER_SETTER("host", GetHost, SetHost), - DECLARE_NAPI_GETTER_SETTER("hash", GetFragment, SetFragment), - DECLARE_NAPI_GETTER_SETTER("protocol", GetScheme, SetScheme), - DECLARE_NAPI_GETTER_SETTER("pathname", GetPath, SetPath), - DECLARE_NAPI_GETTER_SETTER("port", GetPort, SetPort), - DECLARE_NAPI_GETTER("onOrOff", GetOnOrOff), - DECLARE_NAPI_GETTER("GetIsIpv6", GetIsIpv6), - }; - NAPI_CALL(env, napi_define_class(env, urlClassName, strlen(urlClassName), UrlConstructor, - nullptr, sizeof(UrlDesc) / sizeof(UrlDesc[0]), UrlDesc, - &urlClass)); - static napi_property_descriptor desc[] = { - DECLARE_NAPI_PROPERTY("Url", urlClass) - }; - napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); - return exports; -} - -static napi_value Init(napi_env env, napi_value exports) -{ - napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("stringParmas", StringParmas), - }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); - SeachParamsInit(env, exports); - UrlInit(env, exports); - return exports; -} - -extern "C" -__attribute__((visibility("default"))) void NAPI_url_GetJSCode(const char** buf, int* bufLen) -{ - if (buf != nullptr) { - *buf = _binary_js_url_js_start; - } - - if (bufLen != nullptr) { - *bufLen = _binary_js_url_js_end - _binary_js_url_js_start; - } -} - -static napi_module UrlModule = { - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = Init, - .nm_modname = "url", - .nm_priv = ((void*)0), - .reserved = {0}, -}; -extern "C" __attribute__((constructor)) void RegisterModule() -{ - napi_module_register(&UrlModule); -} \ No newline at end of file