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