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