Changeset 84293 in vbox
- Timestamp:
- May 13, 2020 4:23:25 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
- 1 copied
-
include/iprt/base64.h (modified) (4 diffs)
-
include/iprt/mangling.h (modified) (1 diff)
-
src/VBox/Runtime/Makefile.kmk (modified) (1 diff)
-
src/VBox/Runtime/common/string/base64-utf16.cpp (copied) (copied from trunk/src/VBox/Runtime/common/string/base64.cpp ) (23 diffs)
-
src/VBox/Runtime/common/string/base64.cpp (modified) (23 diffs)
-
src/VBox/Runtime/testcase/tstRTBase64.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/base64.h
r84286 r84293 74 74 75 75 /** 76 * Calculates the decoded data size for a Base64 encoded UTF-16 string. 77 * 78 * @returns The length in bytes. -1 if the encoding is bad. 79 * 80 * @param pwszString The Base64 encoded UTF-16 string. 81 * @param ppwszEnd If not NULL, this will point to the first char 82 * following the Base64 encoded text block. If 83 * NULL the entire string is assumed to be Base64. 84 */ 85 RTDECL(ssize_t) RTBase64DecodedUtf16Size(PCRTUTF16 pwszString, PRTUTF16 *ppwszEnd); 86 87 /** 76 88 * Calculates the decoded data size for a Base64 encoded string. 77 89 * … … 87 99 */ 88 100 RTDECL(ssize_t) RTBase64DecodedSizeEx(const char *pszString, size_t cchStringMax, char **ppszEnd); 101 102 /** 103 * Calculates the decoded data size for a Base64 encoded UTF-16 string. 104 * 105 * @returns The length in bytes. -1 if the encoding is bad. 106 * 107 * @param pwszString The Base64 encoded UTF-16 string. 108 * @param cwcStringMax The max length to decode in RTUTF16 units, use 109 * RTSTR_MAX if the length of @a pwszString is not 110 * known and it is really zero terminated. 111 * @param ppwszEnd If not NULL, this will point to the first char 112 * following the Base64 encoded text block. If 113 * NULL the entire string is assumed to be Base64. 114 */ 115 RTDECL(ssize_t) RTBase64DecodedSizeUtf16Ex(PCRTUTF16 pwszString, size_t cwcStringMax, PRTUTF16 *ppwszEnd); 89 116 90 117 /** … … 110 137 */ 111 138 RTDECL(int) RTBase64Decode(const char *pszString, void *pvData, size_t cbData, size_t *pcbActual, char **ppszEnd); 139 140 /** 141 * Decodes a Base64 encoded UTF-16 string into the buffer supplied by the 142 * caller. 143 * 144 * @returns IPRT status code. 145 * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. pcbActual will not 146 * be set, nor will ppszEnd. 147 * @retval VERR_INVALID_BASE64_ENCODING if the encoding is wrong. 148 * 149 * @param pwszString The Base64 UTF-16 string. Whether the entire string 150 * or just the start of the string is in Base64 depends 151 * on whether ppwszEnd is specified or not. 152 * @param pvData Where to store the decoded data. 153 * @param cbData The size of the output buffer that pvData points to. 154 * @param pcbActual Where to store the actual number of bytes returned. 155 * Optional. 156 * @param ppwszEnd Indicates that the string may contain other stuff 157 * after the Base64 encoded data when not NULL. Will 158 * be set to point to the first char that's not part of 159 * the encoding. If NULL the entire string must be part 160 * of the Base64 encoded data. 161 */ 162 RTDECL(int) RTBase64DecodeUtf16(PCRTUTF16 pwszString, void *pvData, size_t cbData, size_t *pcbActual, PRTUTF16 *ppwszEnd); 112 163 113 164 /** … … 138 189 size_t *pcbActual, char **ppszEnd); 139 190 191 /** 192 * Decodes a Base64 encoded UTF-16 string into the buffer supplied by the 193 * caller. 194 * 195 * @returns IPRT status code. 196 * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. pcbActual will not 197 * be set, nor will ppszEnd. 198 * @retval VERR_INVALID_BASE64_ENCODING if the encoding is wrong. 199 * 200 * @param pwszString The Base64 UTF-16 string. Whether the entire string 201 * or just the start of the string is in Base64 depends 202 * on whether ppszEnd is specified or not. 203 * @param cwcStringMax The max length to decode in RTUTF16 units, use 204 * RTSTR_MAX if the length of @a pwszString is not 205 * known and it is really zero terminated. 206 * @param pvData Where to store the decoded data. 207 * @param cbData The size of the output buffer that pvData points to. 208 * @param pcbActual Where to store the actual number of bytes returned. 209 * Optional. 210 * @param ppwszEnd Indicates that the string may contain other stuff 211 * after the Base64 encoded data when not NULL. Will 212 * be set to point to the first char that's not part of 213 * the encoding. If NULL the entire string must be part 214 * of the Base64 encoded data. 215 */ 216 RTDECL(int) RTBase64DecodeUtf16Ex(PCRTUTF16 pwszString, size_t cwcStringMax, void *pvData, size_t cbData, 217 size_t *pcbActual, PRTUTF16 *ppwszEnd); 218 140 219 141 220 /** -
trunk/include/iprt/mangling.h
r84286 r84293 577 577 # define RTBase64DecodedSize RT_MANGLER(RTBase64DecodedSize) 578 578 # define RTBase64DecodedSizeEx RT_MANGLER(RTBase64DecodedSizeEx) 579 # define RTBase64DecodeUtf16 RT_MANGLER(RTBase64DecodeUtf16) 580 # define RTBase64DecodeUtf16Ex RT_MANGLER(RTBase64DecodeUtf16Ex) 581 # define RTBase64DecodedUtf16Size RT_MANGLER(RTBase64DecodedUtf16Size) 582 # define RTBase64DecodedUtf16SizeEx RT_MANGLER(RTBase64DecodedUtf16SizeEx) 579 583 # define RTBase64Encode RT_MANGLER(RTBase64Encode) 580 584 # define RTBase64EncodeEx RT_MANGLER(RTBase64EncodeEx) -
trunk/src/VBox/Runtime/Makefile.kmk
r84230 r84293 609 609 common/string/RTUtf16PrintHexBytes.cpp \ 610 610 common/string/base64.cpp \ 611 common/string/base64-utf16.cpp \ 611 612 common/string/simplepattern.cpp \ 612 613 common/string/straprintf.cpp \ -
trunk/src/VBox/Runtime/common/string/base64-utf16.cpp
r84286 r84293 2 2 /** @file 3 3 * IPRT - Base64, MIME content transfer encoding. 4 * 5 * @note The base64.cpp file must be diffable with this one. 6 * Fixed typically applies to both files. 4 7 */ 5 8 … … 34 37 #include <iprt/assert.h> 35 38 #include <iprt/err.h> 36 #include <iprt/ctype.h>37 39 #include <iprt/string.h> 40 #include <iprt/uni.h> 38 41 #ifdef RT_STRICT 39 42 # include <iprt/asm.h> 40 43 #endif 41 44 42 43 /********************************************************************************************************************************* 44 * Defined Constants And Macros * 45 *********************************************************************************************************************************/ 46 /** The line length used for encoding. */ 47 #define RTBASE64_LINE_LEN 64 48 49 /** @name Special g_au8CharToVal values 50 * @{ */ 51 #define BASE64_SPACE 0xc0 52 #define BASE64_PAD 0xe0 53 #define BASE64_INVALID 0xff 54 /** @} */ 55 56 57 /********************************************************************************************************************************* 58 * Global Variables * 59 *********************************************************************************************************************************/ 60 /** Base64 character to value. (RFC 2045) 61 * ASSUMES ASCII / UTF-8. */ 62 static const uint8_t g_au8CharToVal[256] = 63 { 64 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, /* 0x00..0x0f */ 65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x10..0x1f */ 66 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, /* 0x20..0x2f */ 67 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, /* 0x30..0x3f */ 68 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40..0x4f */ 69 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x50..0x5f */ 70 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60..0x6f */ 71 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70..0x7f */ 72 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x80..0x8f */ 73 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90..0x9f */ 74 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xa0..0xaf */ 75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0..0xbf */ 76 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xc0..0xcf */ 77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0..0xdf */ 78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xe0..0xef */ 79 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* 0xf0..0xff */ 80 }; 81 82 /** Value to Base64 character. (RFC 2045) */ 83 static const char g_szValToChar[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 84 85 /** The end-of-line lengths (indexed by style flag value). */ 86 static const size_t g_acchEolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1] = 87 { 88 /*[RTBASE64_FLAGS_EOL_NATIVE ]:*/ RTBASE64_EOL_SIZE, 89 /*[RTBASE64_FLAGS_NO_LINE_BREAKS]:*/ 0, 90 /*[RTBASE64_FLAGS_EOL_LF ]:*/ 1, 91 /*[RTBASE64_FLAGS_EOL_CRLF ]:*/ 2 92 }; 93 94 /** The end-of-line characters (zero, one or two). */ 95 static const char g_aachEolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2] = 96 { 97 /*[RTBASE64_FLAGS_EOL_NATIVE ]:*/ { RTBASE64_EOL_SIZE == 1 ? '\n' : '\r', RTBASE64_EOL_SIZE == 1 ? '\0' : '\n', }, 98 /*[RTBASE64_FLAGS_NO_LINE_BREAKS]:*/ { '\0', '\0' }, 99 /*[RTBASE64_FLAGS_EOL_LF ]:*/ { '\n', '\0' }, 100 /*[RTBASE64_FLAGS_EOL_CRLF ]:*/ { '\r', '\n' }, 101 }; 102 103 104 105 #ifdef RT_STRICT 106 /** 107 * Perform table sanity checks on the first call. 45 #include "base64.h" 46 47 48 /** Translates the given character. */ 49 DECL_FORCE_INLINE(uint8_t) rtBase64TranslateUtf16(RTUTF16 wc) 50 { 51 if (wc < RT_ELEMENTS(g_au8RTBase64CharToVal)) 52 return g_au8RTBase64CharToVal[wc]; 53 if (RTUniCpIsSpace(wc)) 54 return BASE64_SPACE; 55 return BASE64_INVALID; 56 } 57 58 59 /** Fetched the next character in the string and translates it. */ 60 DECL_FORCE_INLINE(uint8_t) rtBase64TranslateNextUtf16(PCRTUTF16 pwszString, size_t cwcStringMax) 61 { 62 if (cwcStringMax > 0) 63 return rtBase64TranslateUtf16(*pwszString); 64 return BASE64_INVALID; 65 } 66 67 68 /* 69 * Mostly the same as RTBase64DecodedSizeEx, except for the wider character 70 * type and therefore more careful handling of g_szRTBase64ValToChar and additional 71 * space characters. Fixes must be applied to both copies of the code. 108 72 */ 109 static void rtBase64Sanity(void) 110 { 111 static bool s_fSane = false; 112 if (RT_UNLIKELY(!s_fSane)) 113 { 114 for (unsigned i = 0; i < 64; i++) 115 { 116 unsigned ch = g_szValToChar[i]; 117 Assert(ch); 118 Assert(g_au8CharToVal[ch] == i); 119 } 120 121 for (unsigned i = 0; i < 256; i++) 122 { 123 uint8_t u8 = g_au8CharToVal[i]; 124 Assert( ( u8 == BASE64_INVALID 125 && !RT_C_IS_ALNUM(i) 126 && !RT_C_IS_SPACE(i)) 127 || ( u8 == BASE64_PAD 128 && i == '=') 129 || ( u8 == BASE64_SPACE 130 && RT_C_IS_SPACE(i)) 131 || ( u8 < 64 132 && (unsigned)g_szValToChar[u8] == i)); 133 } 134 ASMAtomicWriteBool(&s_fSane, true); 135 } 136 } 137 #endif /* RT_STRICT */ 138 139 140 RTDECL(ssize_t) RTBase64DecodedSizeEx(const char *pszString, size_t cchStringMax, char **ppszEnd) 73 RTDECL(ssize_t) RTBase64DecodedUtf16SizeEx(PCRTUTF16 pwszString, size_t cwcStringMax, PRTUTF16 *ppwszEnd) 141 74 { 142 75 #ifdef RT_STRICT … … 149 82 uint32_t c6Bits = 0; 150 83 uint8_t u8 = BASE64_INVALID; 151 unsigned ch = 0; 152 AssertCompile(sizeof(char) == sizeof(uint8_t)); 153 154 while (cchStringMax > 0 && (ch = *pszString)) 155 { 156 u8 = g_au8CharToVal[ch]; 84 RTUTF16 wc = 0; 85 86 while (cwcStringMax > 0 && (wc = *pwszString)) 87 { 88 u8 = rtBase64TranslateUtf16(wc); 157 89 if (u8 < 64) 158 90 c6Bits++; … … 161 93 162 94 /* advance */ 163 p szString++;164 c chStringMax--;95 pwszString++; 96 cwcStringMax--; 165 97 } 166 98 … … 174 106 cbPad = 1; 175 107 c6Bits++; 176 p szString++;177 c chStringMax--;178 while (c chStringMax > 0 && (ch = *pszString))179 { 180 u8 = g_au8CharToVal[ch];108 pwszString++; 109 cwcStringMax--; 110 while (cwcStringMax > 0 && (wc = *pwszString)) 111 { 112 u8 = rtBase64TranslateUtf16(wc); 181 113 if (u8 != BASE64_SPACE) 182 114 { … … 186 118 cbPad++; 187 119 } 188 p szString++;189 c chStringMax--;120 pwszString++; 121 cwcStringMax--; 190 122 } 191 123 if (cbPad >= 3) … … 198 130 */ 199 131 if ( u8 == BASE64_INVALID 200 && !pp szEnd201 && ch)132 && !ppwszEnd 133 && wc) 202 134 return -1; 203 135 … … 205 137 * Recalc 6-bit to 8-bit and adjust for padding. 206 138 */ 207 size_t cb; 208 if (c6Bits * 3 / 3 == c6Bits) 209 { 210 if ((c6Bits * 3 % 4) != 0) 211 return -1; 212 cb = c6Bits * 3 / 4; 213 } 214 else 215 { 216 if ((c6Bits * (uint64_t)3 % 4) != 0) 217 return -1; 218 cb = c6Bits * (uint64_t)3 / 4; 219 } 220 221 if (cb < cbPad) 222 return -1; 223 cb -= cbPad; 224 225 if (ppszEnd) 226 *ppszEnd = (char *)pszString; 227 return cb; 228 } 229 RT_EXPORT_SYMBOL(RTBase64DecodedSizeEx); 230 231 232 RTDECL(ssize_t) RTBase64DecodedSize(const char *pszString, char **ppszEnd) 233 { 234 return RTBase64DecodedSizeEx(pszString, RTSTR_MAX, ppszEnd); 235 } 236 RT_EXPORT_SYMBOL(RTBase64DecodedSize); 237 238 239 RTDECL(int) RTBase64DecodeEx(const char *pszString, size_t cchStringMax, void *pvData, size_t cbData, 240 size_t *pcbActual, char **ppszEnd) 139 if (ppwszEnd) 140 *ppwszEnd = (PRTUTF16)pwszString; 141 return rtBase64DecodedSizeRecalc(c6Bits, cbPad); 142 } 143 RT_EXPORT_SYMBOL(RTBase64DecodedUtf16SizeEx); 144 145 146 RTDECL(ssize_t) RTBase64DecodedUtf16Size(PCRTUTF16 pwszString, PRTUTF16 *ppwszEnd) 147 { 148 return RTBase64DecodedUtf16SizeEx(pwszString, RTSTR_MAX, ppwszEnd); 149 } 150 RT_EXPORT_SYMBOL(RTBase64DecodedUtf16Size); 151 152 153 RTDECL(int) RTBase64DecodeUtf16Ex(PCRTUTF16 pwszString, size_t cwcStringMax, void *pvData, size_t cbData, 154 size_t *pcbActual, PRTUTF16 *ppwszEnd) 241 155 { 242 156 #ifdef RT_STRICT … … 249 163 uint8_t u8Trio[3] = { 0, 0, 0 }; /* shuts up gcc */ 250 164 uint8_t *pbData = (uint8_t *)pvData; 251 unsigned ch;252 165 uint8_t u8; 253 166 unsigned c6Bits = 0; … … 257 170 { 258 171 /* The first 6-bit group. */ 259 while ((u8 = g_au8CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)260 p szString++, cchStringMax--;172 while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) == BASE64_SPACE) 173 pwszString++, cwcStringMax--; 261 174 if (u8 >= 64) 262 175 { … … 265 178 } 266 179 u8Trio[0] = u8 << 2; 267 p szString++;268 c chStringMax--;180 pwszString++; 181 cwcStringMax--; 269 182 270 183 /* The second 6-bit group. */ 271 while ((u8 = g_au8CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)272 p szString++, cchStringMax--;184 while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) == BASE64_SPACE) 185 pwszString++, cwcStringMax--; 273 186 if (u8 >= 64) 274 187 { … … 278 191 u8Trio[0] |= u8 >> 4; 279 192 u8Trio[1] = u8 << 4; 280 p szString++;281 c chStringMax--;193 pwszString++; 194 cwcStringMax--; 282 195 283 196 /* The third 6-bit group. */ 284 197 u8 = BASE64_INVALID; 285 while ((u8 = g_au8CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)286 p szString++, cchStringMax--;198 while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) == BASE64_SPACE) 199 pwszString++, cwcStringMax--; 287 200 if (u8 >= 64) 288 201 { … … 292 205 u8Trio[1] |= u8 >> 2; 293 206 u8Trio[2] = u8 << 6; 294 p szString++;295 c chStringMax--;207 pwszString++; 208 cwcStringMax--; 296 209 297 210 /* The fourth 6-bit group. */ 298 211 u8 = BASE64_INVALID; 299 while ((u8 = g_au8CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)300 p szString++, cchStringMax--;212 while ((u8 = rtBase64TranslateNextUtf16(pwszString, cwcStringMax)) == BASE64_SPACE) 213 pwszString++, cwcStringMax--; 301 214 if (u8 >= 64) 302 215 { … … 305 218 } 306 219 u8Trio[2] |= u8; 307 p szString++;308 c chStringMax--;220 pwszString++; 221 cwcStringMax--; 309 222 310 223 /* flush the trio */ … … 326 239 { 327 240 cbPad = 1; 328 pszString++; 329 cchStringMax--; 330 while (cchStringMax > 0 && (ch = (uint8_t)*pszString)) 331 { 332 u8 = g_au8CharToVal[ch]; 241 pwszString++; 242 cwcStringMax--; 243 RTUTF16 wc; 244 while (cwcStringMax > 0 && (wc = *pwszString)) 245 { 246 u8 = rtBase64TranslateUtf16(wc); 333 247 if (u8 != BASE64_SPACE) 334 248 { … … 337 251 cbPad++; 338 252 } 339 p szString++;340 c chStringMax--;253 pwszString++; 254 cwcStringMax--; 341 255 } 342 256 if (cbPad >= 3) … … 349 263 */ 350 264 if ( u8 == BASE64_INVALID 351 && !ppszEnd 352 && ch != '\0') 265 && !ppwszEnd 266 && cwcStringMax != 0 267 && *pwszString != '\0') 353 268 return VERR_INVALID_BASE64_ENCODING; 354 269 … … 400 315 * Set optional return values and return successfully. 401 316 */ 402 if (pp szEnd)403 *pp szEnd = (char *)pszString;317 if (ppwszEnd) 318 *ppwszEnd = (PRTUTF16)pwszString; 404 319 if (pcbActual) 405 320 *pcbActual = pbData - (uint8_t *)pvData; 406 321 return VINF_SUCCESS; 407 322 } 408 RT_EXPORT_SYMBOL(RTBase64Decode Ex);409 410 411 RTDECL(int) RTBase64Decode (const char *pszString, void *pvData, size_t cbData, size_t *pcbActual, char **ppszEnd)412 { 413 return RTBase64Decode Ex(pszString, RTSTR_MAX, pvData, cbData, pcbActual, ppszEnd);414 } 415 RT_EXPORT_SYMBOL(RTBase64Decode );416 417 418 RTDECL(size_t) RTBase64Encoded Length(size_t cbData)323 RT_EXPORT_SYMBOL(RTBase64DecodeUtf16Ex); 324 325 326 RTDECL(int) RTBase64DecodeUtf16(PCRTUTF16 pwszString, void *pvData, size_t cbData, size_t *pcbActual, PRTUTF16 *ppwszEnd) 327 { 328 return RTBase64DecodeUtf16Ex(pwszString, RTSTR_MAX, pvData, cbData, pcbActual, ppwszEnd); 329 } 330 RT_EXPORT_SYMBOL(RTBase64DecodeUtf16); 331 332 333 RTDECL(size_t) RTBase64EncodedUtf16Length(size_t cbData) 419 334 { 420 335 return RTBase64EncodedLengthEx(cbData, 0); 421 336 } 422 RT_EXPORT_SYMBOL(RTBase64EncodedLength); 423 424 425 RTDECL(size_t) RTBase64EncodedLengthEx(size_t cbData, uint32_t fFlags) 426 { 427 size_t const cchEol = g_acchEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK]; 428 429 if (cbData * 8 / 8 != cbData) 430 { 431 AssertReturn(sizeof(size_t) == sizeof(uint64_t), ~(size_t)0); 432 uint64_t cch = cbData * (uint64_t)8; 433 while (cch % 24) 434 cch += 8; 435 cch /= 6; 436 cch += ((cch - 1) / RTBASE64_LINE_LEN) * cchEol; 437 return cch; 438 } 439 440 size_t cch = cbData * 8; 441 while (cch % 24) 442 cch += 8; 443 cch /= 6; 444 cch += ((cch - 1) / RTBASE64_LINE_LEN) * cchEol; 445 return cch; 446 } 447 RT_EXPORT_SYMBOL(RTBase64EncodedLengthEx); 448 449 450 RTDECL(int) RTBase64Encode(const void *pvData, size_t cbData, char *pszBuf, size_t cbBuf, size_t *pcchActual) 451 { 452 return RTBase64EncodeEx(pvData, cbData, 0, pszBuf, cbBuf, pcchActual); 453 } 454 RT_EXPORT_SYMBOL(RTBase64Encode); 455 456 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. 461 */ 462 RTDECL(int) RTBase64EncodeEx(const void *pvData, size_t cbData, uint32_t fFlags, 463 char *pszBuf, size_t cbBuf, size_t *pcchActual) 464 { 465 /* Expand the EOL style flags: */ 466 size_t const cchEol = g_acchEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK]; 467 char const chEol0 = g_aachEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0]; 468 char const chEol1 = g_aachEolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1]; 469 Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U)); 470 471 /* 472 * Process whole "trios" of input data. 473 */ 474 uint8_t u8A; 475 uint8_t u8B; 476 uint8_t u8C; 477 size_t cbLineFeed = cchEol ? cbBuf - RTBASE64_LINE_LEN : ~(size_t)0; 478 const uint8_t *pbSrc = (const uint8_t *)pvData; 479 char *pchDst = pszBuf; 480 while (cbData >= 3) 481 { 482 if (cbBuf < 4 + 1) 483 return VERR_BUFFER_OVERFLOW; 484 485 /* encode */ 486 u8A = pbSrc[0]; 487 pchDst[0] = g_szValToChar[u8A >> 2]; 488 u8B = pbSrc[1]; 489 pchDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 490 u8C = pbSrc[2]; 491 pchDst[2] = g_szValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)]; 492 pchDst[3] = g_szValToChar[u8C & 0x3f]; 493 494 /* advance */ 495 cbBuf -= 4; 496 pchDst += 4; 497 cbData -= 3; 498 pbSrc += 3; 499 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; 510 } 511 } 512 513 /* 514 * Deal with the odd bytes and string termination. 515 */ 516 if (cbData) 517 { 518 if (cbBuf < 4 + 1) 519 return VERR_BUFFER_OVERFLOW; 520 switch (cbData) 521 { 522 case 1: 523 u8A = pbSrc[0]; 524 pchDst[0] = g_szValToChar[u8A >> 2]; 525 pchDst[1] = g_szValToChar[(u8A << 4) & 0x3f]; 526 pchDst[2] = '='; 527 pchDst[3] = '='; 528 break; 529 case 2: 530 u8A = pbSrc[0]; 531 pchDst[0] = g_szValToChar[u8A >> 2]; 532 u8B = pbSrc[1]; 533 pchDst[1] = g_szValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 534 pchDst[2] = g_szValToChar[(u8B << 2) & 0x3f]; 535 pchDst[3] = '='; 536 break; 537 } 538 pchDst += 4; 539 } 540 541 *pchDst = '\0'; 542 543 if (pcchActual) 544 *pcchActual = pchDst - pszBuf; 545 return VINF_SUCCESS; 546 } 547 RT_EXPORT_SYMBOL(RTBase64EncodeEx); 337 RT_EXPORT_SYMBOL(RTBase64EncodedUtf16Length); 338 339 340 RTDECL(size_t) RTBase64EncodedUtf16LengthEx(size_t cbData, uint32_t fFlags) 341 { 342 return RTBase64EncodedLengthEx(cbData, fFlags); 343 } 344 RT_EXPORT_SYMBOL(RTBase64EncodedUtf16LengthEx); 345 346 347 RTDECL(int) RTBase64EncodeUtf16(const void *pvData, size_t cbData, PRTUTF16 pwszBuf, size_t cwcBuf, size_t *pcwcActual) 348 { 349 return RTBase64EncodeUtf16Ex(pvData, cbData, 0, pwszBuf, cwcBuf, pcwcActual); 350 } 351 RT_EXPORT_SYMBOL(RTBase64EncodeUtf16); 548 352 549 353 … … 557 361 { 558 362 /* Expand the EOL style flags: */ 559 size_t const cchEol = g_acch EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];560 char const chEol0 = g_aach EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];561 char const chEol1 = g_aach EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];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]; 562 366 Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U)); 563 367 … … 578 382 /* encode */ 579 383 u8A = pbSrc[0]; 580 pwcDst[0] = g_sz ValToChar[u8A >> 2];384 pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 581 385 u8B = pbSrc[1]; 582 pwcDst[1] = g_sz ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];386 pwcDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 583 387 u8C = pbSrc[2]; 584 pwcDst[2] = g_sz ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];585 pwcDst[3] = g_sz ValToChar[u8C & 0x3f];388 pwcDst[2] = g_szRTBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)]; 389 pwcDst[3] = g_szRTBase64ValToChar[u8C & 0x3f]; 586 390 587 391 /* advance */ … … 615 419 case 1: 616 420 u8A = pbSrc[0]; 617 pwcDst[0] = g_sz ValToChar[u8A >> 2];618 pwcDst[1] = g_sz ValToChar[(u8A << 4) & 0x3f];421 pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 422 pwcDst[1] = g_szRTBase64ValToChar[(u8A << 4) & 0x3f]; 619 423 pwcDst[2] = '='; 620 424 pwcDst[3] = '='; … … 622 426 case 2: 623 427 u8A = pbSrc[0]; 624 pwcDst[0] = g_sz ValToChar[u8A >> 2];428 pwcDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 625 429 u8B = pbSrc[1]; 626 pwcDst[1] = g_sz ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];627 pwcDst[2] = g_sz ValToChar[(u8B << 2) & 0x3f];430 pwcDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 431 pwcDst[2] = g_szRTBase64ValToChar[(u8B << 2) & 0x3f]; 628 432 pwcDst[3] = '='; 629 433 break; … … 640 444 RT_EXPORT_SYMBOL(RTBase64EncodeUtf16Ex); 641 445 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 -
trunk/src/VBox/Runtime/common/string/base64.cpp
r84286 r84293 2 2 /** @file 3 3 * IPRT - Base64, MIME content transfer encoding. 4 * 5 * @note The base64-utf16.cpp file must be diffable with this one. 6 * Fixed typically applies to both files. 4 7 */ 5 8 … … 40 43 #endif 41 44 42 43 /********************************************************************************************************************************* 44 * Defined Constants And Macros * 45 *********************************************************************************************************************************/ 46 /** The line length used for encoding. */ 47 #define RTBASE64_LINE_LEN 64 48 49 /** @name Special g_au8CharToVal values 50 * @{ */ 51 #define BASE64_SPACE 0xc0 52 #define BASE64_PAD 0xe0 53 #define BASE64_INVALID 0xff 54 /** @} */ 45 #include "base64.h" 55 46 56 47 … … 60 51 /** Base64 character to value. (RFC 2045) 61 52 * ASSUMES ASCII / UTF-8. */ 62 static const uint8_t g_au8CharToVal[256] =53 DECL_HIDDEN_CONST(const uint8_t) g_au8RTBase64CharToVal[256] = 63 54 { 64 55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, /* 0x00..0x0f */ … … 81 72 82 73 /** Value to Base64 character. (RFC 2045) */ 83 static const char g_szValToChar[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";74 DECL_HIDDEN_CONST(const char) g_szRTBase64ValToChar[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 84 75 85 76 /** The end-of-line lengths (indexed by style flag value). */ 86 static const size_t g_acchEolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1] =77 DECL_HIDDEN_CONST(const size_t) g_acchRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1] = 87 78 { 88 79 /*[RTBASE64_FLAGS_EOL_NATIVE ]:*/ RTBASE64_EOL_SIZE, … … 93 84 94 85 /** The end-of-line characters (zero, one or two). */ 95 static const char g_aachEolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2] =86 DECL_HIDDEN_CONST(const char) g_aachRTBase64EolStyles[RTBASE64_FLAGS_EOL_STYLE_MASK + 1][2] = 96 87 { 97 88 /*[RTBASE64_FLAGS_EOL_NATIVE ]:*/ { RTBASE64_EOL_SIZE == 1 ? '\n' : '\r', RTBASE64_EOL_SIZE == 1 ? '\0' : '\n', }, … … 107 98 * Perform table sanity checks on the first call. 108 99 */ 109 static voidrtBase64Sanity(void)100 DECLHIDDEN(void) rtBase64Sanity(void) 110 101 { 111 102 static bool s_fSane = false; … … 114 105 for (unsigned i = 0; i < 64; i++) 115 106 { 116 unsigned ch = g_sz ValToChar[i];107 unsigned ch = g_szRTBase64ValToChar[i]; 117 108 Assert(ch); 118 Assert(g_au8 CharToVal[ch] == i);109 Assert(g_au8RTBase64CharToVal[ch] == i); 119 110 } 120 111 121 112 for (unsigned i = 0; i < 256; i++) 122 113 { 123 uint8_t u8 = g_au8 CharToVal[i];114 uint8_t u8 = g_au8RTBase64CharToVal[i]; 124 115 Assert( ( u8 == BASE64_INVALID 125 116 && !RT_C_IS_ALNUM(i) … … 130 121 && RT_C_IS_SPACE(i)) 131 122 || ( u8 < 64 132 && (unsigned)g_sz ValToChar[u8] == i));123 && (unsigned)g_szRTBase64ValToChar[u8] == i)); 133 124 } 134 125 ASMAtomicWriteBool(&s_fSane, true); … … 138 129 139 130 131 /* 132 * Mostly the same as RTBase64DecodedUtf16SizeEx, except for the simpler 133 * character type. Fixes must be applied to both copies of the code. 134 */ 140 135 RTDECL(ssize_t) RTBase64DecodedSizeEx(const char *pszString, size_t cchStringMax, char **ppszEnd) 141 136 { … … 154 149 while (cchStringMax > 0 && (ch = *pszString)) 155 150 { 156 u8 = g_au8 CharToVal[ch];151 u8 = g_au8RTBase64CharToVal[ch]; 157 152 if (u8 < 64) 158 153 c6Bits++; … … 178 173 while (cchStringMax > 0 && (ch = *pszString)) 179 174 { 180 u8 = g_au8 CharToVal[ch];175 u8 = g_au8RTBase64CharToVal[ch]; 181 176 if (u8 != BASE64_SPACE) 182 177 { … … 205 200 * Recalc 6-bit to 8-bit and adjust for padding. 206 201 */ 207 size_t cb;208 if (c6Bits * 3 / 3 == c6Bits)209 {210 if ((c6Bits * 3 % 4) != 0)211 return -1;212 cb = c6Bits * 3 / 4;213 }214 else215 {216 if ((c6Bits * (uint64_t)3 % 4) != 0)217 return -1;218 cb = c6Bits * (uint64_t)3 / 4;219 }220 221 if (cb < cbPad)222 return -1;223 cb -= cbPad;224 225 202 if (ppszEnd) 226 203 *ppszEnd = (char *)pszString; 227 return cb;204 return rtBase64DecodedSizeRecalc(c6Bits, cbPad); 228 205 } 229 206 RT_EXPORT_SYMBOL(RTBase64DecodedSizeEx); … … 257 234 { 258 235 /* The first 6-bit group. */ 259 while ((u8 = g_au8 CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)236 while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE) 260 237 pszString++, cchStringMax--; 261 238 if (u8 >= 64) … … 269 246 270 247 /* The second 6-bit group. */ 271 while ((u8 = g_au8 CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)248 while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE) 272 249 pszString++, cchStringMax--; 273 250 if (u8 >= 64) … … 283 260 /* The third 6-bit group. */ 284 261 u8 = BASE64_INVALID; 285 while ((u8 = g_au8 CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)262 while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE) 286 263 pszString++, cchStringMax--; 287 264 if (u8 >= 64) … … 297 274 /* The fourth 6-bit group. */ 298 275 u8 = BASE64_INVALID; 299 while ((u8 = g_au8 CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE)276 while ((u8 = g_au8RTBase64CharToVal[ch = cchStringMax > 0 ? (uint8_t)*pszString : 0]) == BASE64_SPACE) 300 277 pszString++, cchStringMax--; 301 278 if (u8 >= 64) … … 330 307 while (cchStringMax > 0 && (ch = (uint8_t)*pszString)) 331 308 { 332 u8 = g_au8 CharToVal[ch];309 u8 = g_au8RTBase64CharToVal[ch]; 333 310 if (u8 != BASE64_SPACE) 334 311 { … … 425 402 RTDECL(size_t) RTBase64EncodedLengthEx(size_t cbData, uint32_t fFlags) 426 403 { 427 size_t const cchEol = g_acch EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];404 size_t const cchEol = g_acchRTBase64EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK]; 428 405 429 406 if (cbData * 8 / 8 != cbData) … … 464 441 { 465 442 /* Expand the EOL style flags: */ 466 size_t const cchEol = g_acch EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK];467 char const chEol0 = g_aach EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][0];468 char const chEol1 = g_aach EolStyles[fFlags & RTBASE64_FLAGS_EOL_STYLE_MASK][1];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]; 469 446 Assert(cchEol == (chEol0 != '\0' ? 1U : 0U) + (chEol1 != '\0' ? 1U : 0U)); 470 447 … … 485 462 /* encode */ 486 463 u8A = pbSrc[0]; 487 pchDst[0] = g_sz ValToChar[u8A >> 2];464 pchDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 488 465 u8B = pbSrc[1]; 489 pchDst[1] = g_sz ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];466 pchDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 490 467 u8C = pbSrc[2]; 491 pchDst[2] = g_sz ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)];492 pchDst[3] = g_sz ValToChar[u8C & 0x3f];468 pchDst[2] = g_szRTBase64ValToChar[((u8B << 2) & 0x3f) | (u8C >> 6)]; 469 pchDst[3] = g_szRTBase64ValToChar[u8C & 0x3f]; 493 470 494 471 /* advance */ … … 522 499 case 1: 523 500 u8A = pbSrc[0]; 524 pchDst[0] = g_sz ValToChar[u8A >> 2];525 pchDst[1] = g_sz ValToChar[(u8A << 4) & 0x3f];501 pchDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 502 pchDst[1] = g_szRTBase64ValToChar[(u8A << 4) & 0x3f]; 526 503 pchDst[2] = '='; 527 504 pchDst[3] = '='; … … 529 506 case 2: 530 507 u8A = pbSrc[0]; 531 pchDst[0] = g_sz ValToChar[u8A >> 2];508 pchDst[0] = g_szRTBase64ValToChar[u8A >> 2]; 532 509 u8B = pbSrc[1]; 533 pchDst[1] = g_sz ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)];534 pchDst[2] = g_sz ValToChar[(u8B << 2) & 0x3f];510 pchDst[1] = g_szRTBase64ValToChar[((u8A << 4) & 0x3f) | (u8B >> 4)]; 511 pchDst[2] = g_szRTBase64ValToChar[(u8B << 2) & 0x3f]; 535 512 pchDst[3] = '='; 536 513 break; … … 547 524 RT_EXPORT_SYMBOL(RTBase64EncodeEx); 548 525 549 550 /*551 * Please note that RTBase64EncodeEx contains an almost exact copy of552 * 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 -
trunk/src/VBox/Runtime/testcase/tstRTBase64.cpp
r84286 r84293 113 113 */ 114 114 115 /* Decoding: later */116 117 115 /* Encoding UTF-16: */ 118 116 memset(wszOut, 0xaa, sizeof(wszOut)); … … 130 128 if (cwcOut != cwcOut2) 131 129 RTTestIFailed("RTBase64EncodedLength returned %zu RTUTF16 units, expected %zu.\n", cwcOut2, cwcOut); 130 131 /* Decoding UTF-16: */ 132 PRTUTF16 pwszEnc = NULL; 133 RTTESTI_CHECK_RC_OK_RETV(RTStrToUtf16(pszEnc, &pwszEnc)); 134 135 rc = RTBase64DecodeUtf16(pwszEnc, szOut, cbData, &cchOut, NULL); 136 if (RT_FAILURE(rc)) 137 RTTestIFailed("RTBase64DecodeUtf16 -> %Rrc", rc); 138 else if (cchOut != cbData) 139 RTTestIFailed("RTBase64DecodeUtf16 returned %zu bytes, expected %zu.", cchOut, cbData); 140 else if (memcmp(szOut, pvData, cchOut)) 141 { 142 if (fTextData) 143 RTTestIFailed("RTBase64Decode returned:\n%.*s\nexpected:\n%s\n", (int)cchOut, szOut, pvData); 144 else 145 RTTestIFailed("RTBase64Decode return mismatching output\n"); 146 } 147 148 cchOut = RTBase64DecodedUtf16Size(pwszEnc, NULL); 149 if (cchOut != cbData) 150 RTTestIFailed("RTBase64DecodedUtf16Size returned %zu bytes, expected %zu.\n", cchOut, cbData); 151 152 RTUtf16Free(pwszEnc); 132 153 } 133 154
Note:
See TracChangeset
for help on using the changeset viewer.

