110 const std::uint8_t* in =
reinterpret_cast<const std::uint8_t*
>(data);
111 const std::uint8_t* in_end = in + size;
116 out.reserve(size * 3 / 4);
118 static constexpr std::uint8_t ex = 255;
119 static constexpr std::uint8_t ws = 254;
121 static const std::uint8_t decoding64[256] = {
122 ex, ex, ex, ex, ex, ex, ex, ex, ex, ws, ws, ex, ex, ws, ex, ex,
123 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
124 ws, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, 62, ex, ex, ex, 63,
125 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, ex, ex, ex, ws, ex, ex,
126 ex, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
127 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, ex, ex, ex, ex, ex,
128 ex, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
129 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, ex, ex, ex, ex, ex,
130 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
131 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
132 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
133 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
134 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
135 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
136 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex,
137 ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex, ex
140 std::uint8_t outchar, fragment;
142 static const char* ex_message =
143 "Invalid character encountered during base64 decoding.";
149 if (in == in_end)
return out;
151 fragment = decoding64[*in++];
153 if (fragment == ex && strict)
154 throw std::runtime_error(ex_message);
155 }
while (fragment >= ws);
157 outchar =
static_cast<std::uint8_t
>((fragment & 0x3F) << 2);
161 if (in == in_end)
return out;
163 fragment = decoding64[*in++];
165 if (fragment == ex && strict)
166 throw std::runtime_error(ex_message);
167 }
while (fragment >= ws);
169 outchar =
static_cast<std::uint8_t
>(outchar | ((fragment & 0x30) >> 4));
170 out +=
static_cast<char>(outchar);
172 outchar =
static_cast<std::uint8_t
>((fragment & 0x0F) << 4);
176 if (in == in_end)
return out;
178 fragment = decoding64[*in++];
180 if (fragment == ex && strict)
181 throw std::runtime_error(ex_message);
182 }
while (fragment >= ws);
184 outchar =
static_cast<std::uint8_t
>(outchar | ((fragment & 0x3C) >> 2));
185 out +=
static_cast<char>(outchar);
187 outchar =
static_cast<std::uint8_t
>((fragment & 0x03) << 6);
191 if (in == in_end)
return out;
193 fragment = decoding64[*in++];
195 if (fragment == ex && strict)
196 throw std::runtime_error(ex_message);
197 }
while (fragment >= ws);
199 outchar =
static_cast<std::uint8_t
>(outchar | ((fragment & 0x3F) >> 0));
200 out +=
static_cast<char>(outchar);