15#pragma GCC diagnostic push
16#pragma GCC diagnostic ignored "-Wunknown-pragmas"
22 inline const char base64_enc_lookup[64] = {
23 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
24 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
25 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
26 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'
29 inline const uint8_t base64_dec_lookup[256] = {
31 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
32 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
34 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
35 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
36 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
37 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
38 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
44 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
45 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
74 template<
class T,
class TR,
class AX>
75 void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_bytecount_(size)
const void *data, _In_
size_t size, _In_opt_
bool is_last =
true)
77 _Assume_(data || !size);
80 out.reserve(out.size() +
enc_size(size));
83 for (
size_t i = 0;; i++) {
92 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
96 if (is_last &&
m_num) {
119 return ((
m_num + size + 2)/3)*4;
126 template<
class T,
class TR,
class AX>
127 void encode(_Inout_ std::basic_string<T, TR, AX> &out)
129 out += base64_enc_lookup[
m_buf[0] >> 2 ];
130 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
131 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
132 out += base64_enc_lookup[
m_buf[2] & 0x3f];
138 template<
class T,
class TR,
class AX>
139 void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_
size_t size)
142 out += base64_enc_lookup[
m_buf[0] >> 2];
144 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
146 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
147 out += base64_enc_lookup[
m_buf[2] & 0x3f];
149 out += base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
153 out += base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
178 m_max_blocks(max_blocks),
194 virtual _Success_(
return != 0) size_t
write(
195 _In_reads_bytes_opt_(length) const
void* data, _In_
size_t length)
197 _Assume_(data || !length);
198 for (
size_t i = 0;; i++) {
205 if (!m_source->
ok()) _Unlikely_ {
206 m_state = m_source->
state();
212 m_state = stdex::stream::state_t::ok;
215 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
226 out[0] = base64_enc_lookup[
m_buf[0] >> 2 ];
227 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
228 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
229 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
230 m_source->
write_array(out,
sizeof(*out), _countof(out));
240 out[0] = base64_enc_lookup[
m_buf[0] >> 2];
242 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
244 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
245 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
247 out[2] = base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
251 out[1] = base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
261 m_source->
write_array(out,
sizeof(*out), _countof(out));
295 template<
class T_to,
class AX,
class T_from>
296 void decode(_Inout_ std::vector<T_to, AX> &out, _Out_
bool &is_last, _In_z_count_(size)
const T_from *data, _In_
size_t size)
301 for (
size_t k = 0; k < size; k++)
302 if (!data[k]) { size = k;
break; }
305 out.reserve(out.size() +
dec_size(size));
307 for (
size_t i = 0;; i++) {
310 size_t nibbles =
decode(out);
320 size_t x =
static_cast<size_t>(data[i]);
322 if ((
m_buf[
m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
344 return ((
m_num + size + 3)/4)*3;
351 template<
class T,
class AX>
352 size_t decode(_Inout_ std::vector<T, AX> &out)
355 out.push_back((T)(((
m_buf[0] << 2) | (
m_buf[1] >> 4)) & 0xff));
357 out.push_back((T)(((
m_buf[1] << 4) | (
m_buf[2] >> 2)) & 0xff));
359 out.push_back((T)(((
m_buf[2] << 6) |
m_buf[3]) & 0xff));
373#pragma warning(disable: 26495)
387#pragma warning(suppress: 6101)
388 virtual _Success_(
return != 0 || length == 0) size_t
read(
389 _Out_writes_bytes_to_opt_(length, return)
void* data, _In_
size_t length)
391 _Assume_(data || !length);
392 for (
size_t to_read = length;;) {
397 m_state = stdex::stream::state_t::ok;
402 reinterpret_cast<uint8_t*&
>(data) +=
m_temp_len;
411 if (!m_source->
ok()) _Unlikely_ {
412 m_state = m_source->
state();
413 return length - to_read;
415 if ((
m_buf[
m_num] = base64_dec_lookup[x]) != 255)
425 m_state = stdex::stream::state_t::ok;
426 return length - to_read;
462#pragma GCC diagnostic pop
Base64 decoding session.
Definition base64.hpp:274
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:369
size_t decode(std::vector< T, AX > &out)
Decodes one complete internal buffer of data.
Definition base64.hpp:352
base64_dec() noexcept
Constructs blank decoding session.
Definition base64.hpp:279
size_t dec_size(size_t size) const noexcept
Returns maximum decoded size.
Definition base64.hpp:342
void clear() noexcept
Resets decoding session.
Definition base64.hpp:330
void decode(std::vector< T_to, AX > &out, bool &is_last, const T_from *data, size_t size)
Decodes one block of information, and appends it to the output.
Definition base64.hpp:296
uint8_t m_buf[4]
Internal buffer.
Definition base64.hpp:368
Base64 encoding session.
Definition base64.hpp:54
void encode(std::basic_string< T, TR, AX > &out, size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:139
void encode(std::basic_string< T, TR, AX > &out)
Encodes one complete internal buffer of data.
Definition base64.hpp:127
void encode(std::basic_string< T, TR, AX > &out, const void *data, size_t size, bool is_last=true)
Encodes one block of information, and appends it to the output.
Definition base64.hpp:75
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:167
uint8_t m_buf[3]
Internal buffer.
Definition base64.hpp:166
base64_enc() noexcept
Constructs blank encoding session.
Definition base64.hpp:59
void clear() noexcept
Resets encoding session.
Definition base64.hpp:105
size_t enc_size(size_t size) const noexcept
Returns maximum encoded size.
Definition base64.hpp:117
Converts from Base64 when reading from a stream.
Definition base64.hpp:379
void decode()
Decodes one complete internal buffer of data.
Definition base64.hpp:435
char m_temp[3]
Temporary buffer.
Definition base64.hpp:452
size_t m_temp_len
Number of bytes of data in m_temp
Definition base64.hpp:455
virtual size_t read(_Out_writes_bytes_to_opt_(length, return) void *data, size_t length)
Reads block of data from the stream.
Definition base64.hpp:388
size_t m_temp_off
Index of data start in m_temp
Definition base64.hpp:454
Converts to Base64 when writing to a stream.
Definition base64.hpp:174
size_t m_num_blocks
Maximum number of Base64 blocks (4 chars) to write without a line break (SIZE_MAX no line breaks)
Definition base64.hpp:267
void encode()
Encodes one complete internal buffer of data.
Definition base64.hpp:223
void encode(size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:236
virtual size_t write(_In_reads_bytes_opt_(length) const void *data, size_t length)
Writes block of data to the stream.
Definition base64.hpp:194
UTF-8 byte-order-mark
Definition stream.hpp:84
bool ok() const
Returns true if the stream state is clean i.e. previous operation was successful.
Definition stream.hpp:180
state_t state() const
Returns stream state after last operation.
Definition stream.hpp:175
size_t write_array(_In_reads_bytes_opt_(size *count) const void *array, size_t size, size_t count)
Writes an array of data to the stream.
Definition stream.hpp:393
Modifies data on the fly when reading from/writing to a source stream. Could also be used to modify r...
Definition stream.hpp:1022