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 
31 namespace 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          */
Base64()87         explicit Base64() {}
88 
89         /**
90          * Destructor of Base64.
91          */
~Base64()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