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 {
DecodeArrDecodeArr29         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, std::vector<int> optionVec);
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          * Get encoding format.
77          *
78          * @param env NAPI environment parameters.
79          */
80         napi_value GetEncoding(napi_env env) const;
81 
82         /**
83          * Gets the setting of the exception thrown.
84          *
85          * @param env NAPI environment parameters.
86          */
87         napi_value GetFatal(napi_env env) const;
88 
89         /**
90          * Gets whether to ignore the setting of BOM flag.
91          *
92          * @param env NAPI environment parameters.
93          */
94         napi_value GetIgnoreBOM(napi_env env) const;
95 
96         /**
97          * Gets the size of minimum byte.
98          */
99         size_t GetMinByteSize() const;
100 
101         /**
102          * Reset function.
103          */
104         void Reset() const;
105 
106         /**
107          * Gets the pointer to the converter.
108          */
GetConverterPtr()109         UConverter *GetConverterPtr() const
110         {
111             return tranTool_.get();
112         }
113 
114         /**
115          * Determine whether it is the flag of BOM.
116          */
IsBomFlag()117         bool IsBomFlag() const
118         {
119             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
120             return temp == static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
121         }
122 
123         /**
124          * Determine whether it is Unicode.
125          */
IsUnicode()126         bool IsUnicode() const
127         {
128             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
129             return temp == static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
130         }
131 
132         /**
133          * Determine whether it is an ignored BOM.
134          */
IsIgnoreBom()135         bool IsIgnoreBom() const
136         {
137             int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
138             return temp == static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
139         }
140 
141         /**
142          * Close the pointer of converter.
143          */
ConverterClose(UConverter * pointer)144         static void ConverterClose(UConverter *pointer)
145         {
146             ucnv_close(pointer);
147         }
148 
149     private:
150         void SetBomFlag(const UChar *arr, const UErrorCode codeFlag, const DecodeArr decArr,
151                         size_t& rstLen, bool& bomFlag);
152         void SetIgnoreBOM(const UChar *arr, size_t resultLen, bool& bomFlag);
153         void FreedMemory(UChar *&pData);
154         const char* ReplaceNull(void *data, size_t length) const;
155         napi_value ThrowError(napi_env env, const char* errMessage);
156         int32_t label_ {};
157         std::string encStr_ {};
158         TransformToolPointer tranTool_;
159     };
160 }
161 #endif // UTIL_JS_TEXTDECODER_H
162