4
Copyright (C) 2004-2008 René Nyffenegger
6
This source code is provided 'as-is', without any express or implied
7
warranty. In no event will the author be held liable for any damages
8
arising from the use of this software.
10
Permission is granted to anyone to use this software for any purpose,
11
including commercial applications, and to alter it and redistribute it
12
freely, subject to the following restrictions:
14
1. The origin of this source code must not be misrepresented; you must not
15
claim that you wrote the original source code. If you use this source code
16
in a product, an acknowledgment in the product documentation would be
17
appreciated but is not required.
19
2. Altered source versions must be plainly marked as such, and must not be
20
misrepresented as being the original source code.
22
3. This notice may not be removed or altered from any source distribution.
24
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
26
NOTICE: The source code here has been altered from the original to use a provided character buffer
27
rather than returning a new string for each call.
28
These modifications are Copyright (c) 2019 Zheng Lei (realthunder.dev@gmail.com)
31
#include "PreCompiled.h"
39
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic,
40
// cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers,
41
// readability-magic-numbers)
43
static const std::array<char, 65> base64_chars {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
44
"abcdefghijklmnopqrstuvwxyz"
48
std::array<const signed char, Base::base64DecodeTableSize> Base::base64_decode_table()
50
static std::array<const signed char, Base::base64DecodeTableSize> _table = {
51
-1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -1, -2, -1, -1, // 0-15
52
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
53
-2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
54
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, // 48-63
55
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
56
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
57
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
58
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
59
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
60
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
61
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
62
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
63
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
64
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
65
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
66
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
71
std::size_t Base::base64_encode(char* out, void const* in, std::size_t in_len)
74
auto const* bytes_to_encode = reinterpret_cast<unsigned char const*>(in); // NOLINT
77
std::array<unsigned char, 3> char_array_3 {};
78
std::array<unsigned char, 4> char_array_4 {};
80
while ((in_len--) != 0U) {
81
char_array_3[char3++] = *(bytes_to_encode++);
83
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
84
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
85
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
86
char_array_4[3] = char_array_3[2] & 0x3f;
88
for (char3 = 0; (char3 < 4); char3++) {
89
*ret++ = base64_chars[char_array_4[char3]];
96
for (char4 = char3; char4 < 3; char4++) {
97
char_array_3[char4] = '\0';
100
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
101
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
102
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
103
char_array_4[3] = char_array_3[2] & 0x3f;
105
for (char4 = 0; (char4 < char3 + 1); char4++) {
106
*ret++ = base64_chars[char_array_4[char4]];
109
while ((char3++ < 3)) {
117
std::pair<std::size_t, std::size_t>
118
Base::base64_decode(void* _out, char const* in, std::size_t in_len)
120
auto* out = reinterpret_cast<unsigned char*>(_out); // NOLINT
121
unsigned char* ret = out;
122
char const* input = in;
123
int byteCounter1 {0};
125
std::array<unsigned char, 4> char_array_4 {};
126
std::array<unsigned char, 3> char_array_3 {};
128
static auto table = base64_decode_table();
130
while (((in_len--) != 0U) && *in != '=') {
131
const signed char lookup = table[static_cast<unsigned char>(*in++)];
136
char_array_4[byteCounter1++] = (unsigned char)lookup;
137
if (byteCounter1 == 4) {
138
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
139
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
140
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
142
for (byteCounter1 = 0; (byteCounter1 < 3); byteCounter1++) {
143
*ret++ = char_array_3[byteCounter1];
149
if (byteCounter1 != 0) {
150
for (byteCounter2 = byteCounter1; byteCounter2 < 4; byteCounter2++) {
151
char_array_4[byteCounter2] = 0;
154
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
155
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
156
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
158
for (byteCounter2 = 0; (byteCounter2 < byteCounter1 - 1); byteCounter2++) {
159
*ret++ = char_array_3[byteCounter2];
163
return std::make_pair((std::size_t)(ret - out), (std::size_t)(in - input));
166
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic,
167
// cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers,
168
// readability-magic-numbers)