• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_textdecoder.h"
17 #include <algorithm>
18 #include <codecvt>
19 
20 #include <locale>
21 #include <map>
22 #include <string>
23 #include <vector>
24 
25 #include "ohos/init_data.h"
26 #include "securec.h"
27 #include "unicode/unistr.h"
28 #include "utils/log.h"
29 #include "util_helper.h"
30 
31 namespace OHOS::Util {
32     using namespace Commonlibrary::Platform;
33 
TextDecoder(const std::string & buff,std::vector<int> optionVec)34     TextDecoder::TextDecoder(const std::string &buff, std::vector<int> optionVec)
35         : label_(0), encStr_(buff), tranTool_(nullptr, nullptr)
36     {
37         uint32_t i32Flag = 0;
38         if (optionVec.size() == 2) { // 2:Meaning of optionVec size 2
39             if (optionVec[0] >= 0 && optionVec[1] >= 0) {
40                 i32Flag |= optionVec[0] ? static_cast<uint32_t>(ConverterFlags::FATAL_FLG) : 0;
41                 i32Flag |= optionVec[1] ? static_cast<uint32_t>(ConverterFlags::IGNORE_BOM_FLG) : 0;
42             } else if (optionVec[0] >= 0 && optionVec[1] < 0) {
43                 i32Flag |= optionVec[0] ? static_cast<uint32_t>(ConverterFlags::FATAL_FLG) : 0;
44             } else if (optionVec[0] < 0 && optionVec[1] >= 0) {
45                 i32Flag |= optionVec[1] ? static_cast<uint32_t>(ConverterFlags::IGNORE_BOM_FLG) : 0;
46             }
47         }
48         label_ = i32Flag;
49 #if !defined(__ARKUI_CROSS__)
50         SetHwIcuDirectory();
51 #endif
52         bool fatal = (i32Flag & static_cast<uint32_t>(ConverterFlags::FATAL_FLG)) ==
53              static_cast<uint32_t>(ConverterFlags::FATAL_FLG);
54         UErrorCode codeflag = U_ZERO_ERROR;
55         UConverter *conv = CreateConverter(encStr_, codeflag);
56 
57         if (U_FAILURE(codeflag)) {
58             HILOG_ERROR("ucnv_open failed !");
59             return;
60         }
61         if (fatal) {
62             codeflag = U_ZERO_ERROR;
63             ucnv_setToUCallBack(conv, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &codeflag);
64         }
65         TransformToolPointer tempTranTool(conv, ConverterClose);
66         tranTool_ = std::move(tempTranTool);
67     }
68 
69 
Decode(napi_env env,napi_value src,bool iflag)70     napi_value TextDecoder::Decode(napi_env env, napi_value src, bool iflag)
71     {
72         uint8_t flags = 0;
73         flags |= (iflag ? 0 : static_cast<uint8_t>(ConverterFlags::FLUSH_FLG));
74         UBool flush = ((flags & static_cast<uint8_t>(ConverterFlags::FLUSH_FLG))) ==
75         static_cast<uint8_t>(ConverterFlags::FLUSH_FLG);
76         napi_typedarray_type type;
77         size_t length = 0;
78         void *data1 = nullptr;
79         size_t byteOffset = 0;
80         napi_value arrayBuffer = nullptr;
81         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &data1, &arrayBuffer, &byteOffset));
82         const char *source = static_cast<char*>(data1);
83         UErrorCode codeFlag = U_ZERO_ERROR;
84         size_t limit = GetMinByteSize() * length;
85         size_t len = limit * sizeof(UChar);
86         UChar *arr = nullptr;
87         if (limit > 0) {
88             arr = new UChar[limit + 1];
89             if (memset_s(arr, len + sizeof(UChar), 0, len + sizeof(UChar)) != EOK) {
90                 HILOG_ERROR("decode arr memset_s failed");
91                 FreedMemory(arr);
92                 return nullptr;
93             }
94         } else {
95             HILOG_ERROR("limit is error");
96             return nullptr;
97         }
98         UChar *target = arr;
99         size_t tarStartPos = reinterpret_cast<uintptr_t>(arr);
100         ucnv_toUnicode(GetConverterPtr(), &target, target + len, &source, source + length, nullptr, flush, &codeFlag);
101         size_t resultLength = 0;
102         bool omitInitialBom = false;
103         DecodeArr decArr(target, tarStartPos, limit);
104         SetBomFlag(arr, codeFlag, decArr, resultLength, omitInitialBom);
105         UChar *arrDat = arr;
106         if (omitInitialBom && resultLength > 0) {
107             arrDat = &arr[2]; // 2: Obtains the 2 value of the array.
108         }
109         std::string tepStr = ConvertToString(arrDat, length);
110         napi_value resultStr = nullptr;
111         NAPI_CALL(env, napi_create_string_utf8(env, tepStr.c_str(), tepStr.size(), &resultStr));
112         FreedMemory(arr);
113         if (flush) {
114             label_ &= static_cast<uint32_t>(ConverterFlags::BOM_SEEN_FLG);
115             Reset();
116         }
117         return resultStr;
118     }
119 
GetEncoding(napi_env env) const120     napi_value TextDecoder::GetEncoding(napi_env env) const
121     {
122         size_t length = strlen(encStr_.c_str());
123         napi_value result = nullptr;
124         NAPI_CALL(env, napi_create_string_utf8(env, encStr_.c_str(), length, &result));
125         return result;
126     }
127 
GetFatal(napi_env env) const128     napi_value TextDecoder::GetFatal(napi_env env) const
129     {
130         uint32_t temp = label_ & static_cast<uint32_t>(ConverterFlags::FATAL_FLG);
131         bool comRst = false;
132         if (temp == static_cast<uint32_t>(ConverterFlags::FATAL_FLG)) {
133             comRst = true;
134         } else {
135             comRst = false;
136         }
137         napi_value result = nullptr;
138         NAPI_CALL(env, napi_get_boolean(env, comRst, &result));
139         return result;
140     }
141 
GetIgnoreBOM(napi_env env) const142     napi_value TextDecoder::GetIgnoreBOM(napi_env env) const
143     {
144         uint32_t temp = label_ & static_cast<uint32_t>(ConverterFlags::IGNORE_BOM_FLG);
145         bool comRst = false;
146         if (temp == static_cast<uint32_t>(ConverterFlags::IGNORE_BOM_FLG)) {
147             comRst = true;
148         } else {
149             comRst = false;
150         }
151         napi_value result;
152         NAPI_CALL(env, napi_get_boolean(env, comRst, &result));
153         return result;
154     }
155 
GetMinByteSize() const156     size_t TextDecoder::GetMinByteSize() const
157     {
158         if (tranTool_ == nullptr) {
159             return 0;
160         }
161         size_t res = static_cast<size_t>(ucnv_getMinCharSize(tranTool_.get()));
162         return res;
163     }
164 
Reset() const165     void TextDecoder::Reset() const
166     {
167         if (tranTool_ == nullptr) {
168             return;
169         }
170         ucnv_reset(tranTool_.get());
171     }
172 
FreedMemory(UChar * pData)173     void TextDecoder::FreedMemory(UChar *pData)
174     {
175         if (pData != nullptr) {
176             delete[] pData;
177             pData = nullptr;
178         }
179     }
180 
SetBomFlag(const UChar * arr,const UErrorCode codeFlag,const DecodeArr decArr,size_t & rstLen,bool & bomFlag)181     void TextDecoder::SetBomFlag(const UChar *arr, const UErrorCode codeFlag, const DecodeArr decArr,
182                                  size_t &rstLen, bool &bomFlag)
183     {
184         if (arr == nullptr) {
185             return;
186         }
187         if (U_SUCCESS(codeFlag)) {
188             if (decArr.limitLen > 0) {
189                 rstLen = reinterpret_cast<uintptr_t>(decArr.target) - decArr.tarStartPos;
190                 if (rstLen > 0 && IsUnicode() && !IsIgnoreBom() && !IsBomFlag()) {
191                     bomFlag = (arr[0] == 0xFEFF) ? true : false;
192                     label_ |= static_cast<uint32_t>(ConverterFlags::BOM_SEEN_FLG);
193                 }
194             }
195         }
196     }
197 }
198