| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ |
| #include "kwsysPrivate.h" |
| #include KWSYS_HEADER(Base64.h) |
| |
| /* Work-around CMake dependency scanning limitation. This must |
| duplicate the above list of headers. */ |
| #if 0 |
| # include "Base64.h.in" |
| #endif |
| |
| static const unsigned char kwsysBase64EncodeTable[65] = |
| "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| "abcdefghijklmnopqrstuvwxyz" |
| "0123456789+/"; |
| |
| static const unsigned char kwsysBase64DecodeTable[256] = { |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, |
| 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, |
| 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, |
| 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, |
| 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, |
| 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| /*------------------------------------*/ |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
| }; |
| |
| static unsigned char kwsysBase64EncodeChar(int c) |
| { |
| return kwsysBase64EncodeTable[(unsigned char)c]; |
| } |
| |
| static unsigned char kwsysBase64DecodeChar(unsigned char c) |
| { |
| return kwsysBase64DecodeTable[c]; |
| } |
| |
| /* Encode 3 bytes into a 4 byte string. */ |
| void kwsysBase64_Encode3(const unsigned char* src, unsigned char* dest) |
| { |
| dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); |
| dest[1] = |
| kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F)); |
| dest[2] = |
| kwsysBase64EncodeChar(((src[1] << 2) & 0x3C) | ((src[2] >> 6) & 0x03)); |
| dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F); |
| } |
| |
| /* Encode 2 bytes into a 4 byte string. */ |
| void kwsysBase64_Encode2(const unsigned char* src, unsigned char* dest) |
| { |
| dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); |
| dest[1] = |
| kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F)); |
| dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C)); |
| dest[3] = '='; |
| } |
| |
| /* Encode 1 bytes into a 4 byte string. */ |
| void kwsysBase64_Encode1(const unsigned char* src, unsigned char* dest) |
| { |
| dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); |
| dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)); |
| dest[2] = '='; |
| dest[3] = '='; |
| } |
| |
| /* Encode 'length' bytes from the input buffer and store the |
| encoded stream into the output buffer. Return the length of the encoded |
| buffer (output). Note that the output buffer must be allocated by the caller |
| (length * 1.5 should be a safe estimate). If 'mark_end' is true than an |
| extra set of 4 bytes is added to the end of the stream if the input is a |
| multiple of 3 bytes. These bytes are invalid chars and therefore they will |
| stop the decoder thus enabling the caller to decode a stream without |
| actually knowing how much data to expect (if the input is not a multiple of |
| 3 bytes then the extra padding needed to complete the encode 4 bytes will |
| stop the decoding anyway). */ |
| size_t kwsysBase64_Encode(const unsigned char* input, size_t length, |
| unsigned char* output, int mark_end) |
| { |
| const unsigned char* ptr = input; |
| const unsigned char* end = input + length; |
| unsigned char* optr = output; |
| |
| /* Encode complete triplet */ |
| |
| while ((end - ptr) >= 3) { |
| kwsysBase64_Encode3(ptr, optr); |
| ptr += 3; |
| optr += 4; |
| } |
| |
| /* Encodes a 2-byte ending into 3 bytes and 1 pad byte and writes. */ |
| |
| if (end - ptr == 2) { |
| kwsysBase64_Encode2(ptr, optr); |
| optr += 4; |
| } |
| |
| /* Encodes a 1-byte ending into 2 bytes and 2 pad bytes */ |
| |
| else if (end - ptr == 1) { |
| kwsysBase64_Encode1(ptr, optr); |
| optr += 4; |
| } |
| |
| /* Do we need to mark the end */ |
| |
| else if (mark_end) { |
| optr[0] = optr[1] = optr[2] = optr[3] = '='; |
| optr += 4; |
| } |
| |
| return (size_t)(optr - output); |
| } |
| |
| /* Decode 4 bytes into a 3 byte string. */ |
| int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest) |
| { |
| unsigned char d0; |
| unsigned char d1; |
| unsigned char d2; |
| unsigned char d3; |
| |
| d0 = kwsysBase64DecodeChar(src[0]); |
| d1 = kwsysBase64DecodeChar(src[1]); |
| d2 = kwsysBase64DecodeChar(src[2]); |
| d3 = kwsysBase64DecodeChar(src[3]); |
| |
| /* Make sure all characters were valid */ |
| |
| if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF) { |
| return 0; |
| } |
| |
| /* Decode the 3 bytes */ |
| |
| dest[0] = (unsigned char)(((d0 << 2) & 0xFC) | ((d1 >> 4) & 0x03)); |
| dest[1] = (unsigned char)(((d1 << 4) & 0xF0) | ((d2 >> 2) & 0x0F)); |
| dest[2] = (unsigned char)(((d2 << 6) & 0xC0) | ((d3 >> 0) & 0x3F)); |
| |
| /* Return the number of bytes actually decoded */ |
| |
| if (src[2] == '=') { |
| return 1; |
| } |
| if (src[3] == '=') { |
| return 2; |
| } |
| return 3; |
| } |
| |
| /* Decode bytes from the input buffer and store the decoded stream |
| into the output buffer until 'length' bytes have been decoded. Return the |
| real length of the decoded stream (which should be equal to 'length'). Note |
| that the output buffer must be allocated by the caller. If |
| 'max_input_length' is not null, then it specifies the number of encoded |
| bytes that should be at most read from the input buffer. In that case the |
| 'length' parameter is ignored. This enables the caller to decode a stream |
| without actually knowing how much decoded data to expect (of course, the |
| buffer must be large enough). */ |
| size_t kwsysBase64_Decode(const unsigned char* input, size_t length, |
| unsigned char* output, size_t max_input_length) |
| { |
| const unsigned char* ptr = input; |
| unsigned char* optr = output; |
| |
| /* Decode complete triplet */ |
| |
| if (max_input_length) { |
| const unsigned char* end = input + max_input_length; |
| while (ptr < end) { |
| int len = kwsysBase64_Decode3(ptr, optr); |
| optr += len; |
| if (len < 3) { |
| return (size_t)(optr - output); |
| } |
| ptr += 4; |
| } |
| } else { |
| unsigned char* oend = output + length; |
| while ((oend - optr) >= 3) { |
| int len = kwsysBase64_Decode3(ptr, optr); |
| optr += len; |
| if (len < 3) { |
| return (size_t)(optr - output); |
| } |
| ptr += 4; |
| } |
| |
| /* Decode the last triplet */ |
| |
| if (oend - optr == 2) { |
| unsigned char temp[3]; |
| int len = kwsysBase64_Decode3(ptr, temp); |
| if (len >= 2) { |
| optr[0] = temp[0]; |
| optr[1] = temp[1]; |
| optr += 2; |
| } else if (len > 0) { |
| optr[0] = temp[0]; |
| optr += 1; |
| } |
| } else if (oend - optr == 1) { |
| unsigned char temp[3]; |
| int len = kwsysBase64_Decode3(ptr, temp); |
| if (len > 0) { |
| optr[0] = temp[0]; |
| optr += 1; |
| } |
| } |
| } |
| |
| return (size_t)(optr - output); |
| } |