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 #ifndef UTIL_JS_TEXTDECODER_H
17 #define UTIL_JS_TEXTDECODER_H
18 
19 #include <memory.h>
20 #include <string>
21 #include <vector>
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24 #include "unicode/ucnv.h"
25 
26 using TransformToolPointer = std::unique_ptr<UConverter, void(*)(UConverter*)>;
27 namespace OHOS::Util {
28     struct DecodeArr {
DecodeArrOHOS::Util::DecodeArr29         DecodeArr(UChar *tarPos, size_t tarStaPos, size_t limLen)
30         {
31             this->target = tarPos;
32             this->tarStartPos = tarStaPos;
33             this->limitLen = limLen;
34         }
35         UChar *target = 0;
36         size_t tarStartPos = 0;
37         size_t limitLen = 0;
38     };
39 
40     class TextDecoder {
41     public:
42         enum class ConverterFlags {
43             FLUSH_FLG = 0x1,
44             FATAL_FLG = 0x2,
45             IGNORE_BOM_FLG = 0x4,
46             UNICODE_FLG = 0x8,
47             BOM_SEEN_FLG = 0x10,
48         };
49 
50     public:
51         /**
52          * Constructor of textdecoder
53          *
54          * @param buff Encoding format.
55          * @param optionVec There are two attributes of code related option parameters: fatal and ignorebom.
56          */
57         TextDecoder(const std::string &buff, int32_t flags);
58 
59         /**
60          * Destructor of textencoder.
61          */
~TextDecoder()62         virtual ~TextDecoder() {}
63 
64         /**
65          * Destructor of textencoder.
66          *
67          * @param env NAPI environment parameters.
68          * @param src An array that matches the format and needs to be decoded.
69          * @param iflag Decoding related option parameters.
70          */
71         napi_value Decode(napi_env env, napi_value src, bool iflag);
72 
73         napi_value DecodeToString(napi_env env, napi_value src, bool iflag);
74 
75         /**
76          * Gets the size of minimum byte.
77          */
78         size_t GetMinByteSize() const;
79 
80         /**
81          * Reset function.
82          */
83         void Reset() const;
84 
85         /**
86          * Gets the pointer to the converter.
87          */
GetConverterPtr() const88         UConverter *GetConverterPtr() const
89         {
90             return tranTool_.get();
91         }
92 
93         /**
94          * Determine whether it is the flag of BOM.
95          */
IsBomFlag() const96         bool IsBomFlag() const
97         {
98             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
99             return temp == static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
100         }
101 
102         /**
103          * Determine whether it is Unicode.
104          */
IsUnicode() const105         bool IsUnicode() const
106         {
107             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
108             return temp == static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
109         }
110 
111         /**
112          * Determine whether it is an ignored BOM.
113          */
IsIgnoreBom() const114         bool IsIgnoreBom() const
115         {
116             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
117             return temp == static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
118         }
119 
120         /**
121          * Close the pointer of converter.
122          */
ConverterClose(UConverter *pointer)123         static void ConverterClose(UConverter *pointer)
124         {
125             ucnv_close(pointer);
126         }
127 
128     private:
129         static constexpr uint32_t TEMP_CHAR_LENGTH = 128;
IsASCIICharacter(uint16_t data)130         static bool IsASCIICharacter(uint16_t data)
131         {
132             return data > 0 && data <= 0x7F;
133         }
134         static bool CanBeCompressed(const uint16_t *utf16Data, uint32_t utf16Len);
135         std::pair<char *, bool> ConvertToChar(UChar* uchar, size_t length, char* tempCharArray);
136         napi_value GetResultStr(napi_env env, UChar *arrDat, size_t length);
137         void SetBomFlag(const UChar *arr, const UErrorCode codeFlag, const DecodeArr decArr,
138                         size_t& rstLen, bool& bomFlag);
139         void SetIgnoreBOM(const UChar *arr, size_t resultLen, bool& bomFlag);
140         void FreedMemory(UChar *&pData);
141         const char* ReplaceNull(void *data, size_t length) const;
142         napi_value ThrowError(napi_env env, const char* errMessage);
143         int32_t label_ {};
144         std::string encStr_ {};
145         TransformToolPointer tranTool_;
146     };
147 }
148 #endif // UTIL_JS_TEXTDECODER_H
149