| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmBase32.h" | |
| // -- Static functions | |
| static unsigned char const Base32EncodeTable[33] = | |
| "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; | |
| inline unsigned char Base32EncodeChar(int schar) | |
| { | |
| return Base32EncodeTable[schar]; | |
| } | |
| static void Base32Encode5(unsigned char const src[5], char dst[8]) | |
| { | |
| // [0]:5 bits | |
| dst[0] = Base32EncodeChar((src[0] >> 3) & 0x1F); | |
| // [0]:3 bits + [1]:2 bits | |
| dst[1] = Base32EncodeChar(((src[0] << 2) & 0x1C) + ((src[1] >> 6) & 0x03)); | |
| // [1]:5 bits | |
| dst[2] = Base32EncodeChar((src[1] >> 1) & 0x1F); | |
| // [1]:1 bit + [2]:4 bits | |
| dst[3] = Base32EncodeChar(((src[1] << 4) & 0x10) + ((src[2] >> 4) & 0x0F)); | |
| // [2]:4 bits + [3]:1 bit | |
| dst[4] = Base32EncodeChar(((src[2] << 1) & 0x1E) + ((src[3] >> 7) & 0x01)); | |
| // [3]:5 bits | |
| dst[5] = Base32EncodeChar((src[3] >> 2) & 0x1F); | |
| // [3]:2 bits + [4]:3 bit | |
| dst[6] = Base32EncodeChar(((src[3] << 3) & 0x18) + ((src[4] >> 5) & 0x07)); | |
| // [4]:5 bits | |
| dst[7] = Base32EncodeChar((src[4] << 0) & 0x1F); | |
| } | |
| // -- Class methods | |
| cmBase32Encoder::cmBase32Encoder() = default; | |
| std::string cmBase32Encoder::encodeString(unsigned char const* input, | |
| size_t len, bool padding) | |
| { | |
| std::string res; | |
| static size_t const blockSize = 5; | |
| static size_t const bufferSize = 8; | |
| char buffer[bufferSize]; | |
| unsigned char const* end = input + len; | |
| while ((input + blockSize) <= end) { | |
| Base32Encode5(input, buffer); | |
| res.append(buffer, bufferSize); | |
| input += blockSize; | |
| } | |
| size_t remain = static_cast<size_t>(end - input); | |
| if (remain != 0) { | |
| // Temporary source buffer filled up with 0s | |
| unsigned char padded[blockSize]; | |
| for (size_t ii = 0; ii != remain; ++ii) { | |
| padded[ii] = input[ii]; | |
| } | |
| for (size_t ii = remain; ii != blockSize; ++ii) { | |
| padded[ii] = 0; | |
| } | |
| Base32Encode5(padded, buffer); | |
| size_t numPad(0); | |
| switch (remain) { | |
| case 1: | |
| numPad = 6; | |
| break; | |
| case 2: | |
| numPad = 4; | |
| break; | |
| case 3: | |
| numPad = 3; | |
| break; | |
| case 4: | |
| numPad = 1; | |
| break; | |
| default: | |
| break; | |
| } | |
| res.append(buffer, bufferSize - numPad); | |
| if (padding) { | |
| for (size_t ii = 0; ii != numPad; ++ii) { | |
| res.push_back(paddingChar); | |
| } | |
| } | |
| } | |
| return res; | |
| } |