From 77080d1811e7a423cc68d7c134fe5fe1cbd31e7c Mon Sep 17 00:00:00 2001 From: lifansheng Date: Tue, 14 Sep 2021 14:27:00 +0800 Subject: [PATCH] codecheck Signed-off-by: lifansheng --- README.en.md | 145 +++ README.md | 306 ++--- {uri => api}/BUILD.gn | 25 +- url/js_url.js => api/js_api.js | 96 +- api/js_uri.cpp | 552 +++++++++ api/js_uri.h | 90 ++ api/js_url.cpp | 2122 ++++++++++++++++++++++++++++++++ api/js_url.h | 122 ++ api/native_module_api.cpp | 1186 ++++++++++++++++++ ohos.build | 2 +- uri/js_uri.cpp | 503 -------- uri/js_uri.h | 82 -- uri/js_uri.js | 81 -- uri/native_module_uri.cpp | 286 ----- url/BUILD.gn | 59 - url/js_url.cpp | 2119 ------------------------------- url/js_url.h | 119 -- url/native_module_url.cpp | 929 -------------- 18 files changed, 4439 insertions(+), 4385 deletions(-) create mode 100755 README.en.md rename {uri => api}/BUILD.gn (73%) rename url/js_url.js => api/js_api.js (82%) mode change 100644 => 100755 create mode 100755 api/js_uri.cpp create mode 100755 api/js_uri.h create mode 100755 api/js_url.cpp create mode 100755 api/js_url.h create mode 100755 api/native_module_api.cpp delete mode 100755 uri/js_uri.cpp delete mode 100755 uri/js_uri.h delete mode 100755 uri/js_uri.js delete mode 100755 uri/native_module_uri.cpp delete mode 100644 url/BUILD.gn delete mode 100644 url/js_url.cpp delete mode 100644 url/js_url.h delete mode 100644 url/native_module_url.cpp diff --git a/README.en.md b/README.en.md new file mode 100755 index 0000000..0d7b8f4 --- /dev/null +++ b/README.en.md @@ -0,0 +1,145 @@ +# js_api_module +# Introduction to URL +The URL interface 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. + +Interface introduction + +1.new URL(url: string,base?:string|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. + +2.tostring():string; + +The stringification method returns a USVString containing the complete URL. It is equivalent to the read-only URL.href. + +3.toJSON():string; + +This method returns a USVString, which contains a serialized URL version. + +The usage of each interface is as follows: + +let b = new URL('https://developer.mozilla.org'); // => 'https://developer.mozilla.org/' + +let a = new URL( 'sca/./path/path/../scasa/jjjjj', 'http://www.example.com'); +// => 'http://www.example.com/sca/path/scasa/jjjjj' + +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' + +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' + + +####2nd. Introduction to URLSreachParams + +The URLSearchParams interface defines some practical methods to process URL query strings. + +Interface introduction + +1.new URLSearchParams() + +The URLSearchParams() constructor has no parameters. This method creates and returns a new URLSearchParams object. The beginning'?' character will be ignored. + +2.new URLSearchParams(string) + +The input parameter of URLSearchParams(string) constructor is string data type. + +3.new URLSearchParams(obj) + +The input parameter of URLSearchParams(obj) constructor is obj data type. + +4.new URLSearchParams(iterable) + +The input parameter of URLSearchParams(iterable) constructor is iterable data type. + +5.isHas(name: string): boolean + +Retrieve whether the searchParams object contains name. If yes, it returns true, otherwise it returns false. + +6.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. + +7.sort(): void + +According to the Unicode code point of the key, sort all key/value pairs contained in this object and return undefined. + +8.toString(): string + +According to the searchParams object, the query string applicable in the URL is returned. + +9.keys(): iterableIterator + +Return an iterator, which allows iterating through all the key values contained in the object. + +10.values(): iterableIterator + +Returns an iterator, which allows iterating over all the value values contained in the object. + +11.append(name: string, value: string): void + +Insert the name, value key-value pair in the searchParams object. + +12.delete(name: string): void + +Traverse the searchParams object, find all the names, and delete the corresponding key-value pairs. + +13.get(name: string): string + +Retrieve the first name in the searchParams object and return the value corresponding to the name key. + +14.getAll(name: string): string[] + +Retrieve all names in the searchParams object and return all the values corresponding to the name key. + +15.entries(): iterableIterator<[string, string]> + +Returns an iterator that allows iterating through all key/value pairs contained in the searchParams object. + +16.forEach(): void +The callback function is used to traverse the key-value pairs on the URLSearchParams instance object. + +The usage of each interface is as follows: + +let params = new URLSearchParams('foo=1&bar=2'); + +console.log(params.has('bar')); // =>ture + +params.set('baz', 3); + +params .sort(); +console.log(params .toString()); // =>bar=2&baz=3&foo=1' + +for(var key of params.keys()) { + console.log(key); +} + // =>bar baz foo +for(var value of params.values()) { + console.log(value); +} // =>2 3 1 + +params.append('foo', 3); // =>bar=2&baz=3&foo=1&foo=3 + +params.delete('baz'); // => bar=2&foo=1&foo=3 + +params.get('foo'); // => 1 + +params.getAll('foo'); // =>[ '1', '3' ] + +for(var pair of searchParams.entries()) { + console.log(pair[0]+ ', '+ pair[1]); +} // => bar, 2 foo, 1 foo, 3 + +url.searchParams.forEach((value, name, searchParams) => { + console.log(name, value, url.searchParams === searchParams); +}); + +// => foo 1 true +// => bar 2 true diff --git a/README.md b/README.md index 6eccad8..7d449a8 100755 --- a/README.md +++ b/README.md @@ -1,213 +1,145 @@ -# js_api_module子系统/组件 +#### js_api_module +####一、URL简介 +URL接口用于解析,构造,规范化和编码 URLs。 URL的构造函数创建新的URL对象。 以便对URL的已解析组成部分或对URL进行更改。 -- [简介](#简介) -- [目录](#目录) -- [说明](#说明) - - [接口说明](#接口说明) - - [使用说明](#使用说明) +接口介绍 -- [相关仓](#相关仓) +1.new URL(url: string,base?:string|URL) -## 简介 +创建并返回一个URL对象,该URL对象引用使用绝对URL字符串,相对URL字符串和基本URL字符串指定的URL。 -URL接口用于解析,构造,规范化和编码 URLs。 URL的构造函数创建新的URL对象。 以便对URL的已解析组成部分或对URL进行更改。URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。 +2.tostring():string; -## 目录 +该字符串化方法返回一个包含完整 URL 的 USVString。它的作用等同于只读的 URL.href。 -``` -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对象 -``` +3.toJSON():string; -## 说明 - -### 接口说明 - - -| 接口名 | 说明 | -| -------- | -------- | -| 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数组。 | - -### 使用说明 +该方法返回一个USVString,其中包含一个序列化的URL版本。 各接口使用方法如下: -1、new URL(url: string,base?:string|URL) -``` -let b = new URL('https://developer.mozilla.org'); // => 'https://developer.mozilla.org/' +let b = new URL('https://developer.mozilla.org'); // => 'https://developer.mozilla.org/' + +let a = new URL( 'sca/./path/path/../scasa/jjjjj', 'http://www.example.com'); +// => 'http://www.example.com/sca/path/scasa/jjjjj' -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' +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' +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; +url.toString() // => 'http://username:password@host:8080/directory/file?query#fragment' + +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' + + +####二、URLSreachParams简介 + +URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。 + +接口介绍 + +1.new URLSearchParams() + +URLSearchParams() 构造器无入参,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 + +2.new URLSearchParams(string) + +URLSearchParams(string) 构造器的入参为string数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 + +3.new URLSearchParams(obj) + +URLSearchParams(obj) 构造器的入参为obj数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 + +4.new URLSearchParams(iterable) + +URLSearchParams(iterable) 构造器的入参为iterable数据类型,该方法创建并返回一个新的URLSearchParams 对象。 开头的'?' 字符会被忽略。 + +5.isHas(name: string): boolean + +检索searchParams对象中是否含有name。有则返回ture,否则返回false。 + +6.set(name: string, value string): void + +检索searchParams对象中是否含有key为name的键值对。 +没有的话则添加该键值对,有的话则修改对象中第一个key所对应的value,并删除键为name的其余键值对。 + +7.sort(): void + +根据键的Unicode代码点,对包含在此对象中的所有键/值对进行排序,并返回undefined。 + +8.toString(): string + +根据searchParams对象,返回适用在URL中的查询字符串。 + +9.keys(): iterableIterator + +返回一个iterator,遍历器允许遍历对象中包含的所有key值。 + +10.values(): iterableIterator + +返回一个iterator,遍历器允许遍历对象中包含的所有value值。 + +11.append(name: string, value: string): void + +在searchParams对象中插入name, value键值对。 + +12.delete(name: string): void + +遍历searchParams对象,查找所有的name,删除对应的键值对。 + +13.get(name: string): string + +检索searchParams对象中第一个name,返回name键对应的值。 + +14.getAll(name: string): string[] + +检索searchParams对象中所有name,返回name键对应的所有值。 + +15.entries(): iterableIterator<[string, string]> + +返回一个iterator,允许遍历searchParams对象中包含的所有键/值对。 + +16.forEach(): void +通过回调函数来遍历URLSearchParams实例对象上的键值对. + +各接口使用方法如下: + +let params = new URLSearchParams('foo=1&bar=2'); + +console.log(params.has('bar')); // =>ture + +params.set('baz', 3); + +params .sort(); +console.log(params .toString()); // =>bar=2&baz=3&foo=1' -// 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 -``` +} + // =>bar baz foo 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 -``` +} // =>2 3 1 + +params.append('foo', 3); // =>bar=2&baz=3&foo=1&foo=3 + +params.delete('baz'); // => bar=2&foo=1&foo=3 + +params.get('foo'); // => 1 + +params.getAll('foo'); // =>[ '1', '3' ] + +for(var pair of searchParams.entries()) { + console.log(pair[0]+ ', '+ pair[1]); +} // => bar, 2 foo, 1 foo, 3 + 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/uri/BUILD.gn b/api/BUILD.gn similarity index 73% rename from uri/BUILD.gn rename to api/BUILD.gn index ed1a9e7..829f0f2 100755 --- a/uri/BUILD.gn +++ b/api/BUILD.gn @@ -14,29 +14,30 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -base_output_path = get_label_info(":js_uri", "target_out_dir") -js_uri_obj_path = base_output_path + "/uri.o" -gen_js_obj("js_uri") { - input = "//base/compileruntime/js_api_module/uri/js_uri.js" - output = js_uri_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("uri") { +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/uri", + "//base/compileruntime/js_api_module/api", ] sources = [ "js_uri.cpp", - "native_module_uri.cpp", + "js_url.cpp", + "native_module_api.cpp", ] deps = [ - ":js_uri", - "//base/compileruntime/js_api_module/uri/:js_uri", + ":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("uri") { relative_install_dir = "module" } -group("uri_packages") { - deps = [ ":uri" ] +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 2d00fb6..efc326b --- 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("----------CJX----------" + 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 0000000..852063d --- /dev/null +++ b/api/js_uri.cpp @@ -0,0 +1,552 @@ +/* + * 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()) { + napi_throw_error(env_, nullptr, "uri is 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 { + HILOG_INFO("CJX -------CPP----- AnalysisUri throw err"); + napi_throw_error(env_, nullptr, "#It can't be the first"); + errStr_ = "#It can't be the first"; + HILOG_INFO("CJX -------CPP----- AnalysisUri throw err end"); + return; + } + } + + // Query + pos = data_.find('?'); + if (pos != std::string::npos) { + AnalysisQuery(pos); + if (!errStr_.empty()) { + return; + } + } + //Scheme + pos = data_.find(':'); + 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)) { + napi_throw_error(env_, nullptr, "SpecialPath does not conform to the rule"); + 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)) { + napi_throw_error(env_, nullptr, "Fragment does not conform to the rule"); + 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)) { + napi_throw_error(env_, nullptr, "Query does not conform to the rule"); + 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])) { + napi_throw_error(env_, nullptr, "Scheme the first character must be a letter"); + errStr_ = "Scheme the first character must be a letter"; + return; + } + std::string scheme = data_.substr(0, pos); + if (!CheckCharacter(scheme, g_ruleScheme, false)) { + napi_throw_error(env_, nullptr, "scheme does not conform to the rule"); + 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) { + napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); + errStr_ = "ipv6 does not conform to the rule"; + return; + } + AnalysisIPV6(); + } else { + napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); + 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)) { + napi_throw_error(env_, nullptr, "path does not conform to the rule"); + 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)) { + napi_throw_error(env_, nullptr, "userInfo does not conform to the rule"); + 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)) { // 存在非规则内字符 + napi_throw_error(env_, nullptr, "port does not conform to the rule"); + 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)))(%([0-9A-Fa-f]|.|_)+)?"); + if (!std::regex_match(str, ipv6)) { + napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); + 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 0000000..c23d28a --- /dev/null +++ b/api/js_uri.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 COMPILERUNTIME_JS_API_URI_H +#define COMPILERUNTIME_JS_API_URI_H + +#include +#include +#include +#include +#include +#include +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS::Api { + namespace { + 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 0000000..d7a6288 --- /dev/null +++ b/api/js_url.cpp @@ -0,0 +1,2122 @@ +/* + * 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) + { + 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; + } +} // namespace \ No newline at end of file diff --git a/api/js_url.h b/api/js_url.h new file mode 100755 index 0000000..2b45c7a --- /dev/null +++ b/api/js_url.h @@ -0,0 +1,122 @@ + /* + * 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 0000000..2f1ae55 --- /dev/null +++ b/api/native_module_api.cpp @@ -0,0 +1,1186 @@ + /* + * 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 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", 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/ohos.build b/ohos.build index 12dc395..628efac 100644 --- a/ohos.build +++ b/ohos.build @@ -7,7 +7,7 @@ "phone" ], "module_list": [ - "//base/compileruntime/js_api_module/uri:uri_packages" + "//base/compileruntime/js_api_module/api:api_packages" ], "inner_kits": [ ], diff --git a/uri/js_uri.cpp b/uri/js_uri.cpp deleted file mode 100755 index 9b755ce..0000000 --- a/uri/js_uri.cpp +++ /dev/null @@ -1,503 +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_uri.h" -#include "utils/log.h" - - // a-z A-Z - std::bitset g_ruleAlpha; - - // a-z A-Z 0-9 + - . - std::bitset g_ruleScheme; - - // ;/?:@&=+$,[] 和 -_.!~*'() 和 0-9 和 a-z 和 A-Z - std::bitset g_ruleUrlc; - - // ;/ 和 :@&=+$, 和 -_.!~*'() 和 0-9 和 a-z 和 A-Z - std::bitset g_rulePath; - - // ;:&=+$, -_.!~*'() a-z A-Z 0-9 - std::bitset g_ruleUserInfo; - - // _. a-z A-Z 0-9 - std::bitset g_ruleScope; - - // 0-9 - std::bitset g_ruleDigit; - - //L_SERVER a-z A-Z 0-9.:@-;&=+$,-_!~*'() - 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; - if (input.empty()) { - napi_throw_error(env_, nullptr, "uri is empty"); - } - 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 { - HILOG_INFO("CJX -------CPP----- AnalysisUri throw err"); - napi_throw_error(env_, nullptr, "#It can't be the first"); - HILOG_INFO("CJX -------CPP----- AnalysisUri throw err end"); - } - } - - //Query - pos = data_.find('?'); - if (pos != std::string::npos) { - AnalysisQuery(pos); - } - //Scheme - pos = data_.find(':'); - if (pos != std::string::npos) { - AnalysisScheme(pos); - } else { - SpecialPath(); - 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); - AnalysisHostAndPath(); - } 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) { - 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)) { - napi_throw_error(env_, nullptr, "Query does not conform to the rule"); - } - uriData_.path = data_; - data_ = ""; -} - -// 考虑合并AnalysisFragment 和 AnalysisQuery 为一个 -void URI::AnalysisFragment(size_t pos) -{ - std::string fragment = data_.substr(pos + 1); - if (!CheckCharacter(fragment, g_ruleUrlc, true)) { - napi_throw_error(env_, nullptr, "Fragment does not conform to the rule"); - } - 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)) { - napi_throw_error(env_, nullptr, "Query does not conform to the rule"); - } - 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])) { - napi_throw_error(env_, nullptr, "Scheme the first character must be a letter"); - } - std::string scheme = data_.substr(0, pos); - if (!CheckCharacter(scheme, g_ruleScheme, false)) { - napi_throw_error(env_, nullptr, "scheme does not conform to the rule"); - } - 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); - } - - uriData_.authority = data_; - - //find UserInfo - pos = data_.find('@'); - if (pos != std::string::npos) { - AnalysisUserInfo(pos); - } - bool isLawfulProt = false; - //find port - pos = data_.rfind(':'); - if (pos != std::string::npos) { - isLawfulProt = AnalysisPort(pos); - } - - //find ipv4 or ipv6 or host - if (data_[0] == '[') { - if (data_[data_.size() - 1] == ']') { - //IPV6 - if (!isLawfulProt) { - napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); - } - AnalysisIPV6(); - } else { - napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); - } - } 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)) { - napi_throw_error(env_, nullptr, "path does not conform to the rule"); - } - 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)) { - napi_throw_error(env_, nullptr, "userInfo does not conform to the rule"); - } - 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)) { // 存在非规则内字符 - napi_throw_error(env_, nullptr, "port does not conform to the rule"); - } 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]{2,6}"); - 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); - std::regex ipv6("^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); - if (!std::regex_match(str, ipv6)) { - napi_throw_error(env_, nullptr, "ipv6 does not conform to the rule"); - } - 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::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; -} \ No newline at end of file diff --git a/uri/js_uri.h b/uri/js_uri.h deleted file mode 100755 index d3929a0..0000000 --- a/uri/js_uri.h +++ /dev/null @@ -1,82 +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 -#include -#include -#include -#include -#include -#include -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -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 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_; - napi_env env_ = nullptr; -}; \ No newline at end of file diff --git a/uri/js_uri.js b/uri/js_uri.js deleted file mode 100755 index 921015c..0000000 --- a/uri/js_uri.js +++ /dev/null @@ -1,81 +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. - */ - -'use strict'; -const uriUtil = requireInternal("uri"); - -class URI { - constructor(input) { - if (typeof input !== 'string' || input.length === 0) { - throw new Error("input type err"); - } - this.uricalss = new uriUtil.uri(input); - } - toString() { - return 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; - } -} - -export default { - URI: URI, -} diff --git a/uri/native_module_uri.cpp b/uri/native_module_uri.cpp deleted file mode 100755 index a02abb1..0000000 --- a/uri/native_module_uri.cpp +++ /dev/null @@ -1,286 +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 "napi/native_api.h" -#include "napi/native_node_api.h" -#include "js_uri.h" -#include "utils/log.h" - -extern const char _binary_js_uri_js_start[]; -extern const char _binary_js_uri_js_end[]; - -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 ToString(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 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", ToString), - 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), - }; - 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; -} - -extern "C" -__attribute__((visibility("default"))) void NAPI_uri_GetJSCode(const char** buf, int* bufLen) -{ - if (buf != nullptr) { - *buf = _binary_js_uri_js_start; - } - - if (bufLen != nullptr) { - *bufLen = _binary_js_uri_js_end - _binary_js_uri_js_start; - } -} - -static napi_module UriModule = -{ - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = UriInit, - .nm_modname = "uri", - .nm_priv = ((void*)0), - .reserved = {0}, -}; -extern "C" __attribute__((constructor)) void RegisterModule() -{ - napi_module_register(&UriModule); -} \ No newline at end of file diff --git a/url/BUILD.gn b/url/BUILD.gn deleted file mode 100644 index cd730c1..0000000 --- a/url/BUILD.gn +++ /dev/null @@ -1,59 +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. - -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 -} - -ohos_shared_library("url") { - include_dirs = [ - "//third_party/icu/icu4c/source/common", - "//third_party/node/src", - "//foundation/ace/napi/interfaces/kits", - "//base/compileruntime/js_api_module/url", - ] - - sources = [ - "js_url.cpp", - "native_module_url.cpp", - ] - - deps = [ - ":js_url", - "//base/compileruntime/js_api_module/url/:js_url", - "//foundation/ace/napi/:ace_napi", - "//foundation/ace/napi/:ace_napi_quickjs", - "//third_party/icu/icu4c:static_icuuc", - "//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("url_packages") { - deps = [ ":url" ] -} diff --git a/url/js_url.cpp b/url/js_url.cpp deleted file mode 100644 index 644e5f7..0000000 --- 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 29c3064..0000000 --- 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 c08aa99..0000000 --- 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