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 <cstring>
17
18#ifdef IOS_PLATFORM
19#include <sys/sysctl.h>
20#else
21#include <sys/sysinfo.h>
22#endif
23
24#include <unistd.h>
25#include "napi/native_api.h"
26#include "napi/native_node_api.h"
27
28#ifndef UTIL_JS_BASE64_H
29#define UTIL_JS_BASE64_H
30
31namespace OHOS::Util {
32
33    enum Type {
34        BASIC,
35        MIME,
36        BASIC_URL_SAFE,
37        MIME_URL_SAFE,
38        TYPED_FIRST = BASIC,
39        TYPED_LAST = MIME_URL_SAFE
40    };
41
42    struct EncodeInfo {
43        napi_async_work worker = nullptr;
44        napi_deferred deferred = nullptr;
45        napi_value promise = nullptr;
46        unsigned char *sinputEncode = nullptr;
47        unsigned char *sinputEncoding = nullptr;
48        size_t slength = 0;
49        size_t soutputLen = 0;
50        napi_env env;
51        Type valueType = BASIC;
52    };
53
54    struct DecodeInfo {
55        napi_async_work worker = nullptr;
56        napi_deferred deferred = nullptr;
57        napi_value promise = nullptr;
58        char *sinputDecode = nullptr;
59        unsigned char *sinputDecoding = nullptr;
60        size_t slength = 0;
61        size_t decodeOutLen = 0;
62        size_t retLen = 0;
63        napi_env env;
64        Type valueType = BASIC;
65    };
66
67    enum ConverterFlags {
68        BIT_FLG = 0x40,
69        SIXTEEN_FLG = 0x3F,
70        XFF_FLG = 0xFF,
71    };
72
73    void FreeMemory(unsigned char *&address);
74    void FreeMemory(char *&address);
75    unsigned char *EncodeAchieves(napi_env env, EncodeInfo *encodeInfo);
76    unsigned char *DecodeAchieves(napi_env env, DecodeInfo *decodeInfo);
77    unsigned char *EncodeAchievesInner(unsigned char *ret, EncodeInfo *encodeInfo,
78                                       const char *searchArray, size_t inputLen, const unsigned char *input);
79    unsigned char *DecodeAchievesInner(size_t inputLen, size_t equalCount,
80                                       const char *input, DecodeInfo *decodeInfo, unsigned char *retDecode);
81
82    class Base64 {
83    public:
84        /**
85         * Constructor of Base64.
86         */
87        explicit Base64() {}
88
89        /**
90         * Destructor of Base64.
91         */
92        virtual ~Base64() {}
93
94        /**
95         * Output the corresponding text after encoding the input parameters.
96         *
97         * @param env NAPI environment parameters.
98         * @param src Encode the input uint8 array.
99         */
100        napi_value EncodeSync(napi_env env, napi_value src, Type valueType);
101
102        /**
103         * Output the corresponding text after encoding the input parameters.
104         *
105         * @param env NAPI environment parameters.
106         * @param src Encode the input uint8 array.
107         */
108        napi_value EncodeToStringSync(napi_env env, napi_value src, Type valueType);
109
110        /**
111         * Output the corresponding text after encoding the input parameters.
112         *
113         * @param env NAPI environment parameters.
114         * @param src Decode the input uint8 array or string.
115         */
116        napi_value DecodeSync(napi_env env, napi_value src, Type valueType);
117
118        /**
119         * Output the corresponding text after asynchronously encoding the input parameters.
120         *
121         * @param env NAPI environment parameters.
122         * @param src Asynchronously encoded input uint8 array.
123         */
124        napi_value Encode(napi_env env, napi_value src, Type valueType);
125
126        /**
127         * Output the corresponding text after asynchronously encoding the input parameters.
128         *
129         * @param env NAPI environment parameters.
130         * @param src Asynchronously encoded input uint8 array.
131         */
132        napi_value EncodeToString(napi_env env, napi_value src, Type valueType);
133
134        /**
135         * Output the corresponding text after asynchronously encoding the input parameters.
136         *
137         * @param env NAPI environment parameters.
138         * @param src Asynchronously decode the input uint8 array or string.
139         */
140        napi_value Decode(napi_env env, napi_value src, Type valueType);
141
142    private:
143        unsigned char *DecodeAchieve(napi_env env, const char *input, size_t inputLen, Type valueType);
144        unsigned char *EncodeAchieve(const unsigned char *input, size_t inputLen, Type valueType);
145        int Finds(napi_env env, char ch, Type valueType);
146        size_t DecodeOut(size_t equalCount, size_t retLen);
147        size_t retLen = 0;
148        size_t decodeOutLen = 0;
149        size_t outputLen = 0;
150        unsigned char *pret = nullptr;
151        const unsigned char *inputEncode_ = nullptr;
152        const char *inputDecode_ = nullptr;
153        unsigned char *retDecode = nullptr;
154        void CreateEncodePromise(napi_env env, unsigned char *inputDecode, size_t length, Type valueType);
155        void CreateEncodeToStringPromise(napi_env env, unsigned char *inputDecode, size_t length, Type valueType);
156        void CreateDecodePromise(napi_env env, char *inputDecode, size_t length, Type valueType);
157        EncodeInfo *stdEncodeInfo_ = nullptr;
158        DecodeInfo *stdDecodeInfo_ = nullptr;
159        static void ReadStdEncode(napi_env env, void *data);
160        static void EndStdEncode(napi_env env, napi_status status, void *buffer);
161        static void ReadStdEncodeToString(napi_env env, void *data);
162        static void EndStdEncodeToString(napi_env env, napi_status status, void *buffer);
163        static void ReadStdDecode(napi_env env, void *data);
164        static void EndStdDecode(napi_env env, napi_status status, void *buffer);
165        unsigned char *EncodeAchieveInner(const unsigned char *input, unsigned char *ret,
166                                          const char *searchArray, size_t inputLen, Type valueType);
167        bool DecodeSyncInner(napi_env env, napi_value src, Type valueType);
168        unsigned char *DecodeAchieveInner(napi_env env, const char *input,
169                                          size_t inputLen, size_t equalCount, Type valueType);
170    };
171}
172#endif // UTIL_JS_BASE64_H
173