diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 407e6d753bb1e09fe655bdbbae219b4ba62766af..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,159 +0,0 @@ -# js_util_module - -#### 1、Introduction to TextEncoder - -The TextEncoder represents a text encoder, accepts character strings as input, encodes in UTF-8 format, and outputs UTF-8 byte stream. - -Interface introduction: - -1.readonly encoding : string - -Get the encoding format, only UTF-8 is supported. - -2.encode(input : string) : Uint8Array - -Input stirng string, encode and output UTF-8 byte stream. - -3.encodeInto(input : string, dest : Uint8Array) : {read : number, written : number} - -Enter the stirng string, dest represents the storage location after encoding, and returns an object, read represents the number of characters that have been encoded, -and written represents the size of bytes occupied by the encoded characters. - -Method of use: - -import util from '@ohos.util' - -var textEncoder = new util.TextEncoder(); - -var result = textEncoder.encode('abc'); - -var dest = new Uint8Array(6); - -var obj = textEncoder.encodeInto('abc', dest); - -var getEncoding = textEncoder.encoding(); - -#### 2、Introduction to TextDecoder - -The TextDecoder interface represents a text decoder. The decoder takes a byte stream as input and outputs a stirng string. - -Interface introduction: - -1.constructor(encoding? : string, options? : {fatal? : boolean, ignoreBOM? : boolean}) - -Constructor, the first parameter encoding indicates the format of decoding. - -The second parameter represents some attributes. - -Fatal in the attribute indicates whether an exception is thrown, and ignoreBOM indicates whether to ignore the bom flag. - -2.readonly encoding : string - -Get the set decoding format - -3.readonly fatal : boolean - -Get the setting that throws the exception - -4.readonly ignoreBOM : boolean - -Get whether to ignore the setting of the bom flag - -5.decode(input : ArrayBuffer | ArrayBufferView, options? : {stream? : false}) : string - -Input the data to be decoded, and solve the corresponding string character string. - -The first parameter input represents the data to be decoded, and the second parameter options represents a bool flag, which means that additional data will be followed. The default is false. - -Method of use: - -import util from '@ohos.util' - -var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); - -var getEncoding = textDecoder.encoding(); - -var fatalStr = textDecoder.fatal(); - -var ignoreBom = textDecoder.ignoreBOM(); - -var input = new Uint8Array([96, 97, 98]); - -var result = textDecoder.decode(input, {stream : true}); - -#### 3、 Introduction to helpfunction - -It is mainly used to callback and promise functions, output error code information, and format a printf-like string. - -The helpfunction module involves four interfaces. - -Interface introduction: - -1.function printf(format: string, ...args: Object[]): string; - - The util.format() method returns a formatted string using the first argument as a printf-like format string which can contain zero or more format specifiers. Each specifier is replaced with the converted value from the corresponding argument. Supported specifiers are: - Each specifier is replaced with a converted value from the corresponding parameter. Supported specifiers are: - %s: String will be used to convert all values except BigInt, Object and -0. BigInt values will be represented with an n and Objects that have no user defined toString function are inspected using util.inspect() with options { depth: 0, colors: false, compact: 3 }. - %d: Number will be used to convert all values except BigInt and Symbol. - %i: parseInt(value, 10) is used for all values except BigInt and Symbol. - %f: parseFloat(value) is used for all values expect Symbol. - %j: JSON. Replaced with the string '[Circular]' if the argument contains circular references. - %o: Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() with options { showHidden: true, showProxy: true }. This will show the full object including non-enumerable properties and proxies. - %O: Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() without options. This will show the full object not including non-enumerable properties and proxies. - %c: CSS. This specifier is ignored and will skip any CSS passed in. - %%: single percent sign ('%'). This does not consume an argument. - Returns: The formatted string - If a specifier does not have a corresponding argument, it is not replaced: - util.format('%s:%s', 'foo'); - // Returns: 'foo:%s' - - Values that are not part of the format string are formatted using util.inspect() if their type is not string. - If there are more arguments passed to the util.format() method than the number of specifiers, the extra arguments are concatenated to the returned string, separated by spaces: - util.format('%s:%s', 'foo', 'bar', 'baz'); - // Returns: 'foo:bar baz' - - If the first argument does not contain a valid format specifier, util.format() returns a string that is the concatenation of all arguments separated by spaces: - util.format(1, 2, 3); - // Returns: '1 2 3' - - If only one argument is passed to util.format(), it is returned as it is without any formatting: - util.format('%% %s'); - // Returns: '%% %s' - -2.function getErrorString(errno: number): string; - - The geterrorstring () method uses a system error number as a parameter to return system error information. - -3.function callbackWrapper(original: Function): (err: Object, value: Object) => void; - - Takes an async function (or a function that returns a Promise) and returns a function following the error-first callback style, i.e. taking an (err, value) => ... callback as the last argument. In the callback, the first argument will be the rejection reason (or null if the Promise resolved), and the second argument will be the resolved value. - -4.function promiseWrapper(original: (err: Object, value: Object) => void): Object; - - Takes a function following the common error-first callback style, i.e. taking an (err, value) => ... callback as the last argument, and returns a version that returns promises. - -####2、 Method of use - -Take printf and geterrorstring as examples: - -1.printf() - -{ - var format = "%%%o%%%i%s"; - - var value = function aa(){}; - - var value1 = 1.5; - - var value2 = "qwer"; - - var result = util.printf(format,value,value1,value2); -} - -2.geterrorstring() - -{ - var errnum = 13; - - var result = util.geterrorstring(errnum); -} diff --git a/README.md b/README.md deleted file mode 100644 index ed82bb6fad06de6da766d213626d2a5603ed52d6..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,192 +0,0 @@ -# js_util_module - -#### 一、TextEncoder介绍 - -TextEncoder表示一个文本编码器,接受字符串作为输入,以UTF-8格式进行编码,输出UTF-8字节流。 - -接口介绍 - -1.readonly encoding : string - -获取编码的格式,只支持UTF-8。 - -2.encode(input : string) : Uint8Array - -输入stirng字符串,编码并输出UTF-8字节流。 - -3.encodeInto(input : string, dest : Uint8Array) : {read : number, written : number} - -输入stirng字符串,dest表示编码后存放位置,返回一个对象,read表示已经编码的字符的个数,written表示已编码字符所占字节的大小。 - -使用方法: - -import util from '@ohos.util' - -var textEncoder = new util.TextEncoder(); - -var result = textEncoder.encode('abc'); - -var dest = new Uint8Array(6); - -var obj = textEncoder.encodeInto('abc', dest); - -var getEncoding = textEncoder.encoding(); - -#### 二、TextDecoder介绍 - -TextDecoder接口表示一个文本解码器,解码器将字节流作为输入,输出stirng字符串。 - -接口介绍 - -1.constructor(encoding? : string, options? : {fatal? : boolean, ignoreBOM? : boolean}) -构造函数,第一个参数encoding表示解码的格式。 - -第二个参数表示一些属性。 - -属性中fatal表示是否抛出异常,ignoreBOM表示是否忽略bom标志。 - -2.readonly encoding : string - -获取设置的解码格式 - -3.readonly fatal : boolean - -获取抛出异常的设置 - -4.readonly ignoreBOM : boolean - -获取是否忽略bom标志的设置 - -5.decode(input : ArrayBuffer | ArrayBufferView, options? : {stream? : false}) : string - -输入要解码的数据,解出对应的string字符串。 - -第一个参数input表示要解码的数据,第二个参数options表示一个bool标志,表示将跟随附加数据,默认为false。 - -使用方法: - -import util from '@ohos.util' - -var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); - -var getEncoding = textDecoder.encoding(); - -var fatalStr = textDecoder.fatal(); - -var ignoreBom = textDecoder.ignoreBOM(); - -var input = new Uint8Array([96, 97, 98]); - -var result = textDecoder.decode(input, {stream : true}); - -#### 三、helpfunction介绍 - -主要是对函数做callback化、promise化以及对错误码进行编写输出,及类字符串的格式化输出。 - -helpfunction模块,涉及4个接口。 - -接口介绍 - -1.function printf(format: string, ...args: Object[]): string; - - printf()方法使用第一个参数作为格式字符串(其可以包含零个或多个格式说明符)来返回格式化的字符串。 - -每个说明符都替换为来自相应参数的转换后的值。 支持的说明符有: - - %s: String 将用于转换除 BigInt、Object 和 -0 之外的所有值。 - - %d: Number 将用于转换除 BigInt 和 Symbol 之外的所有值。 - - %i: parseInt(value, 10) 用于除 BigInt 和 Symbol 之外的所有值。 - - %f: parseFloat(value) 用于除 Symbol 之外的所有值。 - - %j: JSON。 如果参数包含循环引用,则替换为字符串 '[Circular]'。 - - %o: Object. 具有通用 JavaScript 对象格式的对象的字符串表示形式。 - - 类似于具有选项 { showHidden: true, showProxy: true } 的 util.inspect()。 - - 这将显示完整的对象,包括不可枚举的属性和代理。 - - %O: Object. 具有通用 JavaScript 对象格式的对象的字符串表示形式。 - - 类似于没有选项的 util.inspect()。 这将显示完整的对象,但不包括不可枚举的属性和代理。 - - %c: CSS. 此说明符被忽略,将跳过任何传入的 CSS。 - - %%: 单个百分号 ('%')。 这不消费参数。 - - 返回: 格式化的字符串 - - 如果说明符没有相应的参数,则不会替换它: - - printf('%s:%s', 'foo'); - - // 返回: 'foo:%s' - - 如果其类型不是 string,则不属于格式字符串的值将进行%o类型的格式化。 - - 如果传给 printf() 方法的参数多于说明符的数量,则额外的参数将以空格分隔串联到返回的字符串: - - printf('%s:%s', 'foo', 'bar', 'baz'); - - // 返回: 'foo:bar baz' - - 如果第一个参数不包含有效的格式说明符,则printf()返回以空格分隔的所有参数的串联的字符串: - - printf(1, 2, 3); - - // 返回: '1 2 3' - - 如果只有一个参数传给printf(),则它会按原样返回,不进行任何格式化: - - util.format('%% %s'); - - // Returns: '%% %s' - -2.function getErrorString(errno: number): string; - - getErrorString()方法使用一个系统的错误数字作为参数,用来返回系统的错误信息。 - -3.function callbackWrapper(original: Function): (err: Object, value: Object) => void; - - 参数为一个采用 async 函数(或返回 Promise 的函数)并返回遵循错误优先回调风格的函数, - - 即将 (err, value) => ... 回调作为最后一个参数。 在回调中,第一个参数将是拒绝原因 - - (如果 Promise 已解决,则为 null),第二个参数将是已解决的值。 - -4.function promiseWrapper(original: (err: Object, value: Object) => void): Object; - - 参数为采用遵循常见的错误优先的回调风格的函数 - - (也就是将 (err, value) => ... 回调作为最后一个参数),并返回一个返回 promise 的版本。 - -使用方法: - -以printf、geterrorstring为例: - -import util from '@ohos.util' - -1.printf() - -{ - var format = "%%%o%%%i%s"; - - var value = function aa(){}; - - var value1 = 1.5; - - var value2 = "qwer"; - - var result = util.printf(format,value,value1,value2); -} - -2.geterrorstring() - -{ - var errnum = 13; - - var result = util.geterrorstring(errnum); -} \ No newline at end of file diff --git a/README_EN.md b/README_EN.md deleted file mode 100644 index 9d214e6bf63b3e3cb2c39fcc4045aa378163957f..0000000000000000000000000000000000000000 --- a/README_EN.md +++ /dev/null @@ -1,86 +0,0 @@ -# js_ util_ module - -####1、 Introduction to helpfunction - -It is mainly used to callback and promise functions, output error code information, and format a printf-like string. - -The helpfunction module involves four interfaces. - -Interface introduction: - -1.function printf(format: string, ...args: Object[]): string; - - The util.format() method returns a formatted string using the first argument as a printf-like format string which can contain zero or more format specifiers. Each specifier is replaced with the converted value from the corresponding argument. Supported specifiers are: - Each specifier is replaced with a converted value from the corresponding parameter. Supported specifiers are: - %s: String will be used to convert all values except BigInt, Object and -0. BigInt values will be represented with an n and Objects that have no user defined toString function are inspected using util.inspect() with options { depth: 0, colors: false, compact: 3 }. - %d: Number will be used to convert all values except BigInt and Symbol. - %i: parseInt(value, 10) is used for all values except BigInt and Symbol. - %f: parseFloat(value) is used for all values expect Symbol. - %j: JSON. Replaced with the string '[Circular]' if the argument contains circular references. - %o: Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() with options { showHidden: true, showProxy: true }. This will show the full object including non-enumerable properties and proxies. - %O: Object. A string representation of an object with generic JavaScript object formatting. Similar to util.inspect() without options. This will show the full object not including non-enumerable properties and proxies. - %c: CSS. This specifier is ignored and will skip any CSS passed in. - %%: single percent sign ('%'). This does not consume an argument. - Returns: The formatted string - If a specifier does not have a corresponding argument, it is not replaced: - util.format('%s:%s', 'foo'); - // Returns: 'foo:%s' - - Values that are not part of the format string are formatted using util.inspect() if their type is not string. - If there are more arguments passed to the util.format() method than the number of specifiers, the extra arguments are concatenated to the returned string, separated by spaces: - util.format('%s:%s', 'foo', 'bar', 'baz'); - // Returns: 'foo:bar baz' - - If the first argument does not contain a valid format specifier, util.format() returns a string that is the concatenation of all arguments separated by spaces: - util.format(1, 2, 3); - // Returns: '1 2 3' - - If only one argument is passed to util.format(), it is returned as it is without any formatting: - util.format('%% %s'); - // Returns: '%% %s' - -2.function getErrorString(errno: number): string; - - The geterrorstring () method uses a system error number as a parameter to return system error information. - -3.function callbackWrapper(original: Function): (err: Object, value: Object) => void; - - Takes an async function (or a function that returns a Promise) and returns a function following the error-first callback style, i.e. taking an (err, value) => ... callback as the last argument. In the callback, the first argument will be the rejection reason (or null if the Promise resolved), and the second argument will be the resolved value. - -4.function promiseWrapper(original: (err: Object, value: Object) => void): Object; - - Takes a function following the common error-first callback style, i.e. taking an (err, value) => ... callback as the last argument, and returns a version that returns promises. - -####2、 Method of use - -Take printf and geterrorstring as examples: - -1.printf() - -{ - - var format = "%%%o%%%i%s"; - - var value = function aa(){}; - - var value1 = 1.5; - - var value2 = "qwer"; - - var result = util.printf(format,value,value1,value2); - - console.log("-----SK-----printf---result---+[" +result +"]"); - -} - -2.geterrorstring() - -{ - - var errnum = 13; - - var result = util.geterrorstring(errnum); - - console.log("-----SK------ = " + result); - -} \ No newline at end of file diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 0000000000000000000000000000000000000000..9210368799c511a43d04d2d67a8fafa28d736ae7 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,165 @@ +# js_util_module子系统/组件 + +- [简介](#简介) +- [目录](#目录) +- [说明](#说明) + - [接口说明](#接口说明) + - [使用说明](#使用说明) + +- [相关仓](#相关仓) + +## 简介 + +UTIL接口用于字符编码TextEncoder、解码TextDecoder和帮助函数HelpFunction。TextEncoder表示一个文本编码器,接受字符串作为输入,以UTF-8格式进行编码,输出UTF-8字节流。TextDecoder接口表示一个文本解码器,解码器将字节流作为输入,输出stirng字符串。HelpFunction主要是对函数做callback化、promise化以及对错误码进行编写输出,及类字符串的格式化输出。 +## 目录 + +``` +base/compileruntime/js_util_module/ +├── Class:TextEncoder # TextEncoder类 +│ ├── new TextEncoder() # 创建TextEncoder对象 +│ ├── encode() # encode方法 +│ ├── encoding # encoding属性 +│ └── encodeInto() # encodeInto方法 +├── Class:TextDecoder # TextDecoder类 +│ ├── new TextDecoder() # 创建TextDecoder对象 +│ ├── decode() # decode方法 +│ ├── encoding # encoding属性 +│ ├── fatal # fatal属性 +│ └── ignoreBOM # ignoreBOM属性 +├── printf() # printf方法 +├── getErrorString() # getErrorString方法 +├── callbackWrapper() # callbackWrapper方法 +└── promiseWrapper() # promiseWrapper方法 +``` + +## 说明 + +### 接口说明 + + +| 接口名 | 说明 | +| -------- | -------- | +| readonly encoding : string | 获取编码的格式,只支持UTF-8。 | +| encode(input : string) : Uint8Array | 输入stirng字符串,编码并输出UTF-8字节流。 | +| encodeInto(input : string, dest : Uint8Array) : {read : number, written : number} | 输入stirng字符串,dest表示编码后存放位置,返回一个对象,read表示已经编码的字符的个数,written表示已编码字符所占字节的大小。 | +| constructor(encoding? : string, options? : {fatal? : boolean, ignoreBOM? : boolean}) | 构造函数,第一个参数encoding表示解码的格式。第二个参数表示一些属性。属性中fatal表示是否抛出异常,ignoreBOM表示是否忽略bom标志。 | +| readonly encoding : string | 获取设置的解码格式。 | +| readonly fatal : boolean | 获取抛出异常的设置 | +| readonly ignoreBOM : boolean | 获取是否忽略bom标志的设置 | +| decode(input : ArrayBuffer | 输入要解码的数据,解出对应的string字符串。第一个参数input表示要解码的数据,第二个参数options表示一个bool标志,表示将跟随附加数据,默认为false。 | +| function printf(format: string, ...args: Object[]): string | printf()方法使用第一个参数作为格式字符串(其可以包含零个或多个格式说明符)来返回格式化的字符串。 | +| function getErrorString(errno: number): string | getErrorString()方法使用一个系统的错误数字作为参数,用来返回系统的错误信息。 | +| function callbackWrapper(original: Function): (err: Object, value: Object) => void | 参数为一个采用 async 函数(或返回 Promise 的函数)并返回遵循错误优先回调风格的函数,即将 (err, value) => ... 回调作为最后一个参数。 在回调中,第一个参数将是拒绝原因(如果 Promise 已解决,则为 null),第二个参数将是已解决的值。 | +| function promiseWrapper(original: (err: Object, value: Object) => void): Object | 参数为采用遵循常见的错误优先的回调风格的函数(也就是将 (err, value) => ... 回调作为最后一个参数),并返回一个返回 promise 的版本。 | + +printf中每个说明符都替换为来自相应参数的转换后的值。 支持的说明符有: +| 式样化字符 | 式样要求 | +| -------- | -------- | +| %s: | String 将用于转换除 BigInt、Object 和 -0 之外的所有值。| +| %d: |Number 将用于转换除 BigInt 和 Symbol 之外的所有值。| +| %i: |parseInt(value, 10) 用于除 BigInt 和 Symbol 之外的所有值。| +| %f: |parseFloat(value) 用于除 Symbol 之外的所有值。| +| %j: |JSON。 如果参数包含循环引用,则替换为字符串 '[Circular]'。| +| %o: |Object. 具有通用 JavaScript 对象格式的对象的字符串表示形式。类似于具有选项 { showHidden: true, showProxy: true } 的 util.inspect()。这将显示完整的对象,包括不可枚举的属性和代理。| +| %O: |Object. 具有通用 JavaScript 对象格式的对象的字符串表示形式。类似于没有选项的 util.inspect()。 这将显示完整的对象,但不包括不可枚举的属性和代理。| +| %c: | 此说明符被忽略,将跳过任何传入的 CSS。| +| %%: |单个百分号 ('%')。 这不消耗待式样化参数。| + +### 使用说明 + +各接口使用方法如下: + +1.readonly encoding() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var getEncoding = textEncoder.encoding(); +``` +2.encode() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var result = textEncoder.encode('abc'); +``` +3.encodeInto() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); +var obj = textEncoder.encodeInto('abc', dest); +``` +4.textDecoder() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +``` +5.readonly encoding() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var getEncoding = textDecoder.encoding(); +``` +6.readonly fatal() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var fatalStr = textDecoder.fatal(); +``` +7.readonly ignoreBOM() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var ignoreBom = textDecoder.ignoreBOM(); +``` +8.decode() +``` +import util from '@ohos.util' +var textDecoder = new util.textDecoder("utf-16be", {fatal : ture, ignoreBOM : false}); +var result = textDecoder.decode(input, {stream : true}); +``` +9.printf() +``` +import util from '@ohos.util' +var format = "%%%o%%%i%s"; +var value = function aa(){}; +var value1 = 1.5; +var value2 = "qwer"; +var result = util.printf(format,value,value1,value2); +``` +10.getErrorString() +``` +import util from '@ohos.util' +var errnum = 13; +var result = util.getErrorString(errnum); +``` +11.callbackWrapper() +``` +import util from '@ohos.util' +async function promiseFn() { + return Promise.resolve('value'); +}; +var cb = util.callbackWrapper(promiseFn); +cb((err, ret) => { + expect(err).strictEqual(null); + expect(ret).strictEqual('value'); +}) +``` +12.promiseWrapper() +``` +import util from '@ohos.util' +function aysnFun(str1, str2, callback) { + if (typeof str1 === 'string' && typeof str1 === 'string') { + callback(null, str1 + str2); + } else { + callback('type err'); + } +} +let newPromiseObj = util.promiseWrapper(aysnFun)("Hello", 'World'); +newPromiseObj.then(res => { + expect(res).strictEqual('HelloWorld'); +}) +``` +## 相关仓 + +[js_util_module子系统](https://gitee.com/OHOS_STD/js_util_module) + +[base/compileruntime/js_util_module/](base/compileruntime/js_util_module-readme.md) diff --git a/ohos.build b/ohos.build index b85022b46f4aed35299b6ac2e4a7130135d8b852..e5737bd24e47b197bb6bce8f9b9cc367ff4e96dd 100755 --- a/ohos.build +++ b/ohos.build @@ -12,6 +12,7 @@ "inner_kits": [ ], "test_list": [ + "//base/compileruntime/js_util_module/test/unittest:unittest" ] } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..3434bb1bc1b010c868838c7160e0d45d2034a53e --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,63 @@ +# 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/test.gni") + +if (is_standard_system) { + module_output_path = "compileruntime/js_util_module" +} + +ohos_unittest("test_util_unittest") { + module_out_path = module_output_path + + include_dirs = [ + "//base/compileruntime/js_util_module/util", + "//foundation/ace/napi", + "//foundation/ace/napi/interfaces/kits", + "//foundation/ace/napi/native_engine", + "//foundation/ace/napi/native_engine/impl/quickjs", + "//third_party/icu/icu4c/source/common", + "//third_party/googletest/include", + "//third_party/node/src", + "//utils/native/base/include", + ] + + cflags = [ "-g3" ] + + sources = [ + "test_quickjs.cpp", + "test_util.cpp", + ] + + deps = [ + "//base/compileruntime/js_util_module/util:util_packages", + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/googletest:gtest", + "//third_party/googletest:gtest_main", + "//third_party/icu/icu4c:static_icuuc", + "//third_party/libuv:uv_static", + "//third_party/quickjs:qjs", + "//utils/native/base:utils", + "//utils/native/base:utilsecurec", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":test_util_unittest" ] +} diff --git a/test/unittest/test.h b/test/unittest/test.h new file mode 100755 index 0000000000000000000000000000000000000000..af0772277b1847dd5c06d254738beb8d2a02596c --- /dev/null +++ b/test/unittest/test.h @@ -0,0 +1,33 @@ +/* + * 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_NAPI_TEST_UNITTEST_TEST_H +#define FOUNDATION_ACE_NAPI_TEST_UNITTEST_TEST_H + +#include "native_engine.h" + +#include "gtest/gtest.h" + +class NativeEngineTest : public testing::Test { +public: + NativeEngineTest(); + virtual ~NativeEngineTest(); + void SetUp() override {} + void TearDown() override {} +protected: + NativeEngine* engine_; +}; + +#endif /* FOUNDATION_ACE_NAPI_TEST_UNITTEST_TEST_H */ \ No newline at end of file diff --git a/test/unittest/test_quickjs.cpp b/test/unittest/test_quickjs.cpp new file mode 100755 index 0000000000000000000000000000000000000000..22fca43d10a5cba432a18add254e3cab4fc0ebe4 --- /dev/null +++ b/test/unittest/test_quickjs.cpp @@ -0,0 +1,60 @@ +/* + * 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 "test.h" + +#include "quickjs_native_engine.h" + +static NativeEngine* g_nativeEngine = nullptr; + +NativeEngineTest::NativeEngineTest() +{ + engine_ = g_nativeEngine; +} + +NativeEngineTest::~NativeEngineTest() {} + +int main(int argc, char** argv) +{ + testing::GTEST_FLAG(output) = "xml:./"; + testing::InitGoogleTest(&argc, argv); + + JSRuntime* rt = JS_NewRuntime(); + if (rt == nullptr) { + return 0; + } + + JSContext* ctx = JS_NewContext(rt); + if (ctx == nullptr) { + return 0; + } + + js_std_add_helpers(ctx, 0, nullptr); + + g_nativeEngine = new QuickJSNativeEngine(rt, ctx); + + int ret = RUN_ALL_TESTS(); + + g_nativeEngine->Loop(LOOP_DEFAULT); + + delete g_nativeEngine; + g_nativeEngine = nullptr; + + js_std_free_handlers(rt); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + return ret; +} diff --git a/test/unittest/test_util.cpp b/test/unittest/test_util.cpp new file mode 100755 index 0000000000000000000000000000000000000000..14a1618d7fa0c74e7d6d662dfb65d420b9567bc5 --- /dev/null +++ b/test/unittest/test_util.cpp @@ -0,0 +1,690 @@ +/* + * 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 "test.h" + +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "securec.h" +#include "utils/log.h" +#include "js_textdecoder.h" +#include "js_textencoder.h" +// #include "unicode/unistr.h" + +#define ASSERT_CHECK_CALL(call) \ + { \ + ASSERT_EQ(call, napi_ok); \ + } + +#define ASSERT_CHECK_VALUE_TYPE(env, value, type) \ + { \ + napi_valuetype valueType = napi_undefined; \ + ASSERT_TRUE(value != nullptr); \ + ASSERT_CHECK_CALL(napi_typeof(env, value, &valueType)); \ + ASSERT_EQ(valueType, type); \ + } + + +/* @tc.name: getEncodingTest001 + * @tc.desc: Test acquire encoding mode. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, getEncodingTest001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("getEncodingTest001 start"); + napi_env env = (napi_env)engine_; + + OHOS::Util::TextEncoder textEncoder(env); + napi_value result = textEncoder.GetEncoding(); + + std::string tmpTestStr = "utf-8"; + + char *buffer = nullptr; + size_t bufferSize = 0; + napi_get_value_string_utf8(env, result, buffer, -1, &bufferSize); + if (bufferSize > 0) { + buffer = new char[bufferSize + 1]; + napi_get_value_string_utf8(env, result, buffer, bufferSize + 1, &bufferSize); + } + + ASSERT_STREQ(buffer, tmpTestStr.c_str()); + if (buffer != nullptr) { + delete []buffer; + buffer = nullptr; + } +} + +/** + * @tc.name: textEncodeTest001 + * @tc.desc: Test encode src. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, textEncodeTest001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("getEncodingTest001 start"); + napi_env env = (napi_env)engine_; + OHOS::Util::TextEncoder textEncoder(env); + + std::string input = "abc123"; + napi_value src = nullptr; + napi_create_string_utf8(env, input.c_str(), input.size(), &src); + napi_value result = textEncoder.Encode(src); + + char excepted[7] = {0x61, 0x62, 0x63, 0x31, 0x32, 0x33, 0}; + + napi_typedarray_type type; + size_t srcLength = 0; + void* srcData = nullptr; + napi_value srcBuffer = nullptr; + size_t byteOffset = 0; + + napi_get_typedarray_info( + env, result, &type, &srcLength, &srcData, &srcBuffer, &byteOffset); + + ASSERT_EQ(srcLength, 6); + char* res = (char*)srcData; + + res[srcLength] = 0; + ASSERT_STREQ(res, excepted); +} + +/** + * @tc.name: textEncodeTest001 + * @tc.desc: Test encode src. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, textEncodeTest002, testing::ext::TestSize.Level0) +{ + HILOG_INFO("getEncodingTest001 start"); + napi_env env = (napi_env)engine_; + OHOS::Util::TextEncoder textEncoder(env); + + std::string input = ""; + napi_value src = nullptr; + napi_create_string_utf8(env, input.c_str(), input.size(), &src); + napi_value result = textEncoder.Encode(src); + + napi_typedarray_type type; + size_t srcLength = 0; + void* srcData = nullptr; + napi_value srcBuffer = nullptr; + size_t byteOffset = 0; + + napi_get_typedarray_info( + env, result, &type, &srcLength, &srcData, &srcBuffer, &byteOffset); + + ASSERT_STREQ((char*)srcData, nullptr); +} + +/** + * @tc.name: textEncodeIntoTest001 + * @tc.desc: Test returns a dictionary object indicating the progress of the encoding + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, textEncodeIntoTest001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("textEncodeIntoTest001 start"); + napi_env env = (napi_env)engine_; + OHOS::Util::TextEncoder textEncoder(env); + + std::string input = "abc123"; + napi_value src = nullptr; + napi_create_string_utf8(env, input.c_str(), input.size(), &src); + + napi_value arrayBuffer = nullptr; + void* arrayBufferPtr = nullptr; + size_t arrayBufferSize = 20; + napi_create_arraybuffer(env, arrayBufferSize, &arrayBufferPtr, &arrayBuffer); + + napi_value dest = nullptr; + napi_create_typedarray(env, napi_int8_array, arrayBufferSize, arrayBuffer, 0, &dest); + + napi_value result = textEncoder.EncodeInto(src, dest); + + napi_value read = nullptr; + napi_get_named_property(env, result, "read", &read); + + uint32_t resRead = 0; + + napi_get_value_uint32(env, read, &resRead); + + napi_value written = nullptr; + napi_get_named_property(env, result, "written", &written); + + uint32_t resWritten = 0; + napi_get_value_uint32(env, read, &resWritten); + + ASSERT_EQ(resRead, (uint32_t)6); + ASSERT_EQ(resWritten, (uint32_t)6); +} + + +/** + * @tc.name: GetEncoding001 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, GetEncoding001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("TextDecoder::getEncodingTest001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = -1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + napi_value testString = textDecoder.GetEncoding(); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + std::string tmpTestStr = "utf-8"; + size_t strLength = 0; + char* buffer = nullptr; + if (bufferSize > 0) { + buffer = new char[bufferSize + 1]{ 0 }; + napi_get_value_string_utf8(env, testString, buffer, bufferSize + 1, &strLength); + } + ASSERT_STREQ(tmpTestStr.c_str(), buffer); + ASSERT_EQ(tmpTestStr.length(), strLength); + if (buffer != nullptr) { + delete []buffer; + buffer = nullptr; + } +} + +/** + * @tc.name: GetFatal001 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, GetFatal001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("TextDecoder::GetFatal001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 1; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + napi_value naVal = textDecoder.GetFatal(); + bool result = false; + napi_get_value_bool(env, naVal, &result); + ASSERT_TRUE(result); +} + +/** + * @tc.name: GetFatal002 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, GetFatal002, testing::ext::TestSize.Level0) +{ + HILOG_INFO("TextDecoder::GetFatal002 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = 1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + napi_value naVal = textDecoder.GetFatal(); + bool result = false; + napi_get_value_bool(env, naVal, &result); + ASSERT_FALSE(result); +} + +/** + * @tc.name: GetIgnoreBOM001 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, GetIgnoreBOM001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("TextDecoder::GetIgnoreBOM001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = 1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + napi_value naVal = textDecoder.GetIgnoreBOM(); + bool result = false; + napi_get_value_bool(env, naVal, &result); + ASSERT_TRUE(result); +} + +/** + * @tc.name: decoderUtf8001 utf-8 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf8001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf8001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = -1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = false; + size_t byteLength = 3; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[3] = {0x61, 0x62, 0x63}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + size_t length = 0; + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + std::string tempStr = "abc"; + ASSERT_STREQ(tempStr.c_str(), ch); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf8002 utf-8 + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf8002, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf8002 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-8"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = true; + size_t byteLength = 3; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[3] = {0x61, 0x62, 0x63}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + size_t length = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + + std::string tempStr = "abc"; + ASSERT_STREQ(tempStr.c_str(), ch); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16le001 utf-16le + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16le001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16le001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16le"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = false; + size_t byteLength = 6; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[6] = {0x61, 0x00, 0x62, 0x00, 0x63, 0x00}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + size_t length = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + + std::string tempStr = "abc"; + ASSERT_STREQ(tempStr.c_str(), ch); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16le002 utf-16le + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16le002, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16le002 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16le"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = true; + size_t byteLength = 6; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[6] = {0x61, 0x00, 0x62, 0x00, 0x63, 0x00}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + char* ch = nullptr; + size_t length = 0; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr = "abc"; + ASSERT_STREQ(tempStr.c_str(), ch); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16le003 utf-16le + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16le003, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16le003 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16le"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = true; + size_t byteLength = 8; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[8] = {0xFF, 0xFE, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + char* ch = nullptr; + size_t length = 0; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr01(ch); + std::u16string tempU16str02 = + std::wstring_convert, char16_t> {}.from_bytes(tempStr01); + ASSERT_EQ(0xFEFF, (int)tempU16str02[0]); + ASSERT_EQ(0x61, (int)tempU16str02[1]); + ASSERT_EQ(0x62, (int)tempU16str02[2]); + ASSERT_EQ(0x63, (int)tempU16str02[3]); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16le004 utf-16le + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16le004, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16le004 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = -1; + int ignoreBOM = -1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16le"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = false; + size_t byteLength = 8; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[8] = {0xFF, 0xFE, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + char* ch = nullptr; + size_t length = 0; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr01(ch); + std::u16string tempU16str02 = + std::wstring_convert, char16_t> {}.from_bytes(tempStr01); + ASSERT_EQ(0xFEFF, (int)tempU16str02[0]); + ASSERT_EQ(0x61, (int)tempU16str02[1]); + ASSERT_EQ(0x62, (int)tempU16str02[2]); + ASSERT_EQ(0x63, (int)tempU16str02[3]); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16be001 utf-16be + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16be001, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16be001 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16be"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = false; + size_t byteLength = 6; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[6] = {0x00, 0x61, 0x00, 0x62, 0x00, 0x63}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + size_t length = 0; + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr = "abc"; + ASSERT_STREQ(tempStr.c_str(), ch); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16be002 utf-16be + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16be002, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16be002 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 0; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16be"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = false; + size_t byteLength = 8; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[8] = {0xFE, 0xFF, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + size_t length = 0; + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr01(ch); + std::u16string tempU16str02 = + std::wstring_convert, char16_t> {}.from_bytes(tempStr01); + ASSERT_EQ(0xFEFF, (int)tempU16str02[0]); + ASSERT_EQ(0x61, (int)tempU16str02[1]); + ASSERT_EQ(0x62, (int)tempU16str02[2]); + ASSERT_EQ(0x63, (int)tempU16str02[3]); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} + +/** + * @tc.name: decoderUtf16be003 utf-16be + * @tc.desc: Test date type. + * @tc.type: FUNC + */ +HWTEST_F(NativeEngineTest, decoderUtf16be003, testing::ext::TestSize.Level0) +{ + HILOG_INFO("decoderUtf16be003 start"); + napi_env env = (napi_env)engine_; + std::vector inputVec; + int fatal = 0; + int ignoreBOM = 1; + inputVec.push_back(fatal); + inputVec.push_back(ignoreBOM); + std::string str = "utf-16be"; + OHOS::Util::TextDecoder textDecoder(env, str, inputVec); + bool iflag = true; + size_t byteLength = 8; + void* data = nullptr; + napi_value resultBuff; + napi_create_arraybuffer(env, byteLength, &data, &resultBuff); + unsigned char arr[8] = {0xFE, 0xFF, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63}; + int ret = memcpy_s(data, sizeof(arr), reinterpret_cast(arr), sizeof(arr)); + ASSERT_EQ(0, ret); + napi_value result2; + napi_create_typedarray(env, napi_int8_array, byteLength, resultBuff, 0, &result2); + napi_value testString = textDecoder.Decode(result2, iflag); + size_t bufferSize = 0; + napi_get_value_string_utf8(env, testString, nullptr, 0, &bufferSize); + size_t length = 0; + char* ch = nullptr; + if (bufferSize > 0) { + ch = new char[bufferSize + 1](); + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + } + napi_get_value_string_utf8(env, testString, ch, bufferSize + 1, &length); + std::string tempStr01(ch); + std::u16string tempU16str02 = + std::wstring_convert, char16_t> {}.from_bytes(tempStr01); + ASSERT_EQ(0xFEFF, (int)tempU16str02[0]); + ASSERT_EQ(0x61, (int)tempU16str02[1]); + ASSERT_EQ(0x62, (int)tempU16str02[2]); + ASSERT_EQ(0x63, (int)tempU16str02[3]); + if (ch != nullptr) { + delete []ch; + ch = nullptr; + } +} diff --git a/util/BUILD.gn b/util/BUILD.gn index c6044cf8c9b2b9412e9915011d0fb078b4356b6a..ea5e47e21e07ea1bba26b2c1a3c2082e3ac36a00 100644 --- a/util/BUILD.gn +++ b/util/BUILD.gn @@ -33,6 +33,8 @@ ohos_shared_library("util") { ] sources = [ + "js_base64.cpp", + "js_rational.cpp", "js_textdecoder.cpp", "js_textencoder.cpp", "native_module_util.cpp", diff --git a/util/js_base64.cpp b/util/js_base64.cpp new file mode 100755 index 0000000000000000000000000000000000000000..acf91b3b1296c1114b74210b704baf2c4a5f4891 --- /dev/null +++ b/util/js_base64.cpp @@ -0,0 +1,338 @@ +/* + * 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_base64.h" +#include +#include +#include "utils/log.h" +#include "securec.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS::Util { + namespace { + static const size_t TRAGET_TWO = 2; + static const size_t TRAGET_THREE = 3; + static const size_t TRAGET_FOUR = 4; + static const size_t TRAGET_SIX = 6; + static const size_t TRAGET_EIGHT = 8; + const char base[] = { + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 61 + }; + const char base0[] = { + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 45, 95, 61 + }; + } + Base64::Base64(napi_env env_) : env(env_) {} + + /* base64 encode */ + napi_value Base64::Encode(napi_value src, napi_value flags) + { + napi_typedarray_type type; + size_t byteOffset = 0; + size_t length = 0; + void* resultData = nullptr; + napi_value resultBuffer = nullptr; + NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); + inputEncode = static_cast(resultData) + byteOffset; + int32_t iflag = 0; + NAPI_CALL(env, napi_get_value_int32(env, flags, &iflag)); + size_t flag = 0; + flag = static_cast(iflag); + const unsigned char* rets = EncodeAchieve(inputEncode, length, flag); + void* data = nullptr; + napi_value arrayBuffer = nullptr; + size_t bufferSize = outputLen; + NAPI_CALL(env, napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer)); + if (memcpy_s(data, bufferSize, reinterpret_cast(rets), bufferSize) != 0) { + FreeMemory(rets); + HILOG_ERROR("copy ret to arraybuffer error"); + return nullptr; + } + napi_value result = nullptr; + NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result)); + FreeMemory(rets); + return result; + } + + /* base64 encodeToString */ + napi_value Base64::EncodeToString(napi_value src, napi_value flags) + { + napi_typedarray_type type; + size_t byteOffset = 0; + size_t length = 0; + void* resultData = nullptr; + napi_value resultBuffer = nullptr; + NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); + inputEncode = static_cast(resultData) + byteOffset; + int32_t iflag = 0; + NAPI_CALL(env, napi_get_value_int32(env, flags, &iflag)); + size_t flag = 0; + flag = static_cast(iflag); + unsigned char* ret = EncodeAchieve(inputEncode, length, flag); + char* rstring = nullptr; + if (outputLen > 0) { + rstring = new char[outputLen + 1]; + if (memset_s(rstring, outputLen + 1, '\0', outputLen + 1) != 0) { + FreeMemory(ret); + FreeMemory(rstring); + napi_throw_error(env, "-1", "decode rstring memset_s failed"); + } + } else { + FreeMemory(ret); + FreeMemory(rstring); + napi_throw_error(env, "-2", "outputLen is error !"); + } + for (size_t i = 0; i < outputLen; i++) { + rstring[i] = char(ret[i]); + } + std::string finalString = rstring; + const char* outString = finalString.c_str(); + const char* encString = static_cast(outString); + napi_value resultStr = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, encString, strlen(encString), &resultStr)); + FreeMemory(ret); + FreeMemory(rstring); + return resultStr; + } + + unsigned char* Base64::EncodeAchieve(const unsigned char* input, size_t inputLen, size_t iflag) + { + size_t inp = 0; + size_t temp = 0; + size_t bitWise = 0; + unsigned char* ret = nullptr; + unsigned char* bosom = nullptr; + outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR; + if ((inputLen % TRAGET_THREE) > 0) { + outputLen += TRAGET_FOUR; + } + if (outputLen > 0) { + ret = new unsigned char[outputLen + 1]; + if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != 0) { + FreeMemory(ret); + napi_throw_error(env, "-1", "ret path memset_s failed"); + } + } else { + FreeMemory(ret); + napi_throw_error(env, "-2", "outputLen is error !"); + } + bosom = ret; + while (inp < inputLen) { + temp = 0; + bitWise = 0; + while (temp < TRAGET_THREE) { + if (inp >= inputLen) { + break; + } + bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG)); + inp++; + temp++; + } + bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT)); + for (size_t i = 0; i < TRAGET_FOUR; i++) { + if (temp < i && iflag == 0) { + *bosom = base[BIT_FLG]; + } else if (temp < i && iflag != 0) { + *bosom = base0[BIT_FLG]; + } else if (temp >= i && iflag == 0) { + *bosom = base[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG]; + } else if (temp >= i && iflag != 0) { + *bosom = base0[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG]; + } + bosom++; + } + } + *bosom = '\0'; + return ret; + } + + /* base64 decode */ + napi_value Base64::Decode(napi_value src, napi_value flags) + { + napi_valuetype valuetype = napi_undefined; + napi_typeof(env, src, &valuetype); + napi_typedarray_type type; + size_t byteOffset = 0; + size_t length = 0; + void* resultData = nullptr; + napi_value resultBuffer = nullptr; + char* inputString = nullptr; + if (valuetype != napi_valuetype::napi_string) { + NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); + } + int32_t iflag = 0; + NAPI_CALL(env, napi_get_value_int32(env, flags, &iflag)); + size_t flag = 0; + flag = static_cast(iflag); + if (valuetype == napi_valuetype::napi_string) { + size_t prolen = 0; + napi_get_value_string_utf8(env, src, nullptr, 0, &prolen); + if (prolen > 0) { + inputString = new char[prolen + 1]; + if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != 0) { + FreeMemory(inputString); + napi_throw_error(env, "-1", "decode inputString memset_s failed"); + } + } else { + FreeMemory(inputString); + napi_throw_error(env, "-2", "prolen is error !"); + } + napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen); + pret = DecodeAchieve(inputString, prolen, flag); + } else if (type == napi_typedarray_type::napi_uint8_array) { + inputDecode = static_cast(resultData) + byteOffset; + pret = DecodeAchieve(inputDecode, length, flag); + } + void* data = nullptr; + napi_value arrayBuffer = nullptr; + size_t bufferSize = decodeOutLen; + NAPI_CALL(env, napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer)); + if (memcpy_s(data, bufferSize, reinterpret_cast(pret), bufferSize) != 0) { + FreeMemory(inputString); + FreeMemory(pret); + HILOG_ERROR("copy retDecode to arraybuffer error"); + return nullptr; + } + napi_value result = nullptr; + NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result)); + FreeMemory(inputString); + FreeMemory(pret); + return result; + } + + unsigned char* Base64::DecodeAchieve(const char* input, size_t inputLen, size_t iflag) + { + retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE; + decodeOutLen = retLen; + size_t equalCount = 0; + unsigned char* bosom = nullptr; + size_t inp = 0; + size_t temp = 0; + size_t bitWise = 0; + if (*(input + inputLen - 1) == '=') { + equalCount++; + } + if (*(input + inputLen - TRAGET_TWO) == '=') { + equalCount++; + } + if (*(input + inputLen - TRAGET_THREE) == '=') { + equalCount++; + } + retLen = DecodeOut(equalCount, retLen); + if (retLen > 0) { + retDecode = new unsigned char[retLen + 1]; + if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != 0) { + FreeMemory(retDecode); + napi_throw_error(env, "-1", "decode retDecode memset_s failed"); + } + } else { + FreeMemory(retDecode); + napi_throw_error(env, "-2", "retLen is error !"); + } + bosom = retDecode; + while (inp < (inputLen - equalCount)) { + temp = 0; + bitWise = 0; + while (temp < TRAGET_FOUR) { + if (inp >= (inputLen - equalCount)) { + break; + } + bitWise = (bitWise << TRAGET_SIX) | (Finds(input[inp], iflag)); + inp++; + temp++; + } + bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX); + for (size_t i = 0; i < TRAGET_THREE; i++) { + if (i == temp) { + break; + } + *bosom = static_cast((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG); + bosom++; + } + } + *bosom = '\0'; + return retDecode; + } + + size_t Base64::DecodeOut(size_t equalCount, size_t retLen) + { + if (equalCount == 1) { + decodeOutLen -= 1; + } + if (equalCount == TRAGET_TWO) { + decodeOutLen -= TRAGET_TWO; + } + switch (equalCount) { + case 0: + retLen += TRAGET_FOUR; + break; + case 1: + retLen += TRAGET_FOUR; + break; + case TRAGET_TWO: + retLen += TRAGET_THREE; + break; + default: + retLen += TRAGET_TWO; + break; + } + return retLen; + } + + /* Decoding lookup function */ + size_t Base64::Finds(char ch, size_t iflag) + { + size_t couts = 0; + if (iflag == 0) { + // 65:Number of elements in the encoding table. + for (size_t i = 0; i < 65; i++) { + if (base[i] == ch) { + couts = i; + } + } + } else { + // 65:Number of elements in the encoding table. + for (size_t i = 0; i < 65; i++) { + if (base0[i] == ch) { + couts = i; + } + } + } + return couts; + } + + /* Memory cleanup function */ + void Base64::FreeMemory(const unsigned char* address) + { + if (address != nullptr) { + delete[] address; + address = nullptr; + } + } + void Base64::FreeMemory(const char* address) + { + if (address != nullptr) { + delete[] address; + address = nullptr; + } + } +} \ No newline at end of file diff --git a/util/js_base64.h b/util/js_base64.h new file mode 100755 index 0000000000000000000000000000000000000000..a109d4301b751f4680018192854c625b138f6e42 --- /dev/null +++ b/util/js_base64.h @@ -0,0 +1,56 @@ +/* + * 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 "napi/native_api.h" +#include "napi/native_node_api.h" + +#ifndef BASE_COMPILERUNTIME_JS_UTIL_MODULE_BASE64_CLASS_H +#define BASE_COMPILERUNTIME_JS_UTIL_MODULE_BASE64_CLASS_H + +namespace OHOS::Util { + class Base64 { + public: + enum ConverterFlags { + BIT_FLG = 0x40, + SIXTEEN_FLG = 0x3F, + XFF_FLG = 0xFF, + }; + public: + explicit Base64(napi_env env); + virtual ~Base64(){} + napi_value Encode(napi_value src, napi_value flags); + napi_value EncodeToString(napi_value src, napi_value flags); + napi_value Decode(napi_value src, napi_value flags); + private: + napi_env env; + unsigned char* DecodeAchieve(const char* input, size_t inputLen, size_t iflag); + unsigned char* EncodeAchieve(const unsigned char* input, size_t inputLen, size_t iflag); + size_t Finds(char ch, size_t iflag); + size_t DecodeOut(size_t equalCount, size_t retLen); + void FreeMemory(const unsigned char* address); + void FreeMemory(const char* address); + size_t retLen = 0; + size_t decodeOutLen = 0; + size_t outputLen = 0; + unsigned char* pret = nullptr; + const unsigned char* inputEncode = nullptr; + const char* inputDecode = nullptr; + unsigned char* retDecode = nullptr; + }; +} +#endif \ No newline at end of file diff --git a/util/js_rational.cpp b/util/js_rational.cpp new file mode 100755 index 0000000000000000000000000000000000000000..b00ab03c803f4030570345ff4f86c47c63568c3d --- /dev/null +++ b/util/js_rational.cpp @@ -0,0 +1,338 @@ +/* + * 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_rational.h" +#include +#include +#include +#include "utils/log.h" +#include "securec.h" +namespace OHOS::Util { + RationalNumber::RationalNumber(napi_env env, int num, int den) + { + env_ = env; + napi_value result = nullptr; + den < 0 ? num *= -1, den *= -1 : 0; + if (den == 0) { + if (num > 0) { + mnum = 1; + mden = 0; + } else if (num < 0) { + mnum = -1; + mden = 0; + } else { + mnum = 0; + mden = 0; + } + } else if (num == 0) { + mnum = 0; + mden = 1; + } else { + napi_value num1 = nullptr; + napi_value num2 = nullptr; + napi_create_int32(env_, num, &num1); + napi_create_int32(env_, den, &num2); + result = GetCommonDivisor(num1, num2); + int gnum = 0; + napi_get_value_int32(env_, result, &gnum); + if (gnum != 0) { + mnum = num / gnum; + mden = den / gnum; + } + } + } + + napi_value RationalNumber::CreatRationalFromString(napi_value str, napi_value RationalNumberClass) const + { + size_t len = 0; + int flag = 0; + napi_get_value_string_utf8(env_, str, nullptr, 0, &len); + char* buffer = nullptr; + if (len > 0) { + buffer = new char[len + 1]; + if (memset_s(buffer, len + 1, '\0', len + 1) != 0) { + napi_throw_error(env_, "-1", "memset_s failed"); + } + } else { + napi_throw_error(env_, "NullPointerException", "string must not be null!"); + } + napi_get_value_string_utf8(env_, str, buffer, len + 1, &len); + std::string buf = buffer; + delete []buffer; + if (buf.compare("NaN") == 0) { + return GreateObj(0, 0, RationalNumberClass); + } else if (buf.compare("Infinity") == 0) { + return GreateObj(1, 0, RationalNumberClass); + } else if (buf.compare("-Infinity") == 0) { + return GreateObj(-1, 0, RationalNumberClass); + } + size_t colon = buf.find(':'); + size_t semicolon = buf.find('/'); + if ((colon == std::string::npos && semicolon == std::string::npos) + || (colon != std::string::npos && semicolon != std::string::npos)) { + napi_throw_error(env_, "invalidRational", "string invalid!"); + } + size_t index = (colon != std::string::npos) ? colon : semicolon; + std::string s1 = buf.substr(0, index); + std::string s2 = buf.substr(index + 1, buf.size()); + size_t len1 = s1.size(); + size_t len2 = s2.size(); + for (int i = 1; i < len1; i++) { + if (((s1[0] == '+') || (s1[0] == '-') || (isdigit(s1[0]))) && (isdigit(s1[i]))) { + flag = 1; + } else { + napi_throw_error(env_, "invalidRational", "string invalid!"); + } + } + int num1 = stoi(s1) * flag; + for (int i = 1; i < len2; i++) { + if (((s2[0] == '+') || (s2[0] == '-') || (isdigit(s2[0]))) && (isdigit(s2[i]))) { + flag = 1; + } else { + napi_throw_error(env_, "invalidRational", "string invalid!"); + } + } + int num2 = stoi(s2) * flag; + return GreateObj(num1, num2, RationalNumberClass); + } + + napi_value RationalNumber::GreateObj(int num1, int num2, napi_value RationalNumberClass) const + { + napi_value argvs[2] = { nullptr }; + NAPI_CALL(env_, napi_create_int32(env_, num1, &argvs[0])); + NAPI_CALL(env_, napi_create_int32(env_, num2, &argvs[1])); + size_t argc = 2; + napi_value res = nullptr; + NAPI_CALL(env_, napi_new_instance(env_, RationalNumberClass, argc, argvs, &res)); + return res; + } + + napi_value RationalNumber::CompareTo(napi_value rational) const + { + RationalNumber* other = nullptr; + NAPI_CALL(env_, napi_unwrap(env_, rational, reinterpret_cast(&other))); + if (mnum == other->mnum && mden == other->mden) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, 0, &result)); + return result; + } else if (mnum == 0 && mden == 0) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, 1, &result)); + return result; + } else if ((other->mnum == 0) && (other->mden == 0)) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, -1, &result)); + return result; + } else if ((mden == 0 && mnum > 0) || (other->mden == 0 && other->mnum < 0)) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, 1, &result)); + return result; + } else if ((mden == 0 && mnum < 0) || (other->mden == 0 && other->mnum > 0)) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, -1, &result)); + return result; + } + long thisnum = static_cast(mnum) * other->mden; + long othernum = static_cast(other->mnum) * mden; + if (thisnum < othernum) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, -1, &result)); + return result; + } else if (thisnum > othernum) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int64(env_, 1, &result)); + return result; + } else { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, 0, &result)); + return result; + } + } + + napi_value RationalNumber::Equals(napi_value obj) const + { + RationalNumber* object = nullptr; + napi_status status = napi_unwrap(env_, obj, reinterpret_cast(&object)); + bool flag = false; + long thisnum = static_cast(mnum) * object->mden; + long objnum = static_cast(object->mnum) * mden; + if (status != napi_ok) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + if (mnum == object->mnum && mden == object->mden) { + flag = true; + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } else if ((thisnum == objnum) && (mnum != 0 && mden != 0) && (object->mnum != 0 && object->mden != 0)) { + flag = true; + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } else if ((mnum == 0 && mden != 0) && (object->mnum == 0 && object->mden != 0)) { + flag = true; + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } else if ((mnum > 0 && mden == 0) && (object->mnum > 0 && object->mden == 0)) { + flag = true; + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } else if ((mnum < 0 && mden == 0) && (object->mnum < 0 && object->mden == 0)) { + flag = true; + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } else { + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + } + + napi_value RationalNumber::Value() const + { + if (mnum > 0 && mden == 0) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, INT_MAX, &result)); + return result; + } else if (mnum < 0 && mden == 0) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, INT_MIN, &result)); + return result; + } else if ((mnum == 0) && (mden == 0)) { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, 0, &result)); + return result; + } else { + if (mnum % mden == 0) { + int val = mnum / mden; + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, val, &result)); + return result; + } else { + double num = mnum; + double den = mden; + double res = num / den; + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_double(env_, res, &result)); + return result; + } + } + } + + napi_value RationalNumber::GetCommonDivisor(napi_value num1, napi_value num2) const + { + int temp = 0; + int number1 = 0; + int number2 = 0; + napi_get_value_int32(env_, num1, &number1); + napi_get_value_int32(env_, num2, &number2); + if (number1 == 0 || number2 == 0) { + napi_throw_error(env_, "invalidnumber", "Parameter cannot be zero!"); + } + if (number1 < number2) { + temp = number1; + number1 = number2; + number2 = temp; + } + while (number1 % number2 != 0) { + temp = number1 % number2; + number1 = number2; + number2 = temp; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, number2, &result)); + return result; + } + + napi_value RationalNumber::GetDenominator() const + { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, mden, &result)); + return result; + } + + napi_value RationalNumber::GetNumerator() const + { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_int32(env_, mnum, &result)); + return result; + } + + napi_value RationalNumber::IsFinite() const + { + bool flag = false; + if (mden != 0) { + flag = true; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + + napi_value RationalNumber::IsInfinite() const + { + bool flag = false; + if ((mnum != 0) && (mden == 0)) { + flag = true; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + + napi_value RationalNumber::IsNaN() const + { + bool flag = false; + if ((mnum == 0) && (mden == 0)) { + flag = true; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + + napi_value RationalNumber::IsZero() const + { + bool flag = false; + if ((mnum == 0) && (mden != 0)) { + flag = true; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, flag, &result)); + return result; + } + + napi_value RationalNumber::ToString() const + { + std::string buf; + if (mnum == 0 && mden == 0) { + buf = "NaN"; + } else if (mnum > 0 && mden == 0) { + buf = "Infinity"; + } else if (mnum < 0 && mden == 0) { + buf = "-Infinity"; + } else { + buf = std::to_string(mnum) + "/" + std::to_string(mden); + } + napi_value res = nullptr; + napi_create_string_utf8(env_, buf.c_str(), buf.size(), &res); + return res; + } +} \ No newline at end of file diff --git a/util/js_rational.h b/util/js_rational.h new file mode 100755 index 0000000000000000000000000000000000000000..3ed848f16fdb80d81449ffa67159c34bc87ef2ce --- /dev/null +++ b/util/js_rational.h @@ -0,0 +1,47 @@ +/* + * 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 BASE_COMPILERUNTIME_JS_UTIL_MODULE_RATIONALNUMBER_CLASS_H +#define BASE_COMPILERUNTIME_JS_UTIL_MODULE_RATIONALNUMBER_CLASS_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS::Util { + class RationalNumber { + public: + explicit RationalNumber(napi_env env, int numerator, int denominator); + virtual ~RationalNumber(){} + napi_value CreatRationalFromString(napi_value str, napi_value RationalNumberClass) const; + napi_value CompareTo(napi_value rational) const; + napi_value Equals(napi_value obj) const; + napi_value Value() const; + napi_value GetCommonDivisor(napi_value num1, napi_value num2) const; + napi_value GetDenominator() const; + napi_value GetNumerator() const; + napi_value IsFinite() const; + napi_value IsInfinite() const; + napi_value IsNaN() const; + napi_value IsZero() const; + napi_value ToString() const; + private: + int mnum = 0; + int mden = 0; + napi_env env_; + napi_value GreateObj(int num1, int num2, napi_value RationalNumberClass) const; + }; +} +#endif \ No newline at end of file diff --git a/util/js_textdecoder.cpp b/util/js_textdecoder.cpp index 912fc640c95881e5143c7150214060fb2ec82682..b5c412c6f1e05391b7ed23180cb5c2a00e647aeb 100644 --- a/util/js_textdecoder.cpp +++ b/util/js_textdecoder.cpp @@ -25,157 +25,166 @@ #include "securec.h" #include "unicode/unistr.h" #include "utils/log.h" - -TextDecoder::TextDecoder(napi_env env, std::string buff, std::vector optionVec) - : env_(env), label_(0), encStr_(buff), tranTool_(nullptr, nullptr) -{ - uint32_t i32Flag = 0; - if (optionVec.size() == 2) { // 2:Meaning of optionVec size 2 - if (optionVec[0] >= 0 && optionVec[1] >= 0) { - i32Flag |= optionVec[0] ? FATAL_FLG : 0; - i32Flag |= optionVec[1] ? IGNORE_BOM_FLG : 0; - } else if (optionVec[0] >= 0 && optionVec[1] < 0) { - i32Flag |= optionVec[0] ? FATAL_FLG : 0; - } else if (optionVec[0] < 0 && optionVec[1] >= 0) { - i32Flag |= optionVec[1] ? IGNORE_BOM_FLG : 0; +namespace OHOS::Util { + TextDecoder::TextDecoder(napi_env env, std::string buff, std::vector optionVec) + : env_(env), label_(0), encStr_(buff), tranTool_(nullptr, nullptr) + { + uint32_t i32Flag = 0; + if (optionVec.size() == 2) { // 2:Meaning of optionVec size 2 + if (optionVec[0] >= 0 && optionVec[1] >= 0) { + i32Flag |= optionVec[0] ? FATAL_FLG : 0; + i32Flag |= optionVec[1] ? IGNORE_BOM_FLG : 0; + } else if (optionVec[0] >= 0 && optionVec[1] < 0) { + i32Flag |= optionVec[0] ? FATAL_FLG : 0; + } else if (optionVec[0] < 0 && optionVec[1] >= 0) { + i32Flag |= optionVec[1] ? IGNORE_BOM_FLG : 0; + } } + label_ = i32Flag; + bool fatal = + (i32Flag & FATAL_FLG) == FATAL_FLG; + UErrorCode codeflag = U_ZERO_ERROR; + char* pStr = const_cast(encStr_.c_str()); + UConverter* conv = ucnv_open(pStr, &codeflag); + if (U_FAILURE(codeflag)) { + HILOG_ERROR("ucnv_open failed !"); + return; + } + if (fatal) { + codeflag = U_ZERO_ERROR; + ucnv_setToUCallBack(conv, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &codeflag); + } + TransformToolPointer tempTranTool(conv, ConverterClose); + tranTool_ = std::move(tempTranTool); } - label_ = i32Flag; - bool fatal = - (i32Flag & FATAL_FLG) == FATAL_FLG; - UErrorCode codeflag = U_ZERO_ERROR; - char* pStr = const_cast(encStr_.c_str()); - UConverter* conv = ucnv_open(pStr, &codeflag); - if (U_FAILURE(codeflag)) { - HILOG_ERROR("ucnv_open failed !"); - return; - } - if (fatal) { - codeflag = U_ZERO_ERROR; - ucnv_setToUCallBack(conv, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &codeflag); - } - TransformToolPointer tempTranTool(conv, ConverterClose); - tranTool_ = std::move(tempTranTool); -} -napi_value TextDecoder::Decode(napi_value src, bool iflag) -{ - HILOG_INFO("textcoder Decode start"); - uint32_t flags = 0; - flags |= iflag ? 0 : FLUSH_FLG; - UBool flush = ((flags & FLUSH_FLG)) == FLUSH_FLG; - napi_typedarray_type type; - size_t length = 0; - void* data1 = nullptr; - napi_value arrayBuffer = nullptr; - size_t byteOffset = 0; - NAPI_CALL(env_, napi_get_typedarray_info(env_, src, &type, &length, &data1, &arrayBuffer, &byteOffset)); - const char* source = static_cast(data1); - size_t sourceLength = length; - UErrorCode codeflag = U_ZERO_ERROR; - size_t limit = GetMinByteSize() * sourceLength; - size_t len = limit * sizeof(UChar); - UChar* arr = nullptr; - if (limit > 0) { - arr = new UChar[limit + 1]; - if (memset_s(arr, len + sizeof(UChar), 0, len + sizeof(UChar)) != 0) { - HILOG_ERROR("decode arr memset_s failed"); - if (arr != nullptr) { - delete[] arr; - arr = nullptr; + + napi_value TextDecoder::Decode(napi_value src, bool iflag) + { + uint32_t flags = 0; + flags |= iflag ? 0 : FLUSH_FLG; + UBool flush = ((flags & FLUSH_FLG)) == FLUSH_FLG; + napi_typedarray_type type; + size_t length = 0; + void* data1 = nullptr; + size_t byteOffset = 0; + napi_value arrayBuffer = nullptr; + NAPI_CALL(env_, napi_get_typedarray_info(env_, src, &type, &length, &data1, &arrayBuffer, &byteOffset)); + const char* source = static_cast(data1); + UErrorCode codeFlag = U_ZERO_ERROR; + size_t limit = GetMinByteSize() * length; + size_t len = limit * sizeof(UChar); + UChar* arr = nullptr; + if (limit > 0) { + arr = new UChar[limit + 1]; + if (memset_s(arr, len + sizeof(UChar), 0, len + sizeof(UChar)) != 0) { + HILOG_ERROR("decode arr memset_s failed"); + FreedMemory(arr); + return nullptr; } + } else { + HILOG_ERROR("limit is error"); return nullptr; } - } else { - HILOG_ERROR("limit is error"); - return nullptr; - } - UChar* target = arr; - size_t tarStartPos = (intptr_t)arr; - ucnv_toUnicode(GetConverterPtr(), &target, target + len, &source, source + sourceLength, nullptr, flush, &codeflag); - size_t resultLength = 0; - bool omitInitialBom = false; - if (U_SUCCESS(codeflag)) { - if (limit > 0) { - resultLength = (intptr_t)target - tarStartPos; - if (resultLength > 0 && IsUnicode() && !IsIgnoreBom() && !IsBomFlag()) { - if (arr[0] == 0xFEFF) { - omitInitialBom = true; - } - label_ |= BOM_SEEN_FLG; - } + UChar* target = arr; + size_t tarStartPos = (intptr_t)arr; + ucnv_toUnicode(GetConverterPtr(), &target, target + len, &source, source + length, nullptr, flush, &codeFlag); + size_t resultLength = 0; + bool omitInitialBom = false; + DecodeArr decArr(target, tarStartPos, limit); + SetBomFlag(arr, codeFlag, decArr, resultLength, omitInitialBom); + UChar* arrDat = arr; + if (omitInitialBom && resultLength > 0) { + arrDat = &arr[2]; // 2: Obtains the 2 value of the array. } + std::u16string tempStr16(arrDat); + std::string tepStr = std::wstring_convert, char16_t> {}.to_bytes(tempStr16); + const char* tempCh = tepStr.c_str(); + char* rstCh = const_cast(tempCh); + napi_value resultStr = nullptr; + NAPI_CALL(env_, napi_create_string_utf8(env_, rstCh, strlen(rstCh), &resultStr)); + FreedMemory(arr); + if (flush) { + label_ &= BOM_SEEN_FLG; + Reset(); + } + return resultStr; } - UChar* arrDat = arr; - if (omitInitialBom && resultLength > 0) { - arrDat = &arr[2]; // 2: Obtains the 2 value of the array. - } - std::u16string tempStr16(arrDat); - std::string tepStr = std::wstring_convert, char16_t> {}.to_bytes(tempStr16); - const char* tempCh = tepStr.c_str(); - char* rstCh = const_cast(tempCh); - napi_value resultStr = nullptr; - NAPI_CALL(env_, napi_create_string_utf8(env_, rstCh, strlen(rstCh), &resultStr)); - if (arr != nullptr) { - delete[] arr; - arr = nullptr; + + napi_value TextDecoder::GetEncoding() const + { + size_t length = strlen(encStr_.c_str()); + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_string_utf8(env_, encStr_.c_str(), length, &result)); + return result; } - if (flush) { - label_ &= BOM_SEEN_FLG; - Reset(); + + napi_value TextDecoder::GetFatal() const + { + uint32_t temp = label_ & FATAL_FLG; + bool comRst = false; + if (temp == FATAL_FLG) { + comRst = true; + } else { + comRst = false; + } + napi_value result = nullptr; + NAPI_CALL(env_, napi_get_boolean(env_, comRst, &result)); + return result; } - return resultStr; -} -napi_value TextDecoder::GetEncoding() const -{ - size_t length = strlen(encStr_.c_str()); - napi_value result = nullptr; - NAPI_CALL(env_, napi_create_string_utf8(env_, encStr_.c_str(), length, &result)); - return result; -} + napi_value TextDecoder::GetIgnoreBOM() const + { + uint32_t temp = label_ & IGNORE_BOM_FLG; + bool comRst = false; + if (temp == IGNORE_BOM_FLG) { + comRst = true; + } else { + comRst = false; + } + napi_value result; + NAPI_CALL(env_, napi_get_boolean(env_, comRst, &result)); + return result; + } -napi_value TextDecoder::GetFatal() const -{ - uint32_t temp = label_ & FATAL_FLG; - bool comRst = false; - if (temp == FATAL_FLG) { - comRst = true; - } else { - comRst = false; + size_t TextDecoder::GetMinByteSize() const + { + if (tranTool_ == nullptr) { + return -1; + } + size_t res = ucnv_getMinCharSize(tranTool_.get()); + return res; } - napi_value result = nullptr; - NAPI_CALL(env_, napi_get_boolean(env_, comRst, &result)); - return result; -} -napi_value TextDecoder::GetIgnoreBOM() const -{ - uint32_t temp = label_ & IGNORE_BOM_FLG; - bool comRst = false; - if (temp == IGNORE_BOM_FLG) { - comRst = true; - } else { - comRst = false; + void TextDecoder::Reset() const + { + if (tranTool_ == nullptr) { + return; + } + ucnv_reset(tranTool_.get()); } - napi_value result; - NAPI_CALL(env_, napi_get_boolean(env_, comRst, &result)); - return result; -} -size_t TextDecoder::GetMinByteSize() const -{ - if (tranTool_ == nullptr) { - return -1; + void TextDecoder::FreedMemory(UChar *pData) + { + if (pData != nullptr) { + delete[] pData; + pData = nullptr; + } } - size_t res = ucnv_getMinCharSize(tranTool_.get()); - return res; -} -void TextDecoder::Reset() const -{ - if (tranTool_ == nullptr) { - return; + void TextDecoder::SetBomFlag(const UChar* arr, const UErrorCode codeFlag, const DecodeArr decArr , size_t &rstLen, bool &bomFlag) + { + if (arr == nullptr ) { + return; + } + if (U_SUCCESS(codeFlag)) { + if (decArr.limitLen > 0) { + rstLen = (intptr_t)decArr.target - decArr.tarStartPos; + if (rstLen > 0 && IsUnicode() && !IsIgnoreBom() && !IsBomFlag()) { + bomFlag = (arr[0] == 0xFEFF) ? true : false; + label_ |= BOM_SEEN_FLG; + } + } + } } - ucnv_reset(tranTool_.get()); -} +} \ No newline at end of file diff --git a/util/js_textdecoder.h b/util/js_textdecoder.h index 2ff578c366f5cb3e28e7e084646b414cce30f555..7f94fd926b7befcf025ea9f235a26ccd8bdf9061 100644 --- a/util/js_textdecoder.h +++ b/util/js_textdecoder.h @@ -24,65 +24,78 @@ #include "unicode/ucnv.h" using TransformToolPointer = std::unique_ptr; - -class TextDecoder { -public: - enum ConverterFlags { - FLUSH_FLG = 0x1, - FATAL_FLG = 0x2, - IGNORE_BOM_FLG = 0x4, - UNICODE_FLG = 0x8, - BOM_SEEN_FLG = 0x10, +namespace OHOS::Util { + struct DecodeArr { + DecodeArr(UChar* tarPos, size_t tarStaPos, size_t limLen) { + this->target = tarPos; + this->tarStartPos = tarStaPos; + this->limitLen = limLen; + } + UChar* target = 0; + size_t tarStartPos = 0; + size_t limitLen = 0; }; -public: - TextDecoder(napi_env env, std::string buff, std::vector optionVec); - virtual ~TextDecoder() {} - napi_value Decode(napi_value src, bool iflag); - napi_value GetEncoding() const; - napi_value GetFatal() const; - napi_value GetIgnoreBOM() const; - size_t GetMinByteSize() const; - void Reset() const; - UConverter *GetConverterPtr() const - { - return tranTool_.get(); - } - bool IsBomFlag() const - { - uint32_t temp = label_ & BOM_SEEN_FLG; - if (temp == BOM_SEEN_FLG) { - return true; - } else { - return false; + + class TextDecoder { + public: + enum ConverterFlags { + FLUSH_FLG = 0x1, + FATAL_FLG = 0x2, + IGNORE_BOM_FLG = 0x4, + UNICODE_FLG = 0x8, + BOM_SEEN_FLG = 0x10, + }; + public: + TextDecoder(napi_env env, std::string buff, std::vector optionVec); + virtual ~TextDecoder() {} + napi_value Decode(napi_value src, bool iflag); + napi_value GetEncoding() const; + napi_value GetFatal() const; + napi_value GetIgnoreBOM() const; + size_t GetMinByteSize() const; + void Reset() const; + UConverter *GetConverterPtr() const + { + return tranTool_.get(); } - } - bool IsUnicode() const - { - uint32_t temp = label_ & UNICODE_FLG; - if (temp == UNICODE_FLG) { - return true; - } else { - return false; + bool IsBomFlag() const + { + uint32_t temp = label_ & BOM_SEEN_FLG; + if (temp == BOM_SEEN_FLG) { + return true; + } else { + return false; + } } - } - bool IsIgnoreBom() const - { - uint32_t temp = label_ & IGNORE_BOM_FLG; - if (temp == IGNORE_BOM_FLG) { - return true; - } else { - return false; + bool IsUnicode() const + { + uint32_t temp = label_ & UNICODE_FLG; + if (temp == UNICODE_FLG) { + return true; + } else { + return false; + } } - } - static void ConverterClose(UConverter* pointer) - { - ucnv_close(pointer); - } -private: - void FreedMemory(UChar *pData); - napi_env env_; - uint32_t label_; - std::string encStr_; - TransformToolPointer tranTool_; -}; + bool IsIgnoreBom() const + { + uint32_t temp = label_ & IGNORE_BOM_FLG; + if (temp == IGNORE_BOM_FLG) { + return true; + } else { + return false; + } + } + static void ConverterClose(UConverter* pointer) + { + ucnv_close(pointer); + } + private: + void SetBomFlag(const UChar* arr, const UErrorCode codeFlag, const DecodeArr decArr, size_t& rstLen, bool& bomFlag); + void FreedMemory(UChar* pData); + napi_env env_; + uint32_t label_; + std::string encStr_; + TransformToolPointer tranTool_; + }; +} #endif /* FOUNDATION_CCRUNTIME_TEXTCODER_JS_TEXTDECODER_H */ diff --git a/util/js_textencoder.cpp b/util/js_textencoder.cpp index ee8e080ac12f36b674382467318cf7a981a3470a..efe55a791ac6a2bcff71efd1cfa401757dd1dd7b 100644 --- a/util/js_textencoder.cpp +++ b/util/js_textencoder.cpp @@ -20,75 +20,76 @@ #include "native_engine.h" #include "securec.h" #include "utils/log.h" +namespace OHOS::Util { + TextEncoder::TextEncoder(napi_env env) : env_(env), encoding_("utf-8") + { + } -TextEncoder::TextEncoder(napi_env env) : env_(env), encoding_("utf-8") -{ -} - -napi_value TextEncoder::GetEncoding() const -{ - napi_value result = nullptr; - NAPI_CALL(env_, napi_create_string_utf8(env_, encoding_.c_str(), encoding_.length(), &result)); + napi_value TextEncoder::GetEncoding() const + { + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_string_utf8(env_, encoding_.c_str(), encoding_.length(), &result)); - return result; -} + return result; + } -napi_value TextEncoder::Encode(napi_value src) const -{ - char *buffer = nullptr; - size_t bufferSize = 0; + napi_value TextEncoder::Encode(napi_value src) const + { + char *buffer = nullptr; + size_t bufferSize = 0; - NAPI_CALL(env_, napi_get_value_string_utf8(env_, src, buffer, 0, &bufferSize)); - NAPI_ASSERT(env_, bufferSize > 0, "bufferSize == 0"); - buffer = new char[bufferSize + 1]; + NAPI_CALL(env_, napi_get_value_string_utf8(env_, src, buffer, 0, &bufferSize)); + NAPI_ASSERT(env_, bufferSize > 0, "bufferSize == 0"); + buffer = new char[bufferSize + 1]; - NAPI_CALL(env_, napi_get_value_string_utf8(env_, src, buffer, bufferSize + 1, &bufferSize)); + NAPI_CALL(env_, napi_get_value_string_utf8(env_, src, buffer, bufferSize + 1, &bufferSize)); - void* data = nullptr; - napi_value arrayBuffer = nullptr; - NAPI_CALL(env_, napi_create_arraybuffer(env_, bufferSize, &data, &arrayBuffer)); - if (memcpy_s(data, bufferSize, reinterpret_cast(buffer), bufferSize) != 0) { - HILOG_ERROR("copy buffer to arraybuffer error"); - return nullptr; - } + void* data = nullptr; + napi_value arrayBuffer = nullptr; + NAPI_CALL(env_, napi_create_arraybuffer(env_, bufferSize, &data, &arrayBuffer)); + if (memcpy_s(data, bufferSize, reinterpret_cast(buffer), bufferSize) != 0) { + HILOG_ERROR("copy buffer to arraybuffer error"); + return nullptr; + } - delete []buffer; + delete []buffer; - napi_value result = nullptr; - NAPI_CALL(env_, napi_create_typedarray(env_, napi_uint8_array, bufferSize, arrayBuffer, 0, &result)); + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_typedarray(env_, napi_uint8_array, bufferSize, arrayBuffer, 0, &result)); - return result; -} + return result; + } -napi_value TextEncoder::EncodeInto(napi_value src, napi_value dest) const -{ - napi_typedarray_type type; - size_t byteOffset = 0; - size_t length = 0; - void* resultData = nullptr; - napi_value resultBuffer = nullptr; - NAPI_CALL(env_, napi_get_typedarray_info(env_, dest, &type, &length, &resultData, &resultBuffer, &byteOffset)); + napi_value TextEncoder::EncodeInto(napi_value src, napi_value dest) const + { + napi_typedarray_type type; + size_t byteOffset = 0; + size_t length = 0; + void* resultData = nullptr; + napi_value resultBuffer = nullptr; + NAPI_CALL(env_, napi_get_typedarray_info(env_, dest, &type, &length, &resultData, &resultBuffer, &byteOffset)); - char* writeResult = static_cast(resultData) + byteOffset; + char* writeResult = static_cast(resultData) + byteOffset; - int32_t nchars = 0; - int32_t written = 0; - NativeEngine* engine = reinterpret_cast(env_); - NativeValue* nativeValue = reinterpret_cast(src); - engine->EncodeToUtf8(nativeValue, writeResult, &written, length, &nchars); + int32_t nchars = 0; + int32_t written = 0; + NativeEngine* engine = reinterpret_cast(env_); + NativeValue* nativeValue = reinterpret_cast(src); + engine->EncodeToUtf8(nativeValue, writeResult, &written, length, &nchars); - napi_value result = nullptr; - NAPI_CALL(env_, napi_create_object(env_, &result)); + napi_value result = nullptr; + NAPI_CALL(env_, napi_create_object(env_, &result)); - napi_value read = nullptr; - NAPI_CALL(env_, napi_create_uint32(env_, nchars, &read)); + napi_value read = nullptr; + NAPI_CALL(env_, napi_create_uint32(env_, nchars, &read)); - NAPI_CALL(env_, napi_set_named_property(env_, result, "read", read)); + NAPI_CALL(env_, napi_set_named_property(env_, result, "read", read)); - napi_value resWritten = nullptr; - NAPI_CALL(env_, napi_create_uint32(env_, written, &resWritten)); + napi_value resWritten = nullptr; + NAPI_CALL(env_, napi_create_uint32(env_, written, &resWritten)); - NAPI_CALL(env_, napi_set_named_property(env_, result, "written", resWritten)); + NAPI_CALL(env_, napi_set_named_property(env_, result, "written", resWritten)); - return result; -} + return result; + } +} \ No newline at end of file diff --git a/util/js_textencoder.h b/util/js_textencoder.h index ed6bb552930492c7240f6dec321314c07ecd6531..ab9d419c86e9e8c31263d8dc6c423f6237863604 100644 --- a/util/js_textencoder.h +++ b/util/js_textencoder.h @@ -20,20 +20,20 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" - -class TextEncoder { -public: - explicit TextEncoder(napi_env env); - - virtual ~TextEncoder() {} - - napi_value GetEncoding() const; - napi_value Encode(napi_value src) const; - napi_value EncodeInto(napi_value src, napi_value dest) const; - -private: - napi_env env_; - std::string encoding_; -}; - +namespace OHOS::Util { + class TextEncoder { + public: + explicit TextEncoder(napi_env env); + + virtual ~TextEncoder() {} + + napi_value GetEncoding() const; + napi_value Encode(napi_value src) const; + napi_value EncodeInto(napi_value src, napi_value dest) const; + + private: + napi_env env_; + std::string encoding_; + }; +} #endif /* FOUNDATION_CCRUNTIME_TEXTCODER_JS_TEXTENCODER_H */ \ No newline at end of file diff --git a/util/native_module_util.cpp b/util/native_module_util.cpp index 7a28a8a9a4cd97d203cfa3e177fd776ba69cdb29..e6f372e42b68cb07ffbc98475e7e49dfa45d3ca6 100644 --- a/util/native_module_util.cpp +++ b/util/native_module_util.cpp @@ -13,11 +13,13 @@ * limitations under the License. */ -#include +#include #include #include "js_textdecoder.h" #include "js_textencoder.h" +#include "js_rational.h" +#include "js_base64.h" #include "napi/native_api.h" #include "napi/native_node_api.h" @@ -27,6 +29,7 @@ extern const char _binary_util_js_js_start[]; extern const char _binary_util_js_js_end[]; namespace OHOS::Util { static std::string temp = "cdfijoOs"; + napi_value RationalNumberClass = nullptr; static std::string DealWithPrintf(const std::string &format, const std::vector &value) { size_t i = 0; @@ -282,9 +285,9 @@ namespace OHOS::Util { NAPI_CALL(env, napi_wrap( env, thisVar, objectInfo, [](napi_env env, void* data, void* hint) { - auto objectInfo = (TextDecoder*)data; - if (objectInfo != nullptr) { - delete objectInfo; + auto objInfo = (TextDecoder*)data; + if (objInfo != nullptr) { + delete objInfo; } }, nullptr, nullptr)); @@ -375,9 +378,9 @@ namespace OHOS::Util { NAPI_CALL(env, napi_wrap( env, thisVar, object, [](napi_env env, void* data, void* hint) { - auto object = (TextEncoder*)data; - if (object != nullptr) { - delete object; + auto obj = (TextEncoder*)data; + if (obj != nullptr) { + delete obj; } }, nullptr, nullptr)); @@ -449,6 +452,203 @@ namespace OHOS::Util { return result; } + static napi_value RationalNumberConstructor(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + void* data = nullptr; + size_t argc = 3; + napi_value args[2] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data)); + int num = 0; + int den = 0; + napi_get_value_int32(env, args[0], &num); + napi_get_value_int32(env, args[1], &den); + auto objectInfo = new RationalNumber(env, num, den); + NAPI_CALL(env, napi_wrap( + env, thisVar, objectInfo, + [](napi_env env, void* data, void* hint) { + auto objInfo = (RationalNumber*)data; + if (objInfo != nullptr) { + delete objInfo; + } + }, + nullptr, nullptr)); + return thisVar; + } + + static napi_value CreatRationalFromString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 1; + size_t argc = 1; + napi_value args = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= requireArgc, "Wrong nuamber of arguments"); + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, args, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected"); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + if (RationalNumberClass == nullptr) { + napi_throw_error(env, "NullException", "RationalNumberClass must not be null!"); + } + return object->CreatRationalFromString(args, RationalNumberClass); + } + + static napi_value CompareTo(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 1; + size_t argc = 1; + napi_value args = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= requireArgc, "Wrong nuamber of arguments"); + RationalNumber* object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + return object->CompareTo(args); + } + + static napi_value Equals(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 1; + size_t argc = 1; + napi_value args = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= requireArgc, "Wrong nuamber of arguments"); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + return object->Equals(args); + } + + static napi_value Value(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + return object->Value(); + } + + static napi_value GetCommonDivisor(napi_env env, napi_callback_info info) + { + size_t argc = 2; + napi_value argv[2] = {0}; + napi_value thisVar = nullptr; + void* data = nullptr; + napi_value args = nullptr; + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr)); + napi_valuetype valuetype1; + napi_valuetype valuetype2; + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype1)); + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype2)); + NAPI_ASSERT(env, valuetype1 == napi_number, "Wrong argument type. String expected"); + NAPI_ASSERT(env, valuetype2 == napi_number, "Wrong argument type. String expected"); + RationalNumber* object = nullptr; + napi_unwrap(env, thisVar, (void**)&object); + napi_value result = nullptr; + result = object->GetCommonDivisor(argv[0], argv[1]); + return result; + } + + static napi_value GetDenominator(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->GetDenominator(); + return result; + } + + static napi_value GetNumerator(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->GetNumerator(); + return result; + } + + static napi_value IsFinite(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->IsFinite(); + return result; + } + + static napi_value IsInfinite(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->IsInfinite(); + return result; + } + + static napi_value IsNaN(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->IsNaN(); + return result; + } + static napi_value IsZero(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->IsZero(); + return result; + } + + static napi_value ToString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + RationalNumber* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->ToString(); + return result; + } + + static napi_value RationalNumberInit(napi_env env, napi_value exports) + { + const char* RationalNumberClassName = "RationalNumber"; + static napi_property_descriptor RationalNumberDesc[] = { + DECLARE_NAPI_FUNCTION("creatRationalFromString", CreatRationalFromString), + DECLARE_NAPI_FUNCTION("compareTo", CompareTo), + DECLARE_NAPI_FUNCTION("equals", Equals), + DECLARE_NAPI_FUNCTION("value", Value), + DECLARE_NAPI_FUNCTION("getCommonDivisor", GetCommonDivisor), + DECLARE_NAPI_FUNCTION("getDenominator", GetDenominator), + DECLARE_NAPI_FUNCTION("getNumerator", GetNumerator), + DECLARE_NAPI_FUNCTION("isFinite", IsFinite), + DECLARE_NAPI_FUNCTION("isInfinite", IsInfinite), + DECLARE_NAPI_FUNCTION("isNaN", IsNaN), + DECLARE_NAPI_FUNCTION("isZero", IsZero), + DECLARE_NAPI_FUNCTION("toString", ToString), + }; + NAPI_CALL(env, napi_define_class(env, RationalNumberClassName, strlen(RationalNumberClassName), + RationalNumberConstructor, nullptr, + sizeof(RationalNumberDesc) / sizeof(RationalNumberDesc[0]), + RationalNumberDesc, &RationalNumberClass)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("RationalNumber", RationalNumberClass) + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; + } + static napi_value TextcoderInit(napi_env env, napi_value exports) { const char* textEncoderClassName = "TextEncoder"; @@ -485,6 +685,122 @@ namespace OHOS::Util { return exports; } + static napi_value Base64Constructor(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 objectInfo = new Base64(env); + napi_wrap( + env, thisVar, objectInfo, + [](napi_env env, void* data, void* hint) { + auto objInfo = (Base64*)data; + if (objInfo != nullptr) { + delete objInfo; + } + }, + nullptr, nullptr); + return thisVar; + } + + static napi_value EncodeBase64(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 2; + 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 >= requireArgc, "Wrong number of arguments"); + napi_typedarray_type valuetype0; + size_t length = 0; + void* data = nullptr; + napi_value arraybuffer = nullptr; + size_t byteOffset = 0; + NAPI_CALL(env, napi_get_typedarray_info(env, args[0], &valuetype0, &length, &data, &arraybuffer, &byteOffset)); + napi_valuetype valuetype1; + NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1)); + NAPI_ASSERT(env, valuetype0 == napi_uint8_array, "Wrong argument type. napi_uint8_array expected."); + NAPI_ASSERT(env, valuetype1 == napi_number, "Wrong argument type. Nmuber expected."); + Base64* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->Encode(args[0], args[1]); + return result; + } + + static napi_value EncodeToString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 2; + 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 >= requireArgc, "Wrong number of arguments"); + napi_typedarray_type valuetype0; + size_t length = 0; + void* data = nullptr; + napi_value arraybuffer = nullptr; + size_t byteOffset = 0; + NAPI_CALL(env, napi_get_typedarray_info(env, args[0], &valuetype0, &length, &data, &arraybuffer, &byteOffset)); + napi_valuetype valuetype1; + NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1)); + NAPI_ASSERT(env, valuetype0 == napi_uint8_array, "Wrong argument type. napi_uint8_array expected."); + NAPI_ASSERT(env, valuetype1 == napi_number, "Wrong argument type. Nmuber expected."); + Base64* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->EncodeToString(args[0], args[1]); + return result; + } + + static napi_value DecodeBase64(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + size_t requireArgc = 2; + 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 >= requireArgc, "Wrong number of arguments"); + napi_typedarray_type valuetype0; + napi_valuetype valuetype1; + size_t length = 0; + void* data = nullptr; + napi_value arraybuffer = nullptr; + size_t byteOffset = 0; + NAPI_CALL(env, napi_typeof(env, args[0], &valuetype1)); + if (valuetype1 != napi_valuetype::napi_string) { + NAPI_CALL(env, napi_get_typedarray_info(env, args[0], &valuetype0, &length, + &data, &arraybuffer, &byteOffset)); + } + if ((valuetype1 != napi_valuetype::napi_string) && (valuetype0 != napi_typedarray_type::napi_uint8_array)) { + napi_throw_error(env, nullptr, "The parameter type is incorrect"); + } + napi_valuetype valuetype2; + NAPI_CALL(env, napi_typeof(env, args[1], &valuetype2)); + NAPI_ASSERT(env, valuetype2 == napi_number, "Wrong argument type. Nmuber expected."); + Base64* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + napi_value result = object->Decode(args[0], args[1]); + return result; + } + + static napi_value Base64Init(napi_env env, napi_value exports) + { + const char* base64ClassName = "Base64"; + napi_value base64Class = nullptr; + static napi_property_descriptor base64Desc[] = { + DECLARE_NAPI_FUNCTION("encode", EncodeBase64), + DECLARE_NAPI_FUNCTION("encodeToString", EncodeToString), + DECLARE_NAPI_FUNCTION("decode", DecodeBase64), + }; + NAPI_CALL(env, napi_define_class(env, base64ClassName, strlen(base64ClassName), Base64Constructor, + nullptr, sizeof(base64Desc) / sizeof(base64Desc[0]), base64Desc, + &base64Class)); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("Base64", base64Class) + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; + } + static napi_value UtilInit(napi_env env, napi_value exports) { static napi_property_descriptor desc[] = { @@ -494,6 +810,8 @@ namespace OHOS::Util { }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); TextcoderInit(env, exports); + RationalNumberInit(env, exports); + Base64Init(env, exports); return exports; } @@ -526,4 +844,4 @@ namespace OHOS::Util { *buflen = _binary_util_js_js_end - _binary_util_js_js_start; } } -} +} \ No newline at end of file diff --git a/util/util_js.js b/util/util_js.js index 64498531a13dc0f2e168550baaf24d351850dddf..f3ce3a0a334c7dfb5f341f3af4e50c8592bfd9c6 100644 --- a/util/util_js.js +++ b/util/util_js.js @@ -16,6 +16,8 @@ const helpUtil = requireInternal('util'); let TextEncoder = helpUtil.TextEncoder; let TextDecoder = helpUtil.TextDecoder; +let RationalNumber = helpUtil.RationalNumber; +let Base64 = helpUtil.Base64; function switchLittleObject(enter, obj, count) { @@ -430,4 +432,6 @@ export default { promiseWrapper: promiseWrapper, TextEncoder: TextEncoder, TextDecoder: TextDecoder, + RationalNumber: RationalNumber, + Base64: Base64, }; \ No newline at end of file