Merge branch 'release-3.29'
[kiteware-cmake.git] / Source / cmBase32.cxx
blobe8e46aa63a9ad59fad43c9169f6ef902b0944145
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmBase32.h"
5 // -- Static functions
7 static const unsigned char Base32EncodeTable[33] =
8 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
10 inline unsigned char Base32EncodeChar(int schar)
12 return Base32EncodeTable[schar];
15 static void Base32Encode5(const unsigned char src[5], char dst[8])
17 // [0]:5 bits
18 dst[0] = Base32EncodeChar((src[0] >> 3) & 0x1F);
19 // [0]:3 bits + [1]:2 bits
20 dst[1] = Base32EncodeChar(((src[0] << 2) & 0x1C) + ((src[1] >> 6) & 0x03));
21 // [1]:5 bits
22 dst[2] = Base32EncodeChar((src[1] >> 1) & 0x1F);
23 // [1]:1 bit + [2]:4 bits
24 dst[3] = Base32EncodeChar(((src[1] << 4) & 0x10) + ((src[2] >> 4) & 0x0F));
25 // [2]:4 bits + [3]:1 bit
26 dst[4] = Base32EncodeChar(((src[2] << 1) & 0x1E) + ((src[3] >> 7) & 0x01));
27 // [3]:5 bits
28 dst[5] = Base32EncodeChar((src[3] >> 2) & 0x1F);
29 // [3]:2 bits + [4]:3 bit
30 dst[6] = Base32EncodeChar(((src[3] << 3) & 0x18) + ((src[4] >> 5) & 0x07));
31 // [4]:5 bits
32 dst[7] = Base32EncodeChar((src[4] << 0) & 0x1F);
35 // -- Class methods
37 cmBase32Encoder::cmBase32Encoder() = default;
39 std::string cmBase32Encoder::encodeString(const unsigned char* input,
40 size_t len, bool padding)
42 std::string res;
44 static const size_t blockSize = 5;
45 static const size_t bufferSize = 8;
46 char buffer[bufferSize];
48 const unsigned char* end = input + len;
49 while ((input + blockSize) <= end) {
50 Base32Encode5(input, buffer);
51 res.append(buffer, bufferSize);
52 input += blockSize;
55 size_t remain = static_cast<size_t>(end - input);
56 if (remain != 0) {
57 // Temporary source buffer filled up with 0s
58 unsigned char extended[blockSize];
59 for (size_t ii = 0; ii != remain; ++ii) {
60 extended[ii] = input[ii];
62 for (size_t ii = remain; ii != blockSize; ++ii) {
63 extended[ii] = 0;
66 Base32Encode5(extended, buffer);
67 size_t numPad(0);
68 switch (remain) {
69 case 1:
70 numPad = 6;
71 break;
72 case 2:
73 numPad = 4;
74 break;
75 case 3:
76 numPad = 3;
77 break;
78 case 4:
79 numPad = 1;
80 break;
81 default:
82 break;
84 res.append(buffer, bufferSize - numPad);
85 if (padding) {
86 for (size_t ii = 0; ii != numPad; ++ii) {
87 res.push_back(paddingChar);
92 return res;