Changeset 84286 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- May 13, 2020 1:58:21 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/base64.cpp
r84274 r84286 416 416 417 417 418 /**419 * Calculates the length of the Base64 encoding of a given number of bytes of420 * data produced by RTBase64Encode().421 *422 * @returns The Base64 string length.423 * @param cbData The number of bytes to encode.424 */425 418 RTDECL(size_t) RTBase64EncodedLength(size_t cbData) 426 419 { … … 430 423 431 424 432 /**433 * Calculates the length of the Base64 encoding of a given number of bytes of434 * data produced by RTBase64EncodeEx() with the same @a fFlags.435 *436 * @returns The Base64 string length.437 * @param cbData The number of bytes to encode.438 * @param fFlags Flags, any combination of the RTBASE64_FLAGS \#defines.439 */440 425 RTDECL(size_t) RTBase64EncodedLengthEx(size_t cbData, uint32_t fFlags) 441 426 { … … 463 448 464 449 465 /**466 * Encodes the specifed data into a Base64 string, the caller supplies the467 * output buffer.468 *469 * This is equivalent to calling RTBase64EncodeEx() with no flags.470 *471 * @returns IRPT status code.472 * @retval VERR_BUFFER_OVERFLOW if the output buffer is too small. The buffer473 * may contain an invalid Base64 string.474 *475 * @param pvData The data to encode.476 * @param cbData The number of bytes to encode.477 * @param pszBuf Where to put the Base64 string.478 * @param cbBuf The size of the output buffer, including the terminator.479 * @param pcchActual The actual number of characters returned.480 */481 450 RTDECL(int) RTBase64Encode(const void *pvData, size_t cbData, char *pszBuf, size_t cbBuf, size_t *pcchActual) 482 451 { … … 486 455 487 456 488 /** 489 * Encodes the specifed data into a Base64 string, the caller supplies the 490 * output buffer. 491 * 492 * @returns IRPT status code. 493 * @retval VERR_BUFFER_OVERFLOW if the output buffer is too small. The buffer 494 * may contain an invalid Base64 string. 495 * 496 * @param pvData The data to encode. 497 * @param cbData The number of bytes to encode. 498 * @param pszBuf Where to put the Base64 string. 499 * @param cbBuf The size of the output buffer, including the terminator. 500 * @param pcchActual The actual number of characters returned. 457 /* 458 * Please note that RTBase64EncodeUtf16Ex contains an almost exact copy of 459 * this code, just using different output character type and variable prefixes. 460 * So, all fixes must be applied to both versions of the code. 501 461 */ 502 462 RTDECL(int) RTBase64EncodeEx(const void *pvData, size_t cbData, uint32_t fFlags, … … 515 475 uint8_t u8B; 516 476 uint8_t u8C; 517 size_t cbLineFeed = c bBuf - RTBASE64_LINE_LEN;477 size_t cbLineFeed = cchEol ? cbBuf - RTBASE64_LINE_LEN : ~(size_t)0; 518 478 const uint8_t *pbSrc = (const uint8_t *)pvData; 519 479 char *pchDst = pszBuf; … … 538 498 pbSrc += 3; 539 499 540 if (cchEol > 0) 541 { 542 /* deal out end-of-line */ 543 if (cbBuf == cbLineFeed && cbData) 544 { 545 if (cbBuf < cchEol + 1) 546 return VERR_BUFFER_OVERFLOW; 547 cbBuf -= cchEol; 548 *pchDst++ = chEol0; 549 if (chEol1) 550 *pchDst++ = chEol1; 551 cbLineFeed = cbBuf - RTBASE64_LINE_LEN; 552 } 500 /* deal out end-of-line */ 501 if (cbBuf == cbLineFeed && cbData && cchEol) 502 { 503 if (cbBuf < cchEol + 1) 504 return VERR_BUFFER_OVERFLOW; 505 cbBuf -= cchEol; 506 *pchDst++ = chEol0; 507 if (chEol1) 508 *pchDst++ = chEol1; 509 cbLineFeed = cbBuf - RTBASE64_LINE_LEN; 553 510 } 554 511 } … … 589 546 } 590 547 RT_EXPORT_SYMBOL(RTBase64EncodeEx); 548 549 550 /* 551 * Please note that RTBase64EncodeEx contains an almost exact copy of 552 * this code, just using different output character type and variable prefixes. 553 * So, all fixes must be applied to both versions of the code. 554 */ 555 RTDECL(int) RTBase64EncodeUtf16Ex(const void *pvData, size_t cbData, uint32_t fFlags, 556 PRTUTF16 pwszBuf, size_t cwcBuf, size_t *pcwcActual) 557 { 558 /* Expand the EOL style flags: */ 559 size_t const cchEol = g_acchEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK]; 560 char const chEol0 = g_aachEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0]; 561 char const chEol1 = g_aachEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1]; 562 Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U)); 563 564 /* 565 * Process whole "trios" of input data. 566 */ 567 uint8_t u8A; 568 uint8_t u8B; 569 uint8_t u8C; 570 size_t cwcLineFeed = cchEol ? cwcBuf - RTBASE64_LINE_LEN : ~(size_t)0; 571 const uint8_t *pbSrc = (const uint8_t *)pvData; 572 PRTUTF16 pwcDst = pwszBuf; 573 while (cbData >= 3) 574 { 575 if (cwcBuf < 4 + 1) 576 return VERR_BUFFER_OVERFLOW; 577 578 /* encode */ 579 u8A = pbSrc[0]; 580 pwcDst[0] = g_szValToChar[u8A >> 2]; 581 u8B = pbSrc[1]; 582 pwcDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 583 u8C = pbSrc[2]; 584 pwcDst[2] = g_szValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)]; 585 pwcDst[3] = g_szValToChar[u8C & 0x3f]; 586 587 /* advance */ 588 cwcBuf -= 4; 589 pwcDst += 4; 590 cbData -= 3; 591 pbSrc += 3; 592 593 /* deal out end-of-line */ 594 if (cwcBuf == cwcLineFeed && cbData && cchEol) 595 { 596 if (cwcBuf < cchEol + 1) 597 return VERR_BUFFER_OVERFLOW; 598 cwcBuf -= cchEol; 599 *pwcDst++ = chEol0; 600 if (chEol1) 601 *pwcDst++ = chEol1; 602 cwcLineFeed = cwcBuf - RTBASE64_LINE_LEN; 603 } 604 } 605 606 /* 607 * Deal with the odd bytes and string termination. 608 */ 609 if (cbData) 610 { 611 if (cwcBuf < 4 + 1) 612 return VERR_BUFFER_OVERFLOW; 613 switch (cbData) 614 { 615 case 1: 616 u8A = pbSrc[0]; 617 pwcDst[0] = g_szValToChar[u8A >> 2]; 618 pwcDst[1] = g_szValToChar[(u8A << 4) & 0x3f]; 619 pwcDst[2] = '='; 620 pwcDst[3] = '='; 621 break; 622 case 2: 623 u8A = pbSrc[0]; 624 pwcDst[0] = g_szValToChar[u8A >> 2]; 625 u8B = pbSrc[1]; 626 pwcDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 627 pwcDst[2] = g_szValToChar[(u8B << 2) & 0x3f]; 628 pwcDst[3] = '='; 629 break; 630 } 631 pwcDst += 4; 632 } 633 634 *pwcDst = '\0'; 635 636 if (pcwcActual) 637 *pcwcActual = pwcDst - pwszBuf; 638 return VINF_SUCCESS; 639 } 640 RT_EXPORT_SYMBOL(RTBase64EncodeUtf16Ex); 641 642 643 RTDECL(int) RTBase64EncodeUtf16(const void *pvData, size_t cbData, PRTUTF16 pwszBuf, size_t cwcBuf, size_t *pcwcActual) 644 { 645 return RTBase64EncodeUtf16Ex(pvData, cbData, 0, pwszBuf, cwcBuf, pcwcActual); 646 } 647 RT_EXPORT_SYMBOL(RTBase64EncodeUtf16); 648 649 650 RTDECL(size_t) RTBase64EncodedUtf16Length(size_t cbData) 651 { 652 return RTBase64EncodedLengthEx(cbData, 0); 653 } 654 RT_EXPORT_SYMBOL(RTBase64EncodedUtf16Length); 655 656 657 RTDECL(size_t) RTBase64EncodedUtf16LengthEx(size_t cbData, uint32_t fFlags) 658 { 659 return RTBase64EncodedLengthEx(cbData, fFlags); 660 } 661 RT_EXPORT_SYMBOL(RTBase64EncodedUtf16LengthEx); 662
Note:
See TracChangeset
for help on using the changeset viewer.