• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "js_base64.h"
17 #include <cstring>
18 #include <sys/types.h>
19 #include "utils/log.h"
20 #include "securec.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 
24 namespace OHOS::Util {
25     namespace {
26         static const size_t TRAGET_TWO = 2;
27         static const size_t TRAGET_THREE = 3;
28         static const size_t TRAGET_FOUR = 4;
29         static const size_t TRAGET_SIX = 6;
30         static const size_t TRAGET_EIGHT = 8;
31         static const size_t TRAGET_SIXTYFIVE = 65;
32         const char BASE[] = {
33             65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
34             83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105,
35             106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
36             121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 61
37         };
38     }
39 
40     /* base64 encode */
EncodeSync(napi_env env,napi_value src)41     napi_value Base64::EncodeSync(napi_env env, napi_value src)
42     {
43         napi_typedarray_type type;
44         size_t byteOffset = 0;
45         size_t length = 0;
46         void *resultData = nullptr;
47         napi_value resultBuffer = nullptr;
48         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
49         inputEncode_ = static_cast<const unsigned char*>(resultData) + byteOffset;
50         unsigned char *rets = EncodeAchieve(inputEncode_, length);
51         if (rets == nullptr) {
52             napi_throw_error(env, "-1", "encode input is null");
53         }
54         void *data = nullptr;
55         napi_value arrayBuffer = nullptr;
56         size_t bufferSize = outputLen;
57         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
58         if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(rets), bufferSize) != EOK) {
59             FreeMemory(rets);
60             HILOG_ERROR("copy ret to arraybuffer error");
61             return nullptr;
62         }
63         napi_value result = nullptr;
64         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
65         FreeMemory(rets);
66         return result;
67     }
68 
69     /* base64 encodeToString */
EncodeToStringSync(napi_env env,napi_value src)70     napi_value Base64::EncodeToStringSync(napi_env env, napi_value src)
71     {
72         napi_typedarray_type type;
73         size_t byteOffset = 0;
74         size_t length = 0;
75         void *resultData = nullptr;
76         napi_value resultBuffer = nullptr;
77         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
78         inputEncode_ = static_cast<const unsigned char*>(resultData) + byteOffset;
79         unsigned char *ret = EncodeAchieve(inputEncode_, length);
80         if (ret == nullptr) {
81             FreeMemory(ret);
82             napi_throw_error(env, "-1", "encodeToString input is null");
83         }
84         const char *encString = reinterpret_cast<const char*>(ret);
85         napi_value resultStr = nullptr;
86         if (strlen(encString) != 0) {
87             NAPI_CALL(env, napi_create_string_utf8(env, encString, strlen(encString), &resultStr));
88         }
89         FreeMemory(ret);
90         return resultStr;
91     }
92 
EncodeAchieve(const unsigned char * input,size_t inputLen)93     unsigned char *Base64::EncodeAchieve(const unsigned char *input, size_t inputLen)
94     {
95         size_t inp = 0;
96         size_t temp = 0;
97         size_t bitWise = 0;
98         unsigned char *ret = nullptr;
99         size_t index = 0;
100         outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR;
101         if ((inputLen % TRAGET_THREE) > 0) {
102             outputLen += TRAGET_FOUR;
103         }
104         if (outputLen > 0) {
105             ret = new unsigned char[outputLen + 1];
106             if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != EOK) {
107                 HILOG_ERROR("encode ret memset_s failed");
108                 FreeMemory(ret);
109                 return nullptr;
110             }
111         } else {
112             HILOG_ERROR("outputLen is error");
113             return nullptr;
114         }
115         if (ret == nullptr) {
116             return ret;
117         }
118         while (inp < inputLen) {
119             temp = 0;
120             bitWise = 0;
121             while (temp < TRAGET_THREE) {
122                 if (inp >= inputLen) {
123                     break;
124                 }
125                 bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG));
126                 inp++;
127                 temp++;
128             }
129             bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT));
130             for (size_t i = 0; i < TRAGET_FOUR; i++) {
131                 if (temp < i) {
132                     ret[index++] = BASE[BIT_FLG];
133                 } else if (temp >= i) {
134                     ret[index++] = BASE[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG];
135                 }
136             }
137         }
138         ret[index] = 0;
139         return ret;
140     }
141 
142     /* base64 decode */
DecodeSync(napi_env env,napi_value src)143     napi_value Base64::DecodeSync(napi_env env, napi_value src)
144     {
145         napi_valuetype valuetype = napi_undefined;
146         napi_typeof(env, src, &valuetype);
147         napi_typedarray_type type;
148         size_t byteOffset = 0;
149         size_t length = 0;
150         void *resultData = nullptr;
151         napi_value resultBuffer = nullptr;
152         char *inputString = nullptr;
153         if (valuetype != napi_valuetype::napi_string) {
154             NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
155         }
156         if (valuetype == napi_valuetype::napi_string) {
157             size_t prolen = 0;
158             napi_get_value_string_utf8(env, src, nullptr, 0, &prolen);
159             if (prolen > 0) {
160                 inputString = new char[prolen + 1];
161                 if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != EOK) {
162                     FreeMemory(inputString);
163                     napi_throw_error(env, "-1", "decode inputString memset_s failed");
164                 }
165             } else {
166                 napi_throw_error(env, "-2", "prolen is error !");
167             }
168             if (inputString != nullptr) {
169                 napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen);
170                 pret = DecodeAchieve(env, inputString, prolen);
171             }
172         } else if (type == napi_typedarray_type::napi_uint8_array) {
173             inputDecode_ = static_cast<const char*>(resultData) + byteOffset;
174             pret = DecodeAchieve(env, inputDecode_, length);
175         }
176         void *data = nullptr;
177         napi_value arrayBuffer = nullptr;
178         size_t bufferSize = decodeOutLen;
179         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
180         if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(pret), bufferSize) != EOK) {
181             FreeMemory(inputString);
182             FreeMemory(pret);
183             HILOG_ERROR("copy retDecode to arraybuffer error");
184             return nullptr;
185         }
186         napi_value result = nullptr;
187         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
188         FreeMemory(inputString);
189         FreeMemory(pret);
190         return result;
191     }
192 
DecodeAchieve(napi_env env,const char * input,size_t inputLen)193     unsigned char *Base64::DecodeAchieve(napi_env env, const char *input, size_t inputLen)
194     {
195         retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE;
196         decodeOutLen = retLen;
197         size_t equalCount = 0;
198         size_t index = 0;
199         size_t inp = 0;
200         size_t temp = 0;
201         size_t bitWise = 0;
202         if (*(input + inputLen - 1) == '=') {
203             equalCount++;
204         }
205         if (*(input + inputLen - TRAGET_TWO) == '=') {
206             equalCount++;
207         }
208         if (*(input + inputLen - TRAGET_THREE) == '=') {
209             equalCount++;
210         }
211         retLen = DecodeOut(equalCount, retLen);
212         if (retLen > 0) {
213             retDecode = new unsigned char[retLen + 1];
214             if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) {
215                 FreeMemory(retDecode);
216                 napi_throw_error(env, "-1", "decode retDecode memset_s failed");
217             }
218         } else {
219             napi_throw_error(env, "-2", "retLen is error !");
220         }
221         if (retDecode == nullptr) {
222             return retDecode;
223         }
224         while (inp < (inputLen - equalCount)) {
225             temp = 0;
226             bitWise = 0;
227             while (temp < TRAGET_FOUR) {
228                 if (inp >= (inputLen - equalCount)) {
229                     break;
230                 }
231                 bitWise = (bitWise << TRAGET_SIX) | (Finds(input[inp]));
232                 inp++;
233                 temp++;
234             }
235             bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX);
236             for (size_t i = 0; i < TRAGET_THREE; i++) {
237                 if (i == temp) {
238                     break;
239                 }
240                 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG);
241             }
242         }
243         retDecode[index] = 0;
244         return retDecode;
245     }
246 
DecodeOut(size_t equalCount,size_t retLen)247     size_t Base64::DecodeOut(size_t equalCount, size_t retLen)
248     {
249         size_t temp = retLen;
250         if (equalCount == 1) {
251             decodeOutLen -= 1;
252         }
253         if (equalCount == TRAGET_TWO) {
254             decodeOutLen -= TRAGET_TWO;
255         }
256         switch (equalCount) {
257             case 0:
258                 temp += TRAGET_FOUR;
259                 break;
260             case 1:
261                 temp += TRAGET_FOUR;
262                 break;
263             case TRAGET_TWO:
264                 temp += TRAGET_THREE;
265                 break;
266             default:
267                 temp += TRAGET_TWO;
268                 break;
269         }
270         return temp;
271     }
272 
273     /* Decoding lookup function */
Finds(char ch)274     size_t Base64::Finds(char ch)
275     {
276         size_t couts = 0;
277         // 65:Number of elements in the encoding table.
278         for (size_t i = 0; i < 65; i++) {
279             if (BASE[i] == ch) {
280                 couts = i;
281             }
282         }
283         return couts;
284     }
285 
Encode(napi_env env,napi_value src)286     napi_value Base64::Encode(napi_env env, napi_value src)
287     {
288         napi_typedarray_type type;
289         size_t byteOffset = 0;
290         size_t length = 0;
291         void *resultData = nullptr;
292         napi_value resultBuffer = nullptr;
293         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
294         unsigned char *inputEncode = nullptr;
295         inputEncode = static_cast<unsigned char*>(resultData) + byteOffset;
296         CreateEncodePromise(env, inputEncode, length);
297         return stdEncodeInfo_->promise;
298     }
EncodeToString(napi_env env,napi_value src)299     napi_value Base64::EncodeToString(napi_env env, napi_value src)
300     {
301         napi_typedarray_type type;
302         size_t byteOffset = 0;
303         size_t length = 0;
304         void *resultData = nullptr;
305         napi_value resultBuffer = nullptr;
306         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
307         unsigned char *inputEncode = nullptr;
308         inputEncode = static_cast<unsigned char*>(resultData) + byteOffset;
309         CreateEncodeToStringPromise(env, inputEncode, length);
310         return stdEncodeInfo_->promise;
311     }
CreateEncodePromise(napi_env env,unsigned char * inputDecode,size_t length)312     void Base64::CreateEncodePromise(napi_env env, unsigned char *inputDecode, size_t length)
313     {
314         napi_value resourceName = nullptr;
315         stdEncodeInfo_ = new EncodeInfo();
316         stdEncodeInfo_->sinputEncode = inputDecode;
317         stdEncodeInfo_->slength = length;
318         stdEncodeInfo_->env = env;
319         napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise);
320         napi_create_string_utf8(env, "ReadStdEncode", NAPI_AUTO_LENGTH, &resourceName);
321         napi_create_async_work(env, nullptr, resourceName, ReadStdEncode, EndStdEncode,
322                                reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker);
323         napi_queue_async_work(env, stdEncodeInfo_->worker);
324     }
CreateEncodeToStringPromise(napi_env env,unsigned char * inputDecode,size_t length)325     void Base64::CreateEncodeToStringPromise(napi_env env, unsigned char *inputDecode, size_t length)
326     {
327         napi_value resourceName = nullptr;
328         stdEncodeInfo_ = new EncodeInfo();
329         stdEncodeInfo_->sinputEncode = inputDecode;
330         stdEncodeInfo_->slength = length;
331         napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise);
332         napi_create_string_utf8(env, "ReadStdEncodeToString", NAPI_AUTO_LENGTH, &resourceName);
333         napi_create_async_work(env, nullptr, resourceName, ReadStdEncodeToString, EndStdEncodeToString,
334                                reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker);
335         napi_queue_async_work(env, stdEncodeInfo_->worker);
336     }
EncodeAchieves(napi_env env,EncodeInfo * encodeInfo)337     unsigned char *EncodeAchieves(napi_env env, EncodeInfo *encodeInfo)
338     {
339         const unsigned char *input = encodeInfo->sinputEncode;
340         size_t inputLen = encodeInfo->slength;
341         size_t inp = 0;
342         size_t temp = 0;
343         size_t bitWise = 0;
344         unsigned char *ret = nullptr;
345         size_t index = 0;
346         size_t outputLen = 0;
347         outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR;
348         if ((inputLen % TRAGET_THREE) > 0) {
349             outputLen += TRAGET_FOUR;
350         }
351         encodeInfo->soutputLen = outputLen;
352         if (outputLen > 0) {
353             ret = new unsigned char[outputLen + 1];
354             if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != EOK) {
355                 FreeMemory(ret);
356                 napi_throw_error(encodeInfo->env, "-1", "ret path memset_s failed");
357             }
358         } else {
359             napi_throw_error(encodeInfo->env, "-2", "outputLen is error !");
360         }
361         if (ret == nullptr) {
362             return ret;
363         }
364         while (inp < inputLen) {
365             temp = 0;
366             bitWise = 0;
367             while (temp < TRAGET_THREE) {
368                 if (inp >= inputLen) {
369                     break;
370                 }
371                 bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG));
372                 inp++;
373                 temp++;
374             }
375             bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT));
376             for (size_t i = 0; i < TRAGET_FOUR; i++) {
377                 if (temp < i) {
378                     ret[index++] = BASE[BIT_FLG];
379                 } else if (temp >= i) {
380                     ret[index++] = BASE[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG];
381                 }
382             }
383         }
384         ret[index] = 0;
385         return ret;
386     }
ReadStdEncode(napi_env env,void * data)387     void Base64::ReadStdEncode(napi_env env, void *data)
388     {
389         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data);
390         unsigned char *rets = EncodeAchieves(env, stdEncodeInfo);
391         stdEncodeInfo->sinputEncoding = rets;
392     }
EndStdEncode(napi_env env,napi_status status,void * buffer)393     void Base64::EndStdEncode(napi_env env, napi_status status, void *buffer)
394     {
395         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer);
396         void *data = nullptr;
397         napi_value arrayBuffer = nullptr;
398         size_t bufferSize = stdEncodeInfo->soutputLen;
399         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
400         if (memcpy_s(data, bufferSize,
401             reinterpret_cast<const void*>(stdEncodeInfo->sinputEncoding), bufferSize) != EOK) {
402             HILOG_ERROR("copy ret to arraybuffer error");
403             napi_delete_async_work(env, stdEncodeInfo->worker);
404             return;
405         }
406         napi_value result = nullptr;
407         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
408         napi_resolve_deferred(env, stdEncodeInfo->deferred, result);
409         napi_delete_async_work(env, stdEncodeInfo->worker);
410         delete[] stdEncodeInfo->sinputEncoding;
411         delete stdEncodeInfo;
412     }
ReadStdEncodeToString(napi_env env,void * data)413     void Base64::ReadStdEncodeToString(napi_env env, void *data)
414     {
415         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data);
416         unsigned char *rets = EncodeAchieves(env, stdEncodeInfo);
417         stdEncodeInfo->sinputEncoding = rets;
418     }
EndStdEncodeToString(napi_env env,napi_status status,void * buffer)419     void Base64::EndStdEncodeToString(napi_env env, napi_status status, void *buffer)
420     {
421         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer);
422         const char *encString = reinterpret_cast<const char*>(stdEncodeInfo->sinputEncoding);
423         napi_value resultStr = nullptr;
424         napi_create_string_utf8(env, encString, strlen(encString), &resultStr);
425         napi_resolve_deferred(env, stdEncodeInfo->deferred, resultStr);
426         napi_delete_async_work(env, stdEncodeInfo->worker);
427         delete[] stdEncodeInfo->sinputEncoding;
428         delete stdEncodeInfo;
429     }
Decode(napi_env env,napi_value src)430     napi_value Base64::Decode(napi_env env, napi_value src)
431     {
432         napi_valuetype valuetype = napi_undefined;
433         napi_typeof(env, src, &valuetype);
434         napi_typedarray_type type;
435         size_t byteOffset = 0;
436         size_t length = 0;
437         void *resultData = nullptr;
438         napi_value resultBuffer = nullptr;
439         char *inputString = nullptr;
440         char *inputDecode = nullptr;
441         if (valuetype != napi_valuetype::napi_string) {
442             NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
443         }
444         if (valuetype == napi_valuetype::napi_string) {
445             size_t prolen = 0;
446             napi_get_value_string_utf8(env, src, nullptr, 0, &prolen);
447             if (prolen > 0) {
448                 inputString = new char[prolen + 1];
449                 if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != EOK) {
450                     napi_throw_error(env, "-1", "decode inputString memset_s failed");
451                 }
452             } else {
453                 napi_throw_error(env, "-2", "prolen is error !");
454             }
455             napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen);
456             CreateDecodePromise(env, inputString, prolen);
457         } else if (type == napi_typedarray_type::napi_uint8_array) {
458             inputDecode = static_cast<char*>(resultData) + byteOffset;
459             CreateDecodePromise(env, inputDecode, length);
460         }
461         delete[] inputString;
462         inputString = nullptr;
463         return stdDecodeInfo_->promise;
464     }
CreateDecodePromise(napi_env env,char * inputDecode,size_t length)465     void Base64::CreateDecodePromise(napi_env env, char *inputDecode, size_t length)
466     {
467         napi_value resourceName = nullptr;
468         stdDecodeInfo_ = new DecodeInfo();
469         stdDecodeInfo_->sinputDecode = inputDecode;
470         stdDecodeInfo_->slength = length;
471         stdDecodeInfo_->env = env;
472         napi_create_promise(env, &stdDecodeInfo_->deferred, &stdDecodeInfo_->promise);
473         napi_create_string_utf8(env, "ReadStdDecode", NAPI_AUTO_LENGTH, &resourceName);
474         napi_create_async_work(env, nullptr, resourceName, ReadStdDecode, EndStdDecode,
475                                reinterpret_cast<void*>(stdDecodeInfo_), &stdDecodeInfo_->worker);
476         napi_queue_async_work(env, stdDecodeInfo_->worker);
477     }
Finds(char ch)478     size_t Finds(char ch)
479     {
480         size_t couts = 0;
481         for (size_t i = 0; i < TRAGET_SIXTYFIVE; i++) {
482             if (BASE[i] == ch) {
483                 couts = i;
484             }
485         }
486         return couts;
487     }
DecodeOut(size_t equalCount,size_t retLen,DecodeInfo * decodeInfo)488     size_t DecodeOut(size_t equalCount, size_t retLen, DecodeInfo *decodeInfo)
489     {
490         if (equalCount == 1) {
491             decodeInfo->decodeOutLen -= 1;
492         }
493         if (equalCount == TRAGET_TWO) {
494             decodeInfo->decodeOutLen -= TRAGET_TWO;
495         }
496         switch (equalCount) {
497             case 0:
498                 retLen += TRAGET_FOUR;
499                 break;
500             case 1:
501                 retLen += TRAGET_FOUR;
502                 break;
503             case TRAGET_TWO:
504                 retLen += TRAGET_THREE;
505                 break;
506             default:
507                 retLen += TRAGET_TWO;
508                 break;
509         }
510         return retLen;
511     }
DecodeAchieves(napi_env env,DecodeInfo * decodeInfo)512     unsigned char *DecodeAchieves(napi_env env, DecodeInfo *decodeInfo)
513     {
514         const char *input = decodeInfo->sinputDecode;
515         size_t inputLen = decodeInfo->slength;
516         size_t retLen = 0;
517         retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE;
518         decodeInfo->decodeOutLen = retLen;
519         size_t equalCount = 0;
520         size_t inp = 0;
521         size_t temp = 0;
522         size_t bitWise = 0;
523         size_t index = 0;
524         unsigned char *retDecode = nullptr;
525         if (*(input + inputLen - 1) == '=') {
526             equalCount++;
527         }
528         if (*(input + inputLen - TRAGET_TWO) == '=') {
529             equalCount++;
530         }
531         retLen = DecodeOut(equalCount, retLen, decodeInfo);
532         if (retLen > 0) {
533             retDecode = new unsigned char[retLen + 1];
534             if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) {
535                 FreeMemory(retDecode);
536                 napi_throw_error(decodeInfo->env, "-1", "decode retDecode memset_s failed");
537             }
538         } else {
539             napi_throw_error(decodeInfo->env, "-2", "retLen is error !");
540         }
541         while (inp < (inputLen - equalCount)) {
542             temp = 0;
543             bitWise = 0;
544             while (temp < TRAGET_FOUR) {
545                 if (inp >= (inputLen - equalCount)) {
546                     break;
547                 }
548                 bitWise = (bitWise << TRAGET_SIX) | (Finds(input[inp]));
549                 inp++;
550                 temp++;
551             }
552             bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX);
553             for (size_t i = 0; i < TRAGET_THREE; i++) {
554                 if (i == temp) {
555                     break;
556                 }
557                 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG);
558             }
559         }
560         retDecode[index] = 0;
561         return retDecode;
562     }
ReadStdDecode(napi_env env,void * data)563     void Base64::ReadStdDecode(napi_env env, void *data)
564     {
565         auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(data);
566         unsigned char *rets = DecodeAchieves(env, stdDecodeInfo);
567         stdDecodeInfo->sinputDecoding = rets;
568     }
EndStdDecode(napi_env env,napi_status status,void * buffer)569     void Base64::EndStdDecode(napi_env env, napi_status status, void *buffer)
570     {
571         auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(buffer);
572         void *data = nullptr;
573         napi_value arrayBuffer = nullptr;
574         size_t bufferSize = stdDecodeInfo->decodeOutLen;
575         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
576         if (memcpy_s(data, bufferSize,
577             reinterpret_cast<const void*>(stdDecodeInfo->sinputDecoding), bufferSize) != EOK) {
578             HILOG_ERROR("copy ret to arraybuffer error");
579             napi_delete_async_work(env, stdDecodeInfo->worker);
580             return;
581         }
582         napi_value result = nullptr;
583         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
584         napi_resolve_deferred(env, stdDecodeInfo->deferred, result);
585         napi_delete_async_work(env, stdDecodeInfo->worker);
586         delete[] stdDecodeInfo->sinputDecoding;
587         delete stdDecodeInfo;
588     }
589 
590     /* Memory cleanup function */
FreeMemory(char * address)591     void FreeMemory(char *address)
592     {
593         if (address != nullptr) {
594             delete[] address;
595             address = nullptr;
596         }
597     }
FreeMemory(unsigned char * address)598     void FreeMemory(unsigned char *address)
599     {
600         if (address != nullptr) {
601             delete[] address;
602             address = nullptr;
603         }
604     }
605 }