VirtualBox

Ignore:
Timestamp:
May 13, 2020 4:46:27 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137938
Message:

IPRT/base64: Optimize '\0' handling a little and unify the two versions a little more. Try to address cranky linux build boxes wrt mangling. bugref:9224

Location:
trunk/src/VBox/Runtime/common/string
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/base64-utf16.cpp

    r84293 r84296  
    4949DECL_FORCE_INLINE(uint8_t) rtBase64TranslateUtf16(RTUTF16 wc)
    5050{
    51     if (wc < RT_ELEMENTS(g_au8RTBase64CharToVal))
    52         return g_au8RTBase64CharToVal[wc];
     51    if (wc < RT_ELEMENTS(g_au8rtBase64CharToVal))
     52        return g_au8rtBase64CharToVal[wc];
    5353    if (RTUniCpIsSpace(wc))
    5454        return BASE64_SPACE;
     
    6262    if (cwcStringMax > 0)
    6363        return rtBase64TranslateUtf16(*pwszString);
    64     return BASE64_INVALID;
     64    return BASE64_NULL;
    6565}
    6666
     
    6868/*
    6969 * Mostly the same as RTBase64DecodedSizeEx, except for the wider character
    70  * type and therefore more careful handling of g_szRTBase64ValToChar and additional
     70 * type and therefore more careful handling of g_szrtBase64ValToChar and additional
    7171 * space characters.  Fixes must be applied to both copies of the code.
    7272 */
     
    8181     */
    8282    uint32_t    c6Bits = 0;
    83     uint8_t     u8     = BASE64_INVALID;
    84     RTUTF16     wc     = 0;
    85 
    86     while (cwcStringMax > 0 && (wc = *pwszString))
    87     {
    88         u8 = rtBase64TranslateUtf16(wc);
     83    uint8_t     u8;
     84
     85    while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) != BASE64_NULL)
     86    {
    8987        if (u8 < 64)
    9088            c6Bits++;
     
    108106        pwszString++;
    109107        cwcStringMax--;
    110         while (cwcStringMax > 0 && (wc = *pwszString))
    111         {
    112             u8 = rtBase64TranslateUtf16(wc);
     108        while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) != BASE64_NULL)
     109        {
    113110            if (u8 != BASE64_SPACE)
    114111            {
     
    129126     * Base64 text ends? Return failure.
    130127     */
    131     if (    u8 == BASE64_INVALID
    132         &&  !ppwszEnd
    133         &&  wc)
     128    if (   u8 == BASE64_INVALID
     129        && !ppwszEnd)
    134130        return -1;
    135131
     
    165161    uint8_t     u8;
    166162    unsigned    c6Bits    = 0;
    167     AssertCompile(sizeof(char) == sizeof(uint8_t));
    168163
    169164    for (;;)
     
    241236        pwszString++;
    242237        cwcStringMax--;
    243         RTUTF16 wc;
    244         while (cwcStringMax > 0 && (wc = *pwszString))
    245         {
    246             u8 = rtBase64TranslateUtf16(wc);
     238        while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) != BASE64_NULL)
     239        {
    247240            if (u8 != BASE64_SPACE)
    248241            {
     
    262255     * Base64 text ends? Return failure.
    263256     */
    264     if (    u8 == BASE64_INVALID
    265         &&  !ppwszEnd
    266         &&  cwcStringMax != 0
    267         &&  *pwszString != '\0')
     257    if (   u8 == BASE64_INVALID
     258        && !ppwszEnd)
    268259        return VERR_INVALID_BASE64_ENCODING;
    269260
     
    361352{
    362353    /* Expand the EOL style flags: */
    363     size_t const    cchEol = g_acchRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
    364     char const      chEol0 = g_aachRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];
    365     char const      chEol1 = g_aachRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];
     354    size_t const    cchEol = g_acchrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
     355    char const      chEol0 = g_aachrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];
     356    char const      chEol1 = g_aachrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];
    366357    Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U));
    367358
     
    382373        /* encode */
    383374        u8A = pbSrc[0];
    384         pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2];
     375        pwcDst[0] = g_szrtBase64ValToChar[u8A >> 2];
    385376        u8B = pbSrc[1];
    386         pwcDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     377        pwcDst[1] = g_szrtBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
    387378        u8C = pbSrc[2];
    388         pwcDst[2] = g_szRTBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];
    389         pwcDst[3] = g_szRTBase64ValToChar[u8C & 0x3f];
     379        pwcDst[2] = g_szrtBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];
     380        pwcDst[3] = g_szrtBase64ValToChar[u8C & 0x3f];
    390381
    391382        /* advance */
     
    419410            case 1:
    420411                u8A = pbSrc[0];
    421                 pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2];
    422                 pwcDst[1] = g_szRTBase64ValToChar[(u8A << 4) & 0x3f];
     412                pwcDst[0] = g_szrtBase64ValToChar[u8A >> 2];
     413                pwcDst[1] = g_szrtBase64ValToChar[(u8A << 4) & 0x3f];
    423414                pwcDst[2] = '=';
    424415                pwcDst[3] = '=';
     
    426417            case 2:
    427418                u8A = pbSrc[0];
    428                 pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2];
     419                pwcDst[0] = g_szrtBase64ValToChar[u8A >> 2];
    429420                u8B = pbSrc[1];
    430                 pwcDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
    431                 pwcDst[2] = g_szRTBase64ValToChar[(u8B << 2) & 0x3f];
     421                pwcDst[1] = g_szrtBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     422                pwcDst[2] = g_szrtBase64ValToChar[(u8B << 2) & 0x3f];
    432423                pwcDst[3] = '=';
    433424                break;
  • trunk/src/VBox/Runtime/common/string/base64.cpp

    r84293 r84296  
    5151/** Base64 character to value. (RFC 2045)
    5252 * ASSUMES ASCII / UTF-8. */
    53 DECL_HIDDEN_CONST(const uint8_t)    g_au8RTBase64CharToVal[256] =
    54 {
    55     0xff, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff,   0xff, 0xc0, 0xc0, 0xc0,   0xc0, 0xc0, 0xff, 0xff, /* 0x00..0x0f */
     53DECL_HIDDEN_CONST(const uint8_t)    g_au8rtBase64CharToVal[256] =
     54{
     55    0xfe, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff,   0xff, 0xc0, 0xc0, 0xc0,   0xc0, 0xc0, 0xff, 0xff, /* 0x00..0x0f */
    5656    0xff, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff, /* 0x10..0x1f */
    5757    0xc0, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff, 0xff,   0xff, 0xff, 0xff,   62,   0xff, 0xff, 0xff,   63, /* 0x20..0x2f */
     
    7272
    7373/** Value to Base64 character. (RFC 2045) */
    74 DECL_HIDDEN_CONST(const char)   g_szRTBase64ValToChar[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     74DECL_HIDDEN_CONST(const char)   g_szrtBase64ValToChar[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    7575
    7676/** The end-of-line lengths (indexed by style flag value). */
    77 DECL_HIDDEN_CONST(const size_t) g_acchRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1] =
     77DECL_HIDDEN_CONST(const size_t) g_acchrtBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1] =
    7878{
    7979    /*[RTBASE64_FLAGS_EOL_NATIVE    ]:*/ RTBASE64_EOL_SIZE,
     
    8484
    8585/** The end-of-line characters (zero, one or two). */
    86 DECL_HIDDEN_CONST(const char)   g_aachRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2] =
     86DECL_HIDDEN_CONST(const char)   g_aachrtBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2] =
    8787{
    8888    /*[RTBASE64_FLAGS_EOL_NATIVE    ]:*/ { RTBASE64_EOL_SIZE == 1 ? '\n' : '\r', RTBASE64_EOL_SIZE == 1 ? '\0' : '\n', },
     
    105105        for (unsigned i = 0; i < 64; i++)
    106106        {
    107             unsigned ch = g_szRTBase64ValToChar[i];
     107            unsigned ch = g_szrtBase64ValToChar[i];
    108108            Assert(ch);
    109             Assert(g_au8RTBase64CharToVal[ch] == i);
     109            Assert(g_au8rtBase64CharToVal[ch] == i);
    110110        }
    111111
    112112        for (unsigned i = 0; i < 256; i++)
    113113        {
    114             uint8_t u8 = g_au8RTBase64CharToVal[i];
     114            uint8_t u8 = g_au8rtBase64CharToVal[i];
    115115            Assert(   (     u8 == BASE64_INVALID
    116116                       &&   !RT_C_IS_ALNUM(i)
     
    121121                       &&   RT_C_IS_SPACE(i))
    122122                   || (     u8 < 64
    123                        &&   (unsigned)g_szRTBase64ValToChar[u8] == i));
     123                       &&   (unsigned)g_szrtBase64ValToChar[u8] == i)
     124                   || (     u8 == BASE64_NULL
     125                       &&   i  == 0) );
    124126        }
    125127        ASMAtomicWriteBool(&s_fSane, true);
     
    127129}
    128130#endif /* RT_STRICT */
     131
     132
     133
     134/** Fetched the next character in the string and translates it. */
     135DECL_FORCE_INLINE(uint8_t) rtBase64TranslateNext(const char *pszString, size_t cchStringMax)
     136{
     137    AssertCompile(sizeof(unsigned char) == sizeof(uint8_t));
     138    if (cchStringMax > 0)
     139        return g_au8rtBase64CharToVal[(unsigned char)*pszString];
     140    return BASE64_NULL;
     141}
    129142
    130143
     
    143156     */
    144157    uint32_t    c6Bits = 0;
    145     uint8_t     u8     = BASE64_INVALID;
    146     unsigned    ch     = 0;
    147     AssertCompile(sizeof(char) == sizeof(uint8_t));
    148 
    149     while (cchStringMax > 0 && (ch = *pszString))
    150     {
    151         u8 = g_au8RTBase64CharToVal[ch];
     158    uint8_t     u8;
     159
     160    while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) != BASE64_NULL)
     161    {
    152162        if (u8 < 64)
    153163            c6Bits++;
     
    171181        pszString++;
    172182        cchStringMax--;
    173         while (cchStringMax > 0 && (ch = *pszString))
    174         {
    175             u8 = g_au8RTBase64CharToVal[ch];
     183        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) != BASE64_NULL)
     184        {
    176185            if (u8 != BASE64_SPACE)
    177186            {
     
    192201     * Base64 text ends? Return failure.
    193202     */
    194     if (    u8 == BASE64_INVALID
    195         &&  !ppszEnd
    196         &&  ch)
     203    if (   u8 == BASE64_INVALID
     204        && !ppszEnd)
    197205        return -1;
    198206
     
    226234    uint8_t     u8Trio[3] = { 0, 0, 0 }; /* shuts up gcc */
    227235    uint8_t    *pbData    = (uint8_t *)pvData;
    228     unsigned    ch;
    229236    uint8_t     u8;
    230237    unsigned    c6Bits    = 0;
    231     AssertCompile(sizeof(char) == sizeof(uint8_t));
    232238
    233239    for (;;)
    234240    {
    235241        /* The first 6-bit group. */
    236         while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)
     242        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) == BASE64_SPACE)
    237243            pszString++, cchStringMax--;
    238244        if (u8 >= 64)
     
    246252
    247253        /* The second 6-bit group. */
    248         while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)
     254        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) == BASE64_SPACE)
    249255            pszString++, cchStringMax--;
    250256        if (u8 >= 64)
     
    260266        /* The third 6-bit group. */
    261267        u8 = BASE64_INVALID;
    262         while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)
     268        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) == BASE64_SPACE)
    263269            pszString++, cchStringMax--;
    264270        if (u8 >= 64)
     
    274280        /* The fourth 6-bit group. */
    275281        u8 = BASE64_INVALID;
    276         while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)
     282        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) == BASE64_SPACE)
    277283            pszString++, cchStringMax--;
    278284        if (u8 >= 64)
     
    305311        pszString++;
    306312        cchStringMax--;
    307         while (cchStringMax > 0 && (ch = (uint8_t)*pszString))
    308         {
    309             u8 = g_au8RTBase64CharToVal[ch];
     313        while ((u8 = rtBase64TranslateNext(pszString, cchStringMax)) != BASE64_NULL)
     314        {
    310315            if (u8 != BASE64_SPACE)
    311316            {
     
    325330     * Base64 text ends? Return failure.
    326331     */
    327     if (    u8 == BASE64_INVALID
    328         &&  !ppszEnd
    329         &&  ch != '\0')
     332    if (   u8 == BASE64_INVALID
     333        && !ppszEnd)
    330334        return VERR_INVALID_BASE64_ENCODING;
    331335
     
    402406RTDECL(size_t) RTBase64EncodedLengthEx(size_t cbData, uint32_t fFlags)
    403407{
    404     size_t const cchEol = g_acchRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
     408    size_t const cchEol = g_acchrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
    405409
    406410    if (cbData * 8 / 8 != cbData)
     
    441445{
    442446    /* Expand the EOL style flags: */
    443     size_t const    cchEol = g_acchRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
    444     char const      chEol0 = g_aachRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];
    445     char const      chEol1 = g_aachRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];
     447    size_t const    cchEol = g_acchrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];
     448    char const      chEol0 = g_aachrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];
     449    char const      chEol1 = g_aachrtBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];
    446450    Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U));
    447451
     
    462466        /* encode */
    463467        u8A = pbSrc[0];
    464         pchDst[0] = g_szRTBase64ValToChar[u8A >> 2];
     468        pchDst[0] = g_szrtBase64ValToChar[u8A >> 2];
    465469        u8B = pbSrc[1];
    466         pchDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     470        pchDst[1] = g_szrtBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
    467471        u8C = pbSrc[2];
    468         pchDst[2] = g_szRTBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];
    469         pchDst[3] = g_szRTBase64ValToChar[u8C & 0x3f];
     472        pchDst[2] = g_szrtBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];
     473        pchDst[3] = g_szrtBase64ValToChar[u8C & 0x3f];
    470474
    471475        /* advance */
     
    499503            case 1:
    500504                u8A = pbSrc[0];
    501                 pchDst[0] = g_szRTBase64ValToChar[u8A >> 2];
    502                 pchDst[1] = g_szRTBase64ValToChar[(u8A << 4) & 0x3f];
     505                pchDst[0] = g_szrtBase64ValToChar[u8A >> 2];
     506                pchDst[1] = g_szrtBase64ValToChar[(u8A << 4) & 0x3f];
    503507                pchDst[2] = '=';
    504508                pchDst[3] = '=';
     
    506510            case 2:
    507511                u8A = pbSrc[0];
    508                 pchDst[0] = g_szRTBase64ValToChar[u8A >> 2];
     512                pchDst[0] = g_szrtBase64ValToChar[u8A >> 2];
    509513                u8B = pbSrc[1];
    510                 pchDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
    511                 pchDst[2] = g_szRTBase64ValToChar[(u8B << 2) & 0x3f];
     514                pchDst[1] = g_szrtBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     515                pchDst[2] = g_szrtBase64ValToChar[(u8B << 2) & 0x3f];
    512516                pchDst[3] = '=';
    513517                break;
  • trunk/src/VBox/Runtime/common/string/base64.h

    r84294 r84296  
    3232#define RTBASE64_LINE_LEN   64
    3333
    34 /** @name Special g_au8RTBase64CharToVal values
     34/** @name Special g_au8rtBase64CharToVal values
    3535 * @{ */
    3636#define BASE64_SPACE        0xc0
    3737#define BASE64_PAD          0xe0
     38#define BASE64_NULL         0xfe
    3839#define BASE64_INVALID      0xff
    3940/** @} */
     
    4344*   Global Variables                                                                                                             *
    4445*********************************************************************************************************************************/
    45 extern DECLHIDDEN(const uint8_t)    g_au8RTBase64CharToVal[256];
    46 extern DECLHIDDEN(const char)       g_szRTBase64ValToChar[64+1];
    47 extern DECLHIDDEN(const size_t)     g_acchRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1];
    48 extern DECLHIDDEN(const char)       g_aachRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2];
     46extern DECLHIDDEN(const uint8_t)    g_au8rtBase64CharToVal[256];
     47extern DECLHIDDEN(const char)       g_szrtBase64ValToChar[64+1];
     48extern DECLHIDDEN(const size_t)     g_acchrtBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1];
     49extern DECLHIDDEN(const char)       g_aachrtBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2];
    4950
    5051
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette