From 8468db483c38685c94d8a0dfd288c7d2ff0246dd Mon Sep 17 00:00:00 2001 From: lifansheng Date: Fri, 10 Sep 2021 09:40:34 +0800 Subject: [PATCH 1/2] modify codecheck Signed-off-by: lifansheng --- ohos.build | 36 +-- rationalnumber/BUILD.gn | 52 ++++ rationalnumber/js_rational.cpp | 338 ++++++++++++++++++++++ rationalnumber/js_rational.h | 47 +++ rationalnumber/native_module_rational.cpp | 230 +++++++++++++++ 5 files changed, 685 insertions(+), 18 deletions(-) create mode 100755 rationalnumber/BUILD.gn create mode 100755 rationalnumber/js_rational.cpp create mode 100755 rationalnumber/js_rational.h create mode 100755 rationalnumber/native_module_rational.cpp diff --git a/ohos.build b/ohos.build index b85022b..1c6d6ec 100755 --- a/ohos.build +++ b/ohos.build @@ -1,18 +1,18 @@ -{ - "subsystem": "ccruntime", - "parts": { - "jsapi_util": { - "variants": [ - "wearable", - "phone" - ], - "module_list": [ - "//base/compileruntime/js_util_module/util:util_packages" - ], - "inner_kits": [ - ], - "test_list": [ - ] - } - } -} + { + "subsystem": "ccruntime", + "parts": { + "jsapi_rational": { + "variants": [ + "wearable", + "phone" + ], + "module_list": [ + "//base/compileruntime/js_util_module/rationalnumber:rationalnumber_packages" + ], + "inner_kits": [ + ], + "test_list": [ + ] + } + } +} diff --git a/rationalnumber/BUILD.gn b/rationalnumber/BUILD.gn new file mode 100755 index 0000000..3c4afad --- /dev/null +++ b/rationalnumber/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + + +ohos_shared_library("rationalnumber") +{ + include_dirs = [ + "//third_party/icu/icu4c/source/common", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//base/compileruntime/js_util_module/rationalnumber", + ] + + sources = [ + "js_rational.cpp", + "native_module_rational.cpp", + ] + + deps = [ + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/icu/icu4c:static_icuuc", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } + else{ + external_deps = ["hilog:libhilog"] + } + subsystem_name = "ccruntime" + part_name = "jsapi_rational" + + relative_install_dir = "module" +} + +group("rationalnumber_packages") { + deps = [ ":rationalnumber" ] +} diff --git a/rationalnumber/js_rational.cpp b/rationalnumber/js_rational.cpp new file mode 100755 index 0000000..a9c3cf8 --- /dev/null +++ b/rationalnumber/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::Js_api_module::RationalNumber { + 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); + 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; + size_t size = buf.size(); + 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, 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 = ((long)mnum) * other->mden; + long othernum = ((long)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 = ((long)mnum) * object->mden; + long objnum = ((long)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/rationalnumber/js_rational.h b/rationalnumber/js_rational.h new file mode 100755 index 0000000..80d884d --- /dev/null +++ b/rationalnumber/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_API_MODULE_RATIONALNUMBER_CLASS_H +#define BASE_COMPILERUNTIME_JS_API_MODULE_RATIONALNUMBER_CLASS_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS::Js_api_module::RationalNumber { + 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/rationalnumber/native_module_rational.cpp b/rationalnumber/native_module_rational.cpp new file mode 100755 index 0000000..4c4bc1b --- /dev/null +++ b/rationalnumber/native_module_rational.cpp @@ -0,0 +1,230 @@ +/* + * 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" + +namespace OHOS::Js_api_module::RationalNumber { + napi_value RationalNumberClass = nullptr; + 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 objectInfo = (RationalNumber*)data; + if (objectInfo != nullptr) { + delete objectInfo; + } + }, + 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_module RationalNumberModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = RationalNumberInit, + .nm_modname = "RationalNumber", + .nm_priv = ((void*)0), + .reserved = { 0 }, + }; + + extern "C" __attribute__ ((constructor)) void RegisterModule() + { + napi_module_register(&RationalNumberModule); + } +} // namespace \ No newline at end of file -- Gitee From fe7fbc326d5c6de803159133a92bcd335f0cb378 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Sat, 11 Sep 2021 09:25:57 +0800 Subject: [PATCH 2/2] modify readme Signed-off-by: lifansheng --- README.md | 329 ++++++++--------- README_EN.md | 86 ----- js_base64_module/.vscode/settings.json | 33 ++ js_base64_module/base64/BUILD.gn | 52 +++ js_base64_module/base64/js_base64.cpp | 336 ++++++++++++++++++ js_base64_module/base64/js_base64.h | 54 +++ .../base64/native_module_base64.cpp | 150 ++++++++ js_base64_module/ohos.build | 18 + 8 files changed, 794 insertions(+), 264 deletions(-) mode change 100644 => 100755 README.md delete mode 100644 README_EN.md create mode 100755 js_base64_module/.vscode/settings.json create mode 100755 js_base64_module/base64/BUILD.gn create mode 100755 js_base64_module/base64/js_base64.cpp create mode 100755 js_base64_module/base64/js_base64.h create mode 100755 js_base64_module/base64/native_module_base64.cpp create mode 100755 js_base64_module/ohos.build diff --git a/README.md b/README.md old mode 100644 new mode 100755 index ed82bb6..9210368 --- a/README.md +++ b/README.md @@ -1,192 +1,165 @@ -# 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表示已编码字符所占字节的大小。 - -使用方法: - +# 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'); - -var dest = new Uint8Array(6); - +``` +3.encodeInto() +``` +import util from '@ohos.util' +var textEncoder = new util.TextEncoder(); 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。 - -使用方法: - +``` +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(); - -var input = new Uint8Array([96, 97, 98]); - +``` +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}); - -#### 三、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为例: - +``` +9.printf() +``` 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); +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'); +}) +``` +## 相关仓 -2.geterrorstring() - -{ - var errnum = 13; +[js_util_module子系统](https://gitee.com/OHOS_STD/js_util_module) - var result = util.geterrorstring(errnum); -} \ No newline at end of file +[base/compileruntime/js_util_module/](base/compileruntime/js_util_module-readme.md) diff --git a/README_EN.md b/README_EN.md deleted file mode 100644 index 9d214e6..0000000 --- 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/js_base64_module/.vscode/settings.json b/js_base64_module/.vscode/settings.json new file mode 100755 index 0000000..e68d002 --- /dev/null +++ b/js_base64_module/.vscode/settings.json @@ -0,0 +1,33 @@ +{ + "files.associations": { + "compare": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xutility": "cpp", + "bit": "cpp", + "cctype": "cpp", + "concepts": "cpp", + "csignal": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "limits": "cpp", + "map": "cpp", + "new": "cpp", + "string": "cpp", + "vector": "cpp", + "xstddef": "cpp", + "xtree": "cpp" + } +} \ No newline at end of file diff --git a/js_base64_module/base64/BUILD.gn b/js_base64_module/base64/BUILD.gn new file mode 100755 index 0000000..4362ca1 --- /dev/null +++ b/js_base64_module/base64/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + + +ohos_shared_library("base64") +{ + include_dirs = [ + "//third_party/icu/icu4c/source/common", + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//base/compileruntime/js_base64_module/base64", + ] + + sources = [ + "js_base64.cpp", + "native_module_base64.cpp", + ] + + deps = [ + "//foundation/ace/napi/:ace_napi", + "//foundation/ace/napi/:ace_napi_quickjs", + "//third_party/icu/icu4c:static_icuuc", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } + else{ + external_deps = ["hilog:libhilog"] + } + subsystem_name = "ccruntime" + part_name = "jsapi_base64" + + relative_install_dir = "module" +} + +group("base64_packages") { + deps = [ ":base64" ] +} diff --git a/js_base64_module/base64/js_base64.cpp b/js_base64_module/base64/js_base64.cpp new file mode 100755 index 0000000..2b0c127 --- /dev/null +++ b/js_base64_module/base64/js_base64.cpp @@ -0,0 +1,336 @@ +/* + * 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" + + +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; +static const size_t TRAGET_SIXTYFIVE = 65; + +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(); + char* encString = const_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; + size_t i = 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 (i = 0; i < TRAGET_THREE; i++) { + if (i == temp) { + break; + } + *bosom = (char)((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; + case TRAGET_THREE: + 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) { + for (size_t i = 0; i < TRAGET_SIXTYFIVE; i++) { + if (base[i] == ch) { + couts = i; + } + } + } else { + for (size_t i = 0; i < TRAGET_SIXTYFIVE; 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(char* address) +{ + if (address != nullptr) { + delete[] address; + address = nullptr; + } +} diff --git a/js_base64_module/base64/js_base64.h b/js_base64_module/base64/js_base64.h new file mode 100755 index 0000000..3abd3d2 --- /dev/null +++ b/js_base64_module/base64/js_base64.h @@ -0,0 +1,54 @@ +/* + * 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_SYS_MODULE_PROCESS_CLASS_H +#define BASE_COMPILERUNTIME_JS_SYS_MODULE_PROCESS_CLASS_H + + +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(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/js_base64_module/base64/native_module_base64.cpp b/js_base64_module/base64/native_module_base64.cpp new file mode 100755 index 0000000..d852c73 --- /dev/null +++ b/js_base64_module/base64/native_module_base64.cpp @@ -0,0 +1,150 @@ +/* + * 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 "utils/log.h" +#include "securec.h" +#include "js_base64.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +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 objectInfo = (Base64*)data; + if (objectInfo != nullptr) { + delete objectInfo; + } + }, + nullptr, nullptr); + return thisVar; +} + +static napi_value Encode(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 Decode(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", Encode), + DECLARE_NAPI_FUNCTION("encodeToString", EncodeToString), + DECLARE_NAPI_FUNCTION("decode", Decode), + }; + 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_module base64Module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Base64Init, + .nm_modname = "base64", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; +extern "C" __attribute__ ((constructor)) void RegisterModule() +{ + napi_module_register(&base64Module); +} \ No newline at end of file diff --git a/js_base64_module/ohos.build b/js_base64_module/ohos.build new file mode 100755 index 0000000..cf9bc52 --- /dev/null +++ b/js_base64_module/ohos.build @@ -0,0 +1,18 @@ + { + "subsystem": "ccruntime", + "parts": { + "jsapi_base64": { + "variants": [ + "wearable", + "phone" + ], + "module_list": [ + "//base/compileruntime/js_base64_module/base64:base64_packages" + ], + "inner_kits": [ + ], + "test_list": [ + ] + } + } +} -- Gitee