14d6c458bSopenharmony_ci/* 24d6c458bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License. 54d6c458bSopenharmony_ci * You may obtain a copy of the License at 64d6c458bSopenharmony_ci * 74d6c458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84d6c458bSopenharmony_ci * 94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and 134d6c458bSopenharmony_ci * limitations under the License. 144d6c458bSopenharmony_ci */ 154d6c458bSopenharmony_ci 164d6c458bSopenharmony_ci#include "js_stringdecoder.h" 174d6c458bSopenharmony_ci#include "util_helper.h" 184d6c458bSopenharmony_ci 194d6c458bSopenharmony_cinamespace OHOS::Util { 204d6c458bSopenharmony_ciusing namespace Commonlibrary::Platform; 214d6c458bSopenharmony_cistatic const char* ERROR_CODE = "401"; 224d6c458bSopenharmony_ci 234d6c458bSopenharmony_ciStringDecoder::StringDecoder(const std::string &encoding) 244d6c458bSopenharmony_ci{ 254d6c458bSopenharmony_ci UErrorCode codeflag = U_ZERO_ERROR; 264d6c458bSopenharmony_ci conv_ = CreateConverter(encoding, codeflag); 274d6c458bSopenharmony_ci} 284d6c458bSopenharmony_ci 294d6c458bSopenharmony_cinapi_value StringDecoder::Write(napi_env env, napi_value src, UBool flush) 304d6c458bSopenharmony_ci{ 314d6c458bSopenharmony_ci napi_typedarray_type type; 324d6c458bSopenharmony_ci size_t length = 0; 334d6c458bSopenharmony_ci void *data = nullptr; 344d6c458bSopenharmony_ci size_t byteOffset = 0; 354d6c458bSopenharmony_ci napi_value arrayBuffer = nullptr; 364d6c458bSopenharmony_ci bool result = false; 374d6c458bSopenharmony_ci napi_is_typedarray(env, src, &result); 384d6c458bSopenharmony_ci if (!result) { 394d6c458bSopenharmony_ci napi_throw_error(env, "401", 404d6c458bSopenharmony_ci "Parameter error. The type of Parameter must be Uint8Array or string."); 414d6c458bSopenharmony_ci return nullptr; 424d6c458bSopenharmony_ci } 434d6c458bSopenharmony_ci napi_get_typedarray_info(env, src, &type, &length, &data, &arrayBuffer, &byteOffset); 444d6c458bSopenharmony_ci const char *source = static_cast<char*>(data); 454d6c458bSopenharmony_ci size_t limit = static_cast<size_t>(ucnv_getMinCharSize(conv_)) * length; 464d6c458bSopenharmony_ci size_t len = limit * sizeof(UChar); 474d6c458bSopenharmony_ci UChar *arr = nullptr; 484d6c458bSopenharmony_ci if (limit > 0) { 494d6c458bSopenharmony_ci arr = new UChar[limit + 1] { 0 }; 504d6c458bSopenharmony_ci } else { 514d6c458bSopenharmony_ci napi_throw_error(env, ERROR_CODE, "Error obtaining minimum number of input bytes"); 524d6c458bSopenharmony_ci return nullptr; 534d6c458bSopenharmony_ci } 544d6c458bSopenharmony_ci UChar *target = arr; 554d6c458bSopenharmony_ci UErrorCode codeFlag = U_ZERO_ERROR; 564d6c458bSopenharmony_ci ucnv_toUnicode(conv_, &target, target + len, &source, source + length, nullptr, flush, &codeFlag); 574d6c458bSopenharmony_ci if (U_FAILURE(codeFlag)) { 584d6c458bSopenharmony_ci FreedMemory(arr); 594d6c458bSopenharmony_ci std::string err = "decoder error, "; 604d6c458bSopenharmony_ci err += u_errorName(codeFlag); 614d6c458bSopenharmony_ci napi_throw_error(env, ERROR_CODE, err.c_str()); 624d6c458bSopenharmony_ci return nullptr; 634d6c458bSopenharmony_ci } 644d6c458bSopenharmony_ci pendingLen_ = ucnv_toUCountPending(conv_, &codeFlag); 654d6c458bSopenharmony_ci pend_ = source + length - pendingLen_; 664d6c458bSopenharmony_ci 674d6c458bSopenharmony_ci napi_value resultStr = nullptr; 684d6c458bSopenharmony_ci size_t resultLen = target - arr; 694d6c458bSopenharmony_ci napi_create_string_utf16(env, reinterpret_cast<char16_t *>(arr), resultLen, &resultStr); 704d6c458bSopenharmony_ci FreedMemory(arr); 714d6c458bSopenharmony_ci return resultStr; 724d6c458bSopenharmony_ci} 734d6c458bSopenharmony_ci 744d6c458bSopenharmony_cinapi_value StringDecoder::End(napi_env env, napi_value src) 754d6c458bSopenharmony_ci{ 764d6c458bSopenharmony_ci return Write(env, src, true); 774d6c458bSopenharmony_ci} 784d6c458bSopenharmony_ci 794d6c458bSopenharmony_cinapi_value StringDecoder::End(napi_env env) 804d6c458bSopenharmony_ci{ 814d6c458bSopenharmony_ci napi_value resultStr = nullptr; 824d6c458bSopenharmony_ci if (pendingLen_ == 0) { 834d6c458bSopenharmony_ci NAPI_CALL(env, napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &resultStr)); 844d6c458bSopenharmony_ci return resultStr; 854d6c458bSopenharmony_ci } 864d6c458bSopenharmony_ci UErrorCode errorCode = U_ZERO_ERROR; 874d6c458bSopenharmony_ci UChar outputBuffer[pendingLen_]; 884d6c458bSopenharmony_ci UChar *targetEnd = outputBuffer + pendingLen_; 894d6c458bSopenharmony_ci UChar *target = outputBuffer; 904d6c458bSopenharmony_ci const char *src = pend_; 914d6c458bSopenharmony_ci const char *sourceEnd = pend_ + pendingLen_; 924d6c458bSopenharmony_ci UBool flush = true; 934d6c458bSopenharmony_ci ucnv_toUnicode(conv_, &target, targetEnd, &src, sourceEnd, nullptr, flush, &errorCode); 944d6c458bSopenharmony_ci if (U_FAILURE(errorCode)) { 954d6c458bSopenharmony_ci std::string err = "decoder error, "; 964d6c458bSopenharmony_ci err += u_errorName(errorCode); 974d6c458bSopenharmony_ci napi_throw_error(env, ERROR_CODE, err.c_str()); 984d6c458bSopenharmony_ci return nullptr; 994d6c458bSopenharmony_ci } 1004d6c458bSopenharmony_ci std::string tepStr = ConvertToString(target, pendingLen_); 1014d6c458bSopenharmony_ci NAPI_CALL(env, napi_create_string_utf8(env, tepStr.c_str(), tepStr.size(), &resultStr)); 1024d6c458bSopenharmony_ci return resultStr; 1034d6c458bSopenharmony_ci} 1044d6c458bSopenharmony_ci 1054d6c458bSopenharmony_civoid StringDecoder::FreedMemory(UChar *&pData) 1064d6c458bSopenharmony_ci{ 1074d6c458bSopenharmony_ci if (pData != nullptr) { 1084d6c458bSopenharmony_ci delete[] pData; 1094d6c458bSopenharmony_ci pData = nullptr; 1104d6c458bSopenharmony_ci } 1114d6c458bSopenharmony_ci} 1124d6c458bSopenharmony_ci} 113