VirtualBox

Changeset 16766 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Feb 14, 2009 9:32:04 AM (16 years ago)
Author:
vboxsync
Message:

Wrote RTBase64Encode while at it.

File:
1 edited

Legend:

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

    r16765 r16766  
    4444*   Defined Constants And Macros                                               *
    4545*******************************************************************************/
     46/** The line length used for encoding. */
     47#define RTBASE64_LINE_LEN   64
     48
    4649/** @name Special g_au8CharToVal values
    4750 * @{ */
    48 #define BASE64_SPACE    0xc0
    49 #define BASE64_PAD      0xe0
    50 #define BASE64_INVALID  0xff
     51#define BASE64_SPACE        0xc0
     52#define BASE64_PAD          0xe0
     53#define BASE64_INVALID      0xff
    5154/** @} */
    5255
     
    252255    AssertCompile(sizeof(char) == sizeof(uint8_t));
    253256
    254 const char *pszCurStart;
    255257    for (;;)
    256258    {
    257 pszCurStart = pszString;
    258259        /* The first 6-bit group. */
    259260        while ((u8 = g_au8CharToVal[ch = *pszString]) == BASE64_SPACE)
     
    421422        cch /= 6;
    422423
    423         cch += (cch / 64) * RTBASE64_EOL_SIZE;
     424        cch += (cch / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
    424425        return cch;
    425426    }
     
    430431    cch /= 6;
    431432
    432     cch += (cch / 64) * RTBASE64_EOL_SIZE;
     433    cch += (cch / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
    433434    return cch;
    434435}
     
    455456RTDECL(int) RTBase64Encode(const void *pvData, size_t cbData, char *pszBuf, size_t cbBuf, size_t *pcchActual)
    456457{
    457     /** @todo implement RTBase64Encode. */
    458     return VERR_NOT_IMPLEMENTED;
     458    /*
     459     * Process whole "trios" of input data.
     460     */
     461    uint8_t         u8A;
     462    uint8_t         u8B;
     463    uint8_t         u8C;
     464    size_t          cbLineFeed = cbBuf - RTBASE64_LINE_LEN;
     465    const uint8_t  *pbSrc      = (const uint8_t *)pvData;
     466    char           *pchDst     = pszBuf;
     467    while (cbData >= 3)
     468    {
     469        if (cbBuf < 4 + 1)
     470            return VERR_BUFFER_OVERFLOW;
     471
     472        /* encode */
     473        u8A = pbSrc[0];
     474        pchDst[0] = g_szValToChar[u8A >> 2];
     475        u8B = pbSrc[1];
     476        pchDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     477        u8C = pbSrc[2];
     478        pchDst[2] = g_szValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];
     479        pchDst[3] = g_szValToChar[u8C & 0x3f];
     480
     481        /* advance */
     482        cbBuf  -= 4;
     483        pchDst += 4;
     484        cbData -= 3;
     485        pbSrc  += 3;
     486
     487        if (cbBuf == cbLineFeed)
     488        {
     489            if (cbBuf < RTBASE64_EOL_SIZE + 1)
     490                return VERR_BUFFER_OVERFLOW;
     491            cbBuf -= RTBASE64_EOL_SIZE;
     492            if (RTBASE64_EOL_SIZE == 2)
     493                *pchDst++ = '\r';
     494            *pchDst++ = '\n';
     495            cbLineFeed = cbBuf - RTBASE64_LINE_LEN;
     496        }
     497    }
     498
     499    /*
     500     * Deal with the odd bytes and string termination.
     501     */
     502    if (cbData)
     503    {
     504        if (cbBuf < 4 + 1)
     505            return VERR_BUFFER_OVERFLOW;
     506        switch (cbData)
     507        {
     508            case 1:
     509                u8A = pbSrc[0];
     510                pchDst[0] = g_szValToChar[u8A >> 2];
     511                pchDst[1] = g_szValToChar[(u8A << 4) & 0x3f];
     512                pchDst[2] = '=';
     513                pchDst[3] = '=';
     514                break;
     515            case 2:
     516                u8A = pbSrc[0];
     517                pchDst[0] = g_szValToChar[u8A >> 2];
     518                u8B = pbSrc[1];
     519                pchDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];
     520                pchDst[2] = g_szValToChar[(u8B << 2) & 0x3f];
     521                pchDst[3] = '=';
     522                break;
     523        }
     524        pchDst += 4;
     525    }
     526
     527    *pchDst = '\0';
     528
     529    if (pcchActual)
     530        *pcchActual = pchDst - pszBuf;
     531    return VINF_SUCCESS;
    459532}
    460533
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