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