From 32ce658b5a7b2da0f93a3d71a23d2147710b5d0d Mon Sep 17 00:00:00 2001 From: xliu Date: Tue, 24 Aug 2021 15:14:23 +0800 Subject: [PATCH] add helpfunction Signed-off-by: xliu Change-Id: If8e741c551ecf3f8a087279da7a493fa1888c3db --- README.en.md | 195 ++++++++-- README.md | 231 +++++++++-- ohos.build | 4 +- textcoder/native_module_util.cpp | 326 ---------------- {textcoder => util}/BUILD.gn | 26 +- {textcoder => util}/js_textdecoder.cpp | 3 +- {textcoder => util}/js_textdecoder.h | 0 {textcoder => util}/js_textencoder.cpp | 0 {textcoder => util}/js_textencoder.h | 0 util/native_module_util.cpp | 508 +++++++++++++++++++++++++ util/util_js.js | 310 +++++++++++++++ 11 files changed, 1194 insertions(+), 409 deletions(-) delete mode 100755 textcoder/native_module_util.cpp rename {textcoder => util}/BUILD.gn (70%) mode change 100755 => 100644 rename {textcoder => util}/js_textdecoder.cpp (97%) mode change 100755 => 100644 rename {textcoder => util}/js_textdecoder.h (100%) mode change 100755 => 100644 rename {textcoder => util}/js_textencoder.cpp (100%) mode change 100755 => 100644 rename {textcoder => util}/js_textencoder.h (100%) mode change 100755 => 100644 create mode 100644 util/native_module_util.cpp create mode 100644 util/util_js.js diff --git a/README.en.md b/README.en.md index 8f6fa37..5e87c70 100644 --- a/README.en.md +++ b/README.en.md @@ -1,36 +1,159 @@ -# js_util_module - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +# 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 index 02b89ca..13750b3 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,192 @@ -# js_util_module - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +# 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/ohos.build b/ohos.build index 9683641..b85022b 100755 --- a/ohos.build +++ b/ohos.build @@ -7,7 +7,9 @@ "phone" ], "module_list": [ - "//base/compileruntime/js_util_module/textcoder:util" + "//base/compileruntime/js_util_module/util:util_packages" + ], + "inner_kits": [ ], "test_list": [ ] diff --git a/textcoder/native_module_util.cpp b/textcoder/native_module_util.cpp deleted file mode 100755 index 972592e..0000000 --- a/textcoder/native_module_util.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "js_textdecoder.h" -#include "js_textencoder.h" - -#include "napi/native_api.h" -#include "napi/native_node_api.h" -#include "utils/log.h" - -static const int NUM_OF_DATA = 2; -// Decoder -static void SetVec(const napi_status fatSta, const napi_status bomSta, const bool fat, const bool bom, - std::vector ¶Vec) -{ - if (paraVec.size() != 2) { - return; - } - if (fatSta == napi_ok) { - if (fat) { - paraVec[0] = 1; - } else { - paraVec[0] = 0; - } - } - if (bomSta == napi_ok) { - if (bom) { - paraVec[1] = 1; - } else { - paraVec[1] = 0; - } - } -} - -static napi_value TextdecoderConstructor(napi_env env, napi_callback_info info) -{ - size_t tempArgc = 0; - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, &tempArgc, nullptr, &thisVar, nullptr); - size_t argc = 0; - void* data = nullptr; - char* type = nullptr; - size_t typeLen = 0; - std::vector paraVec(2, 0); // 2: Specifies the size of the container to be applied for. - if (tempArgc == 1) { - argc = 1; - napi_value argv = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, &data)); - // first para - NAPI_CALL(env, napi_get_value_string_utf8(env, argv, nullptr, 0, &typeLen)); - if (typeLen > 0) { - type = new char[typeLen + 1](); - } - NAPI_CALL(env, napi_get_value_string_utf8(env, argv, type, typeLen + 1, &typeLen)); - } else if (tempArgc == NUM_OF_DATA) { - argc = NUM_OF_DATA; - napi_value argv[2] = { 0 }; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, &data)); - // first para - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen)); - if (typeLen > 0) { - type = new char[typeLen + 1](); - } - NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen)); - // second para - napi_value messageKeyFatal = nullptr; - const char* messageKeyStrFatal = "fatal"; - napi_value messageKeyIgnorebom = nullptr; - const char* messageKeyStrIgnorebom = "ignoreBOM"; - napi_value resultFatal = nullptr; - napi_value resultIgnorebom = nullptr; - bool bResultFat = false; - bool bResultIgnbom = false; - NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrFatal, strlen(messageKeyStrFatal), &messageKeyFatal)); - NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrIgnorebom, strlen(messageKeyStrIgnorebom), - &messageKeyIgnorebom)); - NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyFatal, &resultFatal)); - NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyIgnorebom, &resultIgnorebom)); - napi_status naFat = napi_get_value_bool(env, resultFatal, &bResultFat); - napi_status naBom = napi_get_value_bool(env, resultIgnorebom, &bResultIgnbom); - SetVec(naFat, naBom, bResultFat, bResultIgnbom, paraVec); - } - std::string enconding = "utf-8"; - if (type != nullptr) { - enconding = type; - } - if (type != nullptr) { - delete []type; - type = nullptr; - } - auto objectInfo = new TextDecoder(env, enconding, paraVec); - NAPI_CALL(env, napi_wrap( - env, thisVar, objectInfo, - [](napi_env env, void* data, void* hint) { - auto objectInfo = (TextDecoder*)data; - if (objectInfo != nullptr) { - delete objectInfo; - } - }, - nullptr, nullptr)); - return thisVar; -} - -static napi_value TextdecoderDecode(napi_env env, napi_callback_info info) -{ - size_t tempArgc = 2; - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, &tempArgc, nullptr, &thisVar, nullptr); - size_t argc = 0; - void* dataPara = nullptr; - napi_typedarray_type type; - size_t length = 0; - void* data = nullptr; - napi_value arraybuffer = nullptr; - size_t byteOffset = 0; - bool iStream = true; - TextDecoder* textDecoder = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); - napi_value valStr = nullptr; - if (tempArgc == 1) { - argc = 1; - napi_value argv = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, &dataPara)); - // first para - NAPI_CALL(env, napi_get_typedarray_info(env, argv, &type, &length, &data, &arraybuffer, &byteOffset)); - valStr = textDecoder->Decode(argv, iStream); - } else if (tempArgc == NUM_OF_DATA) { - argc = NUM_OF_DATA; - napi_value argv[2] = { 0 }; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, &dataPara)); - // first para - NAPI_CALL(env, napi_get_typedarray_info(env, argv[0], &type, &length, &data, &arraybuffer, &byteOffset)); - // second para - napi_value messageKeyStream = nullptr; - const char* messageKeyStrStream = "stream"; - - napi_value resultStream = nullptr; - NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrStream, strlen(messageKeyStrStream), - &messageKeyStream)); - NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyStream, &resultStream)); - NAPI_CALL(env, napi_get_value_bool(env, resultStream, &iStream)); - valStr = textDecoder->Decode(argv[0], iStream); - } - return valStr; -} - -static napi_value TextdecoderGetEncoding(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - TextDecoder* textDecoder = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); - napi_value retVal = textDecoder->GetEncoding(); - return retVal; -} - -static napi_value TextdecoderGetFatal(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - TextDecoder* textDecoder = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); - napi_value retVal = textDecoder->GetFatal(); - return retVal; -} - -static napi_value TextdecoderGetIgnoreBOM(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - TextDecoder* textDecoder = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); - napi_value retVal = textDecoder->GetIgnoreBOM(); - return retVal; -} - -// Encoder -static napi_value TextEncoderConstructor(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - void* data = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data)); - - auto object = new TextEncoder(env); - NAPI_CALL(env, napi_wrap( - env, thisVar, object, - [](napi_env env, void* data, void* hint) { - auto object = (TextEncoder*)data; - if (object != nullptr) { - delete object; - } - }, - nullptr, nullptr)); - - return thisVar; -} - -static napi_value GetEncoding(napi_env env, napi_callback_info info) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); - - TextEncoder* object = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); - - return object->GetEncoding(); -} - -static napi_value Encode(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 number of arguments"); - - napi_valuetype valuetype; - NAPI_CALL(env, napi_typeof(env, args, &valuetype)); - - NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected."); - - TextEncoder* object = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); - - napi_value result = object->Encode(args); - - return result; -} - -static napi_value EncodeInto(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_valuetype valuetype0; - NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0)); - - napi_typedarray_type valuetype1; - size_t length = 0; - void* data = nullptr; - napi_value arraybuffer = nullptr; - size_t byteOffset = 0; - NAPI_CALL(env, napi_get_typedarray_info(env, args[1], &valuetype1, &length, &data, &arraybuffer, &byteOffset)); - - NAPI_ASSERT(env, valuetype0 == napi_string, "Wrong argument type. String expected."); - NAPI_ASSERT(env, valuetype1 == napi_uint8_array, "Wrong argument type. napi_uint8_array expected."); - - TextEncoder* object = nullptr; - NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); - - napi_value result = object->EncodeInto(args[0], args[1]); - - return result; -} - -static napi_value TextcoderInit(napi_env env, napi_value exports) -{ - const char* textEncoderClassName = "TextEncoder"; - napi_value textEncoderClass = nullptr; - static napi_property_descriptor textEncoderDesc[] = { - DECLARE_NAPI_GETTER("encoding", GetEncoding), - DECLARE_NAPI_FUNCTION("encode", Encode), - DECLARE_NAPI_FUNCTION("encodeInto", EncodeInto), - }; - NAPI_CALL(env, napi_define_class(env, textEncoderClassName, strlen(textEncoderClassName), TextEncoderConstructor, - nullptr, sizeof(textEncoderDesc) / sizeof(textEncoderDesc[0]), textEncoderDesc, - &textEncoderClass)); - - const char* textDecoderClassName = "TextDecoder"; - napi_value textDecoderClass = nullptr; - static napi_property_descriptor textdecoderDesc[] = { - DECLARE_NAPI_FUNCTION("decode", TextdecoderDecode), - DECLARE_NAPI_GETTER("encoding", TextdecoderGetEncoding), - DECLARE_NAPI_GETTER("fatal", TextdecoderGetFatal), - DECLARE_NAPI_GETTER("ignoreBOM", TextdecoderGetIgnoreBOM), - }; - NAPI_CALL(env, napi_define_class(env, textDecoderClassName, strlen(textDecoderClassName), TextdecoderConstructor, - nullptr, sizeof(textdecoderDesc) / sizeof(textdecoderDesc[0]), textdecoderDesc, - &textDecoderClass)); - - static napi_property_descriptor desc[] = { - DECLARE_NAPI_PROPERTY("TextEncoder", textEncoderClass), - DECLARE_NAPI_PROPERTY("TextDecoder", textDecoderClass), - }; - - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); - return exports; -} - -// util modules -static napi_module utilModule = { - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = TextcoderInit, - .nm_modname = "util", - .nm_priv = ((void*)0), - .reserved = { 0 }, -}; - -// util module register -extern "C" __attribute__((constructor)) void utilRegister() -{ - napi_module_register(&utilModule); -} diff --git a/textcoder/BUILD.gn b/util/BUILD.gn old mode 100755 new mode 100644 similarity index 70% rename from textcoder/BUILD.gn rename to util/BUILD.gn index 03e5cbe..1fb01f8 --- a/textcoder/BUILD.gn +++ b/util/BUILD.gn @@ -9,10 +9,19 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. -#import("//ark/runtime/ark_config.gni") import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +base_output_path = get_label_info(":util_js", "target_out_dir") +util_js_obj_path = base_output_path + "/util.o" + +gen_js_obj("util_js") { + input = "//base/compileruntime/js_util_module/util/util_js.js" + output = util_js_obj_path +} + ohos_shared_library("util") { include_dirs = [ "//foundation/ace/napi", @@ -20,7 +29,7 @@ ohos_shared_library("util") { "//third_party/icu/icu4c/source/common", "//third_party/node/src", "//foundation/ace/napi/interfaces/kits", - "//base/compileruntime/js_util_module/textcoder", + "//base/compileruntime/js_util_module/util", ] sources = [ @@ -30,11 +39,14 @@ ohos_shared_library("util") { ] deps = [ - "//foundation/ace/napi:ace_napi", - "//foundation/ace/napi:ace_napi_quickjs", + ":util_js", + "//base/compileruntime/js_util_module/util/:util_js", + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", "//third_party/icu/icu4c:static_icuuc", "//utils/native/base:utils", ] + if (is_standard_system) { external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } else { @@ -42,6 +54,8 @@ ohos_shared_library("util") { } subsystem_name = "ccruntime" part_name = "jsapi_util" +} - relative_install_dir = "module" +group("util_packages") { + deps = [ ":util" ] } diff --git a/textcoder/js_textdecoder.cpp b/util/js_textdecoder.cpp old mode 100755 new mode 100644 similarity index 97% rename from textcoder/js_textdecoder.cpp rename to util/js_textdecoder.cpp index f91210b..25e5625 --- a/textcoder/js_textdecoder.cpp +++ b/util/js_textdecoder.cpp @@ -58,6 +58,7 @@ TextDecoder::TextDecoder(napi_env env, std::string buff, std::vector option 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; @@ -75,7 +76,7 @@ napi_value TextDecoder::Decode(napi_value src, bool iflag) UChar* arr = nullptr; if (limit > 0) { arr = new UChar[limit + 1]; - if (memset_s(arr, len + sizeof(UChar), 0x0, len + sizeof(UChar)) != 0) { + if (memset_s(arr, len + sizeof(UChar), 0, len + sizeof(UChar)) != 0) { HILOG_ERROR("decode arr memset_s failed"); if (arr != nullptr) { delete[] arr; diff --git a/textcoder/js_textdecoder.h b/util/js_textdecoder.h old mode 100755 new mode 100644 similarity index 100% rename from textcoder/js_textdecoder.h rename to util/js_textdecoder.h diff --git a/textcoder/js_textencoder.cpp b/util/js_textencoder.cpp old mode 100755 new mode 100644 similarity index 100% rename from textcoder/js_textencoder.cpp rename to util/js_textencoder.cpp diff --git a/textcoder/js_textencoder.h b/util/js_textencoder.h old mode 100755 new mode 100644 similarity index 100% rename from textcoder/js_textencoder.h rename to util/js_textencoder.h diff --git a/util/native_module_util.cpp b/util/native_module_util.cpp new file mode 100644 index 0000000..1fa6f42 --- /dev/null +++ b/util/native_module_util.cpp @@ -0,0 +1,508 @@ +/* + * 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 "js_textdecoder.h" +#include "js_textencoder.h" + +#include "utils/log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +extern const char _binary_util_js_js_start[]; +extern const char _binary_util_js_js_end[]; +namespace OHOS::Util { + static std::string temp = "cdijoOs"; + static std::string DealWithPrintf(const std::string &format, const std::vector &value) + { + size_t i = 0; + size_t j = 0; + std::string str; + size_t formatSize = format.size(); + size_t valueSize = value.size(); + while (i < formatSize && j < valueSize) { + if (format[i] == '%' && (i + 1 < formatSize && format[i + 1] == '%')) { + str += '%'; + i += 2; // 2:The array goes back two digits. + } else if (format[i] == '%' && (i + 1 < formatSize && (temp.find(format[i + 1])) != std::string::npos)) { + if (format[i + 1] == 'c') { + j++; + } else { + str += value[j++]; + } + i += 2; // 2:The array goes back two digits. + } else if (format[i] == '%' && (i + 1 < formatSize && (temp.find(format[i + 1])) == std::string::npos)) { + str += '%'; + i++; + } + if (i < formatSize && format[i] != '%') { + size_t pos = 0; + if ((pos = format.find('%', i)) == std::string::npos) { + str += format.substr(i); + break; + } else { + str += format.substr(i, pos - i); + i = pos; + } + } + } + if (j < valueSize) { + while (j < valueSize) { + str += " " + value[j++]; + } + } else if (i < formatSize) { + str += format.substr(i); + } + return str; + } + + static napi_value DealWithFormatString(napi_env env, napi_callback_info info) + { + size_t argc = 0; + napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr); + napi_value *argv = new napi_value[argc]; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + char* format = nullptr; + size_t formatsize = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &formatsize)); + format = new char[formatsize + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], format, formatsize + 1, &formatsize)); + std::string str = format; + std::string res; + size_t strSize = str.size(); + for (size_t i = 0; i < strSize; ++i) { + if (str[i] == '%' && (i + 1 < strSize && temp.find(str[i + 1]) != std::string::npos)) { + if (str[i + 1] == 'o') { + res += "o "; + } else if (str[i + 1] == 'O') { + res += "O "; + } else if (str[i + 1] == 'i') { + res += "i "; + } else if (str[i + 1] == 'j') { + res += "j "; + } else if (str[i + 1] == 'd') { + res += "d "; + } else if (str[i + 1] == 's') { + res += "s "; + } else if (str[i + 1] == 'c') { + res += "c "; + } + i++; + } else if(str[i] == '%' && (i + 1 < strSize && str[i + 1] == '%')) { + i++; + } + } + res = res.substr(0, res.size() - 1); + napi_value result = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, res.c_str(), res.size(), &result)); + delete []format; + delete []argv; + argv = nullptr; + format = nullptr; + return result; + } + + static std::string PrintfString(const std::string &format, const std::vector &value) + { + std::string printInfo; + printInfo = DealWithPrintf(format, value); + return printInfo; + } + + static napi_value Printf(napi_env env, napi_callback_info info) + { + napi_value result = nullptr; + size_t argc = 0; + napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr); + napi_value *argv = new napi_value[argc]; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + char* format = nullptr; + size_t formatsize = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &formatsize)); + format = new char[formatsize + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], format, formatsize + 1, &formatsize)); + std::string printInfo; + std::vector value; + for (size_t i = 1; i < argc; i++) { + char* valueString = nullptr; + size_t valuesize = 0; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[i], nullptr, 0, &valuesize)); + valueString = new char[valuesize + 1]; + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[i], valueString, valuesize + 1, &valuesize)); + value.push_back(valueString); + delete []valueString; + valueString = nullptr; + } + printInfo = PrintfString(format, value); + napi_create_string_utf8(env, printInfo.c_str(), printInfo.size(), &result); + delete []format; + delete []argv; + argv = nullptr; + format = nullptr; + return result; + } + + static napi_value GetErrorString(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + napi_value result = nullptr; + std::string errInfo; + size_t argc = 1; + napi_value argv = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, nullptr)); + uint32_t err = 0; + NAPI_CALL(env, napi_get_value_uint32(env, argv, &err)); + errInfo = strerror(err); + NAPI_CALL(env, napi_create_string_utf8(env, errInfo.c_str(), errInfo.size(), &result)); + return result; + } + + static void SetVec(const napi_status fatSta, const napi_status bomSta, const bool fat, const bool bom, + std::vector ¶Vec) + { + if (paraVec.size() != 2) { + return; + } + if (fatSta == napi_ok) { + if (fat) { + paraVec[0] = 1; + } else { + paraVec[0] = 0; + } + } + if (bomSta == napi_ok) { + if (bom) { + paraVec[1] = 1; + } else { + paraVec[1] = 0; + } + } + } + + static napi_value TextdecoderConstructor(napi_env env, napi_callback_info info) + { + size_t tempArgc = 0; + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, &tempArgc, nullptr, &thisVar, nullptr); + size_t argc = 0; + void* data = nullptr; + char* type = nullptr; + size_t typeLen = 0; + std::vector paraVec(2, 0); // 2: Specifies the size of the container to be applied for. + if (tempArgc == 1) { + argc = 1; + napi_value argv = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, &data)); + // first para + NAPI_CALL(env, napi_get_value_string_utf8(env, argv, nullptr, 0, &typeLen)); + if (typeLen > 0) { + type = new char[typeLen + 1](); + } + NAPI_CALL(env, napi_get_value_string_utf8(env, argv, type, typeLen + 1, &typeLen)); + } else if (tempArgc == 2) { // 2: The number of parameters is 2. + argc = 2; // 2: The number of parameters is 2. + napi_value argv[2] = { 0 }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, &data)); + // first para + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen)); + if (typeLen > 0) { + type = new char[typeLen + 1](); + } + NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen)); + // second para + napi_value messageKeyFatal = nullptr; + const char* messageKeyStrFatal = "fatal"; + napi_value messageKeyIgnorebom = nullptr; + const char* messageKeyStrIgnorebom = "ignoreBOM"; + napi_value resultFatal = nullptr; + napi_value resultIgnorebom = nullptr; + bool bResultFat = false; + bool bResultIgnbom = false; + NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrFatal, strlen(messageKeyStrFatal), + &messageKeyFatal)); + NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrIgnorebom, strlen(messageKeyStrIgnorebom), + &messageKeyIgnorebom)); + NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyFatal, &resultFatal)); + NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyIgnorebom, &resultIgnorebom)); + napi_status naFat = napi_get_value_bool(env, resultFatal, &bResultFat); + napi_status naBom = napi_get_value_bool(env, resultIgnorebom, &bResultIgnbom); + SetVec(naFat, naBom, bResultFat, bResultIgnbom, paraVec); + } + std::string enconding = "utf-8"; + if (type != nullptr) { + enconding = type; + } + if (type != nullptr) { + delete []type; + type = nullptr; + } + auto objectInfo = new TextDecoder(env, enconding, paraVec); + NAPI_CALL(env, napi_wrap( + env, thisVar, objectInfo, + [](napi_env env, void* data, void* hint) { + auto objectInfo = (TextDecoder*)data; + if (objectInfo != nullptr) { + delete objectInfo; + } + }, + nullptr, nullptr)); + return thisVar; + } + + static napi_value TextdecoderDecode(napi_env env, napi_callback_info info) + { + size_t tempArgc = 2; + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, &tempArgc, nullptr, &thisVar, nullptr); + size_t argc = 0; + void* dataPara = nullptr; + napi_typedarray_type type; + size_t length = 0; + void* data = nullptr; + napi_value arraybuffer = nullptr; + size_t byteOffset = 0; + bool iStream = true; + TextDecoder* textDecoder = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); + napi_value valStr = nullptr; + if (tempArgc == 1) { + argc = 1; + napi_value argv = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, nullptr, &dataPara)); + // first para + NAPI_CALL(env, napi_get_typedarray_info(env, argv, &type, &length, &data, &arraybuffer, &byteOffset)); + valStr = textDecoder->Decode(argv, iStream); + } else if (tempArgc == 2) { // 2: The number of parameters is 2. + argc = 2; // 2: The number of parameters is 2. + napi_value argv[2] = { 0 }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, &dataPara)); + // first para + NAPI_CALL(env, napi_get_typedarray_info(env, argv[0], &type, &length, &data, &arraybuffer, &byteOffset)); + // second para + napi_value messageKeyStream = nullptr; + const char* messageKeyStrStream = "stream"; + + napi_value resultStream = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, messageKeyStrStream, strlen(messageKeyStrStream), + &messageKeyStream)); + NAPI_CALL(env, napi_get_property(env, argv[1], messageKeyStream, &resultStream)); + NAPI_CALL(env, napi_get_value_bool(env, resultStream, &iStream)); + valStr = textDecoder->Decode(argv[0], iStream); + } + return valStr; + } + + static napi_value TextdecoderGetEncoding(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + TextDecoder* textDecoder = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); + napi_value retVal = textDecoder->GetEncoding(); + return retVal; + } + + static napi_value TextdecoderGetFatal(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + TextDecoder* textDecoder = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); + napi_value retVal = textDecoder->GetFatal(); + return retVal; + } + + static napi_value TextdecoderGetIgnoreBOM(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + TextDecoder* textDecoder = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&textDecoder)); + napi_value retVal = textDecoder->GetIgnoreBOM(); + return retVal; + } + + // Encoder + static napi_value TextEncoderConstructor(napi_env env, napi_callback_info info) + { + HILOG_INFO("SK TextEncoderConstructor start"); + napi_value thisVar = nullptr; + void* data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data)); + + auto object = new TextEncoder(env); + NAPI_CALL(env, napi_wrap( + env, thisVar, object, + [](napi_env env, void* data, void* hint) { + auto object = (TextEncoder*)data; + if (object != nullptr) { + delete object; + } + }, + nullptr, nullptr)); + HILOG_INFO("SK TextEncoderConstructor end"); + return thisVar; + } + + static napi_value GetEncoding(napi_env env, napi_callback_info info) + { + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); + + TextEncoder* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + + return object->GetEncoding(); + } + + static napi_value Encode(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 number of arguments"); + + napi_valuetype valuetype; + NAPI_CALL(env, napi_typeof(env, args, &valuetype)); + + NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected."); + + TextEncoder* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + + napi_value result = object->Encode(args); + + return result; + } + + static napi_value EncodeInto(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_valuetype valuetype0; + NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0)); + + napi_typedarray_type valuetype1; + size_t length = 0; + void* data = nullptr; + napi_value arraybuffer = nullptr; + size_t byteOffset = 0; + NAPI_CALL(env, napi_get_typedarray_info(env, args[1], &valuetype1, &length, &data, &arraybuffer, &byteOffset)); + + NAPI_ASSERT(env, valuetype0 == napi_string, "Wrong argument type. String expected."); + NAPI_ASSERT(env, valuetype1 == napi_uint8_array, "Wrong argument type. napi_uint8_array expected."); + + TextEncoder* object = nullptr; + NAPI_CALL(env, napi_unwrap(env, thisVar, (void**)&object)); + + napi_value result = object->EncodeInto(args[0], args[1]); + + return result; + } + + static napi_value TextcoderInit(napi_env env, napi_value exports) + { + HILOG_INFO("SK TextcoderInit start "); + const char* textEncoderClassName = "TextEncoder"; + napi_value textEncoderClass = nullptr; + static napi_property_descriptor textEncoderDesc[] = { + DECLARE_NAPI_GETTER("encoding", GetEncoding), + DECLARE_NAPI_FUNCTION("encode", Encode), + DECLARE_NAPI_FUNCTION("encodeInto", EncodeInto), + }; + NAPI_CALL(env, napi_define_class(env, textEncoderClassName, strlen(textEncoderClassName), + TextEncoderConstructor, nullptr, + sizeof(textEncoderDesc) / sizeof(textEncoderDesc[0]), + textEncoderDesc, &textEncoderClass)); + + const char* textDecoderClassName = "TextDecoder"; + napi_value textDecoderClass = nullptr; + static napi_property_descriptor textdecoderDesc[] = { + DECLARE_NAPI_FUNCTION("decode", TextdecoderDecode), + DECLARE_NAPI_GETTER("encoding", TextdecoderGetEncoding), + DECLARE_NAPI_GETTER("fatal", TextdecoderGetFatal), + DECLARE_NAPI_GETTER("ignoreBOM", TextdecoderGetIgnoreBOM), + }; + NAPI_CALL(env, napi_define_class(env, textDecoderClassName, strlen(textDecoderClassName), + TextdecoderConstructor, nullptr, + sizeof(textdecoderDesc) / sizeof(textdecoderDesc[0]), + textdecoderDesc, &textDecoderClass)); + + static napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("TextEncoder", textEncoderClass), + DECLARE_NAPI_PROPERTY("TextDecoder", textDecoderClass), + }; + + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + HILOG_INFO("SK TextcoderInit end "); + return exports; + } + + static napi_value UtilInit(napi_env env, napi_value exports) + { + HILOG_INFO("SK UtilInit start "); + static napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("printf", Printf), + DECLARE_NAPI_FUNCTION("geterrorstring", GetErrorString), + DECLARE_NAPI_FUNCTION("dealwithformatstring", DealWithFormatString), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + TextcoderInit(env, exports); + HILOG_INFO("SK UtilInit end "); + return exports; + } + + // util module define + static napi_module utilModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = UtilInit, + .nm_modname = "util", + .nm_priv = ((void*)0), + .reserved = {0}, + }; + + // util module register + extern "C" + __attribute__((constructor)) + void RegisterModule() + { + napi_module_register(&utilModule); + } + + // util JS register + extern "C" + __attribute__((visibility("default"))) void NAPI_util_GetJSCode(const char** buf, int* buflen) + { + if (buf != nullptr) { + *buf = _binary_util_js_js_start; + } + if (buflen != nullptr) { + *buflen = _binary_util_js_js_end - _binary_util_js_js_start; + } + } +} diff --git a/util/util_js.js b/util/util_js.js new file mode 100644 index 0000000..a0ce53e --- /dev/null +++ b/util/util_js.js @@ -0,0 +1,310 @@ +/* + * 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. + */ + +const helpUtil = requireInternal('util'); +let TextEncoder = helpUtil.TextEncoder; +let TextDecoder = helpUtil.TextDecoder; + +function switchLittleObject(str, obj, count) +{ + if (obj instanceof Array) { + str += ' [ ' + arrayToString(obj, count) + '[length]: ' + obj.length + ' ],\n '; + str = str.substr(0, str.length - 4); + } + else if (typeof obj === 'object') { + count++; + str += '{ '; + var i = 0; + for (i in obj) { + str += switchLittleValue(i, obj[i], count); + } + str = str.substr(0, str.length - 4); + str = str + ' }'; + } else if (typeof obj === 'function') { + str += '{ '; + str += '[Function: ' + obj.name + ']\n ' + '[length]: ' + + obj.length + ',\n' + ' [name] :\'' + obj.name + '\',\n' + ' [prototype]: ' + obj.name + + ' { [constructor]: [Circular] },\n '; + str = str.substr(0, str.length - 4); + str = str + ' }'; + } else if (typeof obj === 'string') { + str += '\'' + obj + '\'' + '\n '; + } else if (typeof obj === 'number') { + str += obj.toString(); + } + return str; +} + +function switchLittleValue(protoName, obj, count) { + var str = ''; + if (obj === null) { + str += protoName + ': null,\n '; + } else if (obj instanceof Array) { + str += protoName + ': [ ' + arrayToString(obj, count) + '[length]: ' + obj.length + ' ],\n '; + } else if (typeof obj === 'object') { + str += protoName + ': \n '; + var temp = ''; + str += switchLittleObject(temp, obj, count) + ',\n '; + } else if (typeof obj === 'function') { + str += '{ [Function: ' + obj.name + ']\n ' + '[length]: ' + obj.length + ',\n' + + ' [name] :\'' + obj.name + '\''; + if (count === 1) { + str += ',\n [prototype]: ' + obj.name + '{ [constructor]: [Circular] } },\n '; + } else { + str += ',\n [prototype]: ' + '[' + obj.name + '] },\n '; + } + } else { + if (typeof obj === 'string') { + str += protoName + ': \'' + obj + '\',\n '; + } else if (typeof obj === 'number') { + str += protoName + ': ' + obj + ',\n '; + } + } + return str; +} + +function arrayToString(arr, count) +{ + var str = ''; + if (!arr.length) { + return ''; + } + var i = 0; + for (i in arr) { + if (typeof arr[i] === 'string') { + str += '\'' + arr[i].toString() + '\', '; + } else if (typeof arr[i] === 'object') { + var temp = ''; + str += '\n ' + switchLittleObject(temp, arr[i], count); + str += ',\n '; + } else if (typeof arr[i] === 'function') { + var end = ''; + if (arr[i].name !== '') { + str += '{ [Function: ' + arr[i].name + ']\n '; + end = ' [' + arr[i].name + '] },\n '; + } else { + str += '{ [Function]\n '; + end = '[Object] },\n '; + } + str += '[length]: ' + + arr[i].length + ',\n' + ' [name] :\'' + arr[i].name + + '\',\n' + ',\n [prototype]: ' + end; + } else { + str += arr[i].toString() + ', '; + } + } + return str; +} + +function switchBigObject(obj) +{ + var str = ''; + if (obj instanceof Array) { + str += '[ '; + var i = 0; + for (i in obj) { + if (typeof obj[i] === 'string') { + str += '\'' + obj[i] + '\', '; + } else if (typeof obj[i] === 'number') { + str += obj[i] + ', '; + } + } + str = str.substr(0, str.length - 2); + str += ' ] ,'; + } else if (typeof obj === 'function') { + str += '[Function: ' + obj.name + '],\n'; + } else if (typeof obj === 'string') { + str += '\'' + obj + '\' ,'; + } else if (typeof obj === 'number') { + str += obj.toString() + ' ,'; + } else if (typeof obj === 'object') { + str += '{ '; + var i = 0; + for (i in obj) { + if (typeof obj[i] === 'function') { + str += i + ': [Function: ' + obj[i].name + '] ,'; + } else if (typeof obj[i] === 'string') { + str += i + ': \'' + obj[i] + '\' ,'; + } else if (typeof obj[i] === 'number') { + str += i + ': ' + obj[i].toString() + ' ,'; + } else if (obj[i] instanceof Array) { + str += '[ '; + var i = 0; + var j = 0; + for (i in obj[i]) { + if (typeof obj[i][j] === 'string') { + str += '\'' + obj[i][j] + '\', '; + } else if (typeof obj[i][j] === 'number') { + str += obj[i][j] + ', '; + } + } + str = str.substr(0, str.length - 2); + str += ' ] ,'; + } else if (typeof obj[i] === 'boolean') { + str += obj[i].toString() + ','; + } + } + str = str.substr(0, str.length - 1); + str += '},'; + } else if (typeof obj === 'boolean') { + str += obj.toString() + ','; + } + str = str.substr(0, str.length - 1); + str = str + '\n'; + return str; +} + +function printf(formatString, ...valueString) +{ + var formats = helpUtil.dealwithformatstring(formatString); + var arr = []; + arr = formats.split(' '); + var switchString = []; + var valueLength = valueString.length; + var arrLength = arr.length; + var i = 0; + for (; i < valueLength && i < arrLength; i++) { + let inputType = typeof valueString[i]; + if (arr[i] === 'o') { + var str = ''; + var count = 0; + switchString.push(switchLittleObject(str, valueString[i], count)); + } else if (arr[i] === 'O') { + switchString.push(switchBigObject(valueString[i])); + } else if (arr[i] === 'i') { + if (inputType === 'number') { + switchString.push(parseInt(valueString[i], 10).toString()); // 10:The function uses decimal. + } else if (valueString[i] instanceof Array) { + if (typeof valueString[i][0] === 'number') { + switchString.push(parseInt(valueString[i][0], 10).toString()); // 10:The function uses decimal. + } else if (typeof valueString[i][0] === 'string') { + if (isNaN(valueString[i][0])) { + switchString.push('NaN'); + } else { + switchString.push(parseInt(valueString[i][0], 10).toString()); // 10:The function uses decimal. + } + } + } else if (typeof valueString[i] === 'string') { + if (isNaN(valueString[i])) { + switchString.push('NaN'); + } else { + switchString.push(parseInt(valueString[i], 10).toString()); // 10:The function uses decimal. + } + } else { + switchString.push('NaN'); + } + } else if (arr[i] === 'j') { + switchString.push(JSON.stringify(valueString[i])); + } else if (arr[i] === 'd') { + if (inputType === 'number') { + switchString.push(valueString[i].toString()); + } else if (inputType === 'boolean') { + if (valueString[i] === false) { + switchString.push('0'); + } else { + switchString.push('1'); + } + } else { + switchString.push('NaN'); + } + } else if (arr[i] === 's') { + if (inputType === 'string') { + switchString.push(valueString[i]); + } else if (valueString[i] instanceof Array) { + var k = 0; + var strLength = valueString[i].length; + for (; k < strLength; k++) { + switchString.push(valueString[i][k].toString()); + } + } else if (inputType === 'object') { + switchString.push('[object Object]'); + } else { + switchString.push(valueString[i].toString()); + } + } else if (arr[i] === 'c') { + switchString.push(valueString[i].toString()); + } + } + while (i < valueLength) { + switchString.push(valueString[i].toString()); + i++; + } + var helpUtilString = helpUtil.printf(formatString, ...switchString); + return helpUtilString; +} + +function getErrorString(errnum) +{ + var errorString = helpUtil.geterrorstring(errnum); + return errorString; + +} + +function callbackified(original, ...args) + { + const maybeCb = args.pop(); + if (typeof maybeCb !== 'function') { + throw new Error('maybe is not function'); + } + const cb = (...args) => { + Reflect.apply(maybeCb, this, args); + }; + Reflect.apply(original, this, args).then((ret) => cb(null, ret), (rej) => cb(rej)); + } + +function callbackWrapper(original) +{ + if (typeof original !== 'function') { + throw new Error('original is not function'); + } + const descriptors = Object.getOwnPropertyDescriptors(original); + if (typeof descriptors.length.value === 'number') { + descriptors.length.value++; + } + if (typeof descriptors.name.value === 'string') { + descriptors.name.value += 'callbackified'; + } + + function cb(...args) { + callbackified(original, ...args); + } + + Object.defineProperties(cb, descriptors); + return cb; +} + +function promiseWrapper(func) { + return function (...args) { + return new Promise((resolve, reject) => { + let callback = function (err, ...values) { + if (err) { + reject(err); + } else { + resolve(values); + } + }; + func.apply(null, [...args, callback]); + }); + }; +} + +export default { + printf: printf, + getErrorString: getErrorString, + callbackWrapper: callbackWrapper, + promiseWrapper: promiseWrapper, + TextEncoder: TextEncoder, + TextDecoder: TextDecoder, +}; \ No newline at end of file -- Gitee