14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 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#ifndef UTIL_JS_TEXTDECODER_H
174d6c458bSopenharmony_ci#define UTIL_JS_TEXTDECODER_H
184d6c458bSopenharmony_ci
194d6c458bSopenharmony_ci#include <memory.h>
204d6c458bSopenharmony_ci#include <string>
214d6c458bSopenharmony_ci#include <vector>
224d6c458bSopenharmony_ci#include "napi/native_api.h"
234d6c458bSopenharmony_ci#include "napi/native_node_api.h"
244d6c458bSopenharmony_ci#include "unicode/ucnv.h"
254d6c458bSopenharmony_ci
264d6c458bSopenharmony_ciusing TransformToolPointer = std::unique_ptr<UConverter, void(*)(UConverter*)>;
274d6c458bSopenharmony_cinamespace OHOS::Util {
284d6c458bSopenharmony_ci    struct DecodeArr {
294d6c458bSopenharmony_ci        DecodeArr(UChar *tarPos, size_t tarStaPos, size_t limLen)
304d6c458bSopenharmony_ci        {
314d6c458bSopenharmony_ci            this->target = tarPos;
324d6c458bSopenharmony_ci            this->tarStartPos = tarStaPos;
334d6c458bSopenharmony_ci            this->limitLen = limLen;
344d6c458bSopenharmony_ci        }
354d6c458bSopenharmony_ci        UChar *target = 0;
364d6c458bSopenharmony_ci        size_t tarStartPos = 0;
374d6c458bSopenharmony_ci        size_t limitLen = 0;
384d6c458bSopenharmony_ci    };
394d6c458bSopenharmony_ci
404d6c458bSopenharmony_ci    class TextDecoder {
414d6c458bSopenharmony_ci    public:
424d6c458bSopenharmony_ci        enum class ConverterFlags {
434d6c458bSopenharmony_ci            FLUSH_FLG = 0x1,
444d6c458bSopenharmony_ci            FATAL_FLG = 0x2,
454d6c458bSopenharmony_ci            IGNORE_BOM_FLG = 0x4,
464d6c458bSopenharmony_ci            UNICODE_FLG = 0x8,
474d6c458bSopenharmony_ci            BOM_SEEN_FLG = 0x10,
484d6c458bSopenharmony_ci        };
494d6c458bSopenharmony_ci
504d6c458bSopenharmony_ci    public:
514d6c458bSopenharmony_ci        /**
524d6c458bSopenharmony_ci         * Constructor of textdecoder
534d6c458bSopenharmony_ci         *
544d6c458bSopenharmony_ci         * @param buff Encoding format.
554d6c458bSopenharmony_ci         * @param optionVec There are two attributes of code related option parameters: fatal and ignorebom.
564d6c458bSopenharmony_ci         */
574d6c458bSopenharmony_ci        TextDecoder(const std::string &buff, int32_t flags);
584d6c458bSopenharmony_ci
594d6c458bSopenharmony_ci        /**
604d6c458bSopenharmony_ci         * Destructor of textencoder.
614d6c458bSopenharmony_ci         */
624d6c458bSopenharmony_ci        virtual ~TextDecoder() {}
634d6c458bSopenharmony_ci
644d6c458bSopenharmony_ci        /**
654d6c458bSopenharmony_ci         * Destructor of textencoder.
664d6c458bSopenharmony_ci         *
674d6c458bSopenharmony_ci         * @param env NAPI environment parameters.
684d6c458bSopenharmony_ci         * @param src An array that matches the format and needs to be decoded.
694d6c458bSopenharmony_ci         * @param iflag Decoding related option parameters.
704d6c458bSopenharmony_ci         */
714d6c458bSopenharmony_ci        napi_value Decode(napi_env env, napi_value src, bool iflag);
724d6c458bSopenharmony_ci
734d6c458bSopenharmony_ci        napi_value DecodeToString(napi_env env, napi_value src, bool iflag);
744d6c458bSopenharmony_ci
754d6c458bSopenharmony_ci        /**
764d6c458bSopenharmony_ci         * Gets the size of minimum byte.
774d6c458bSopenharmony_ci         */
784d6c458bSopenharmony_ci        size_t GetMinByteSize() const;
794d6c458bSopenharmony_ci
804d6c458bSopenharmony_ci        /**
814d6c458bSopenharmony_ci         * Reset function.
824d6c458bSopenharmony_ci         */
834d6c458bSopenharmony_ci        void Reset() const;
844d6c458bSopenharmony_ci
854d6c458bSopenharmony_ci        /**
864d6c458bSopenharmony_ci         * Gets the pointer to the converter.
874d6c458bSopenharmony_ci         */
884d6c458bSopenharmony_ci        UConverter *GetConverterPtr() const
894d6c458bSopenharmony_ci        {
904d6c458bSopenharmony_ci            return tranTool_.get();
914d6c458bSopenharmony_ci        }
924d6c458bSopenharmony_ci
934d6c458bSopenharmony_ci        /**
944d6c458bSopenharmony_ci         * Determine whether it is the flag of BOM.
954d6c458bSopenharmony_ci         */
964d6c458bSopenharmony_ci        bool IsBomFlag() const
974d6c458bSopenharmony_ci        {
984d6c458bSopenharmony_ci            int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
994d6c458bSopenharmony_ci            return temp == static_cast<int32_t>(ConverterFlags::BOM_SEEN_FLG);
1004d6c458bSopenharmony_ci        }
1014d6c458bSopenharmony_ci
1024d6c458bSopenharmony_ci        /**
1034d6c458bSopenharmony_ci         * Determine whether it is Unicode.
1044d6c458bSopenharmony_ci         */
1054d6c458bSopenharmony_ci        bool IsUnicode() const
1064d6c458bSopenharmony_ci        {
1074d6c458bSopenharmony_ci            int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
1084d6c458bSopenharmony_ci            return temp == static_cast<int32_t>(ConverterFlags::UNICODE_FLG);
1094d6c458bSopenharmony_ci        }
1104d6c458bSopenharmony_ci
1114d6c458bSopenharmony_ci        /**
1124d6c458bSopenharmony_ci         * Determine whether it is an ignored BOM.
1134d6c458bSopenharmony_ci         */
1144d6c458bSopenharmony_ci        bool IsIgnoreBom() const
1154d6c458bSopenharmony_ci        {
1164d6c458bSopenharmony_ci            int32_t temp = label_ & static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
1174d6c458bSopenharmony_ci            return temp == static_cast<int32_t>(ConverterFlags::IGNORE_BOM_FLG);
1184d6c458bSopenharmony_ci        }
1194d6c458bSopenharmony_ci
1204d6c458bSopenharmony_ci        /**
1214d6c458bSopenharmony_ci         * Close the pointer of converter.
1224d6c458bSopenharmony_ci         */
1234d6c458bSopenharmony_ci        static void ConverterClose(UConverter *pointer)
1244d6c458bSopenharmony_ci        {
1254d6c458bSopenharmony_ci            ucnv_close(pointer);
1264d6c458bSopenharmony_ci        }
1274d6c458bSopenharmony_ci
1284d6c458bSopenharmony_ci    private:
1294d6c458bSopenharmony_ci        static constexpr uint32_t TEMP_CHAR_LENGTH = 128;
1304d6c458bSopenharmony_ci        static bool IsASCIICharacter(uint16_t data)
1314d6c458bSopenharmony_ci        {
1324d6c458bSopenharmony_ci            return data > 0 && data <= 0x7F;
1334d6c458bSopenharmony_ci        }
1344d6c458bSopenharmony_ci        static bool CanBeCompressed(const uint16_t *utf16Data, uint32_t utf16Len);
1354d6c458bSopenharmony_ci        std::pair<char *, bool> ConvertToChar(UChar* uchar, size_t length, char* tempCharArray);
1364d6c458bSopenharmony_ci        napi_value GetResultStr(napi_env env, UChar *arrDat, size_t length);
1374d6c458bSopenharmony_ci        void SetBomFlag(const UChar *arr, const UErrorCode codeFlag, const DecodeArr decArr,
1384d6c458bSopenharmony_ci                        size_t& rstLen, bool& bomFlag);
1394d6c458bSopenharmony_ci        void SetIgnoreBOM(const UChar *arr, size_t resultLen, bool& bomFlag);
1404d6c458bSopenharmony_ci        void FreedMemory(UChar *&pData);
1414d6c458bSopenharmony_ci        const char* ReplaceNull(void *data, size_t length) const;
1424d6c458bSopenharmony_ci        napi_value ThrowError(napi_env env, const char* errMessage);
1434d6c458bSopenharmony_ci        int32_t label_ {};
1444d6c458bSopenharmony_ci        std::string encStr_ {};
1454d6c458bSopenharmony_ci        TransformToolPointer tranTool_;
1464d6c458bSopenharmony_ci    };
1474d6c458bSopenharmony_ci}
1484d6c458bSopenharmony_ci#endif // UTIL_JS_TEXTDECODER_H
149