17 inline const char base64_enc_lookup[64] = {
18 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
19 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
20 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
21 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'
24 inline const uint8_t base64_dec_lookup[256] = {
26 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
27 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
28 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
29 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
30 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
31 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
32 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
33 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
34 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 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
69 template<
class T,
class TR,
class AX>
70 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)
72 _Assume_(data || !size);
75 out.reserve(out.size() +
enc_size(size));
78 for (
size_t i = 0;; i++) {
87 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
91 if (is_last &&
m_num) {
114 return ((
m_num + size + 2)/3)*4;
121 template<
class T,
class TR,
class AX>
122 void encode(_Inout_ std::basic_string<T, TR, AX> &out)
124 out += base64_enc_lookup[
m_buf[0] >> 2 ];
125 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
126 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
127 out += base64_enc_lookup[
m_buf[2] & 0x3f];
133 template<
class T,
class TR,
class AX>
134 void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_
size_t size)
137 out += base64_enc_lookup[
m_buf[0] >> 2];
139 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
141 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
142 out += base64_enc_lookup[
m_buf[2] & 0x3f];
144 out += base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
148 out += base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
173 m_max_blocks(max_blocks),
189 virtual _Success_(
return != 0) size_t
write(
190 _In_reads_bytes_opt_(length) const
void* data, _In_
size_t length)
192 _Assume_(data || !length);
193 for (
size_t i = 0;; i++) {
200 if (!m_source->
ok()) _Unlikely_ {
201 m_state = m_source->
state();
207 m_state = stdex::stream::state_t::ok;
210 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
221 out[0] = base64_enc_lookup[
m_buf[0] >> 2 ];
222 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
223 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
224 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
225 m_source->
write_array(out,
sizeof(*out), _countof(out));
235 out[0] = base64_enc_lookup[
m_buf[0] >> 2];
237 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
239 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
240 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
242 out[2] = base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
246 out[1] = base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
256 m_source->
write_array(out,
sizeof(*out), _countof(out));
290 template<
class T_to,
class AX,
class T_from>
291 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)
296 for (
size_t k = 0; k < size; k++)
297 if (!data[k]) { size = k;
break; }
300 out.reserve(out.size() +
dec_size(size));
302 for (
size_t i = 0;; i++) {
305 size_t nibbles =
decode(out);
316 if ((
m_buf[
m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
338 return ((
m_num + size + 3)/4)*3;
345 template<
class T,
class AX>
346 size_t decode(_Inout_ std::vector<T, AX> &out)
349 out.push_back((T)(((
m_buf[0] << 2) | (
m_buf[1] >> 4)) & 0xff));
351 out.push_back((T)(((
m_buf[1] << 4) | (
m_buf[2] >> 2)) & 0xff));
353 out.push_back((T)(((
m_buf[2] << 6) |
m_buf[3]) & 0xff));
368#pragma warning(disable: 26495)
383#pragma warning(suppress: 6101)
384 virtual _Success_(
return != 0 || length == 0) size_t
read(
385 _Out_writes_bytes_to_opt_(length, return)
void* data, _In_
size_t length)
387 _Assume_(data || !length);
388 for (
size_t to_read = length;;) {
393 m_state = stdex::stream::state_t::ok;
398 reinterpret_cast<uint8_t*&
>(data) +=
m_temp_len;
407 if (!m_source->
ok()) _Unlikely_ {
408 m_state = m_source->
state();
409 return length - to_read;
411 if ((
m_buf[
m_num] = base64_dec_lookup[x]) != 255)
415 if (m_temp_len < 3 && to_read >= 3) {
421 m_state = stdex::stream::state_t::ok;
422 return length - to_read;
Base64 decoding session.
Definition base64.hpp:269
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:363
size_t decode(std::vector< T, AX > &out)
Decodes one complete internal buffer of data.
Definition base64.hpp:346
base64_dec() noexcept
Constructs blank decoding session.
Definition base64.hpp:274
size_t dec_size(size_t size) const noexcept
Returns maximum decoded size.
Definition base64.hpp:336
void clear() noexcept
Resets decoding session.
Definition base64.hpp:324
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:291
uint8_t m_buf[4]
Internal buffer.
Definition base64.hpp:362
Base64 encoding session.
Definition base64.hpp:49
void encode(std::basic_string< T, TR, AX > &out, size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:134
void encode(std::basic_string< T, TR, AX > &out)
Encodes one complete internal buffer of data.
Definition base64.hpp:122
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:70
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:162
uint8_t m_buf[3]
Internal buffer.
Definition base64.hpp:161
base64_enc() noexcept
Constructs blank encoding session.
Definition base64.hpp:54
void clear() noexcept
Resets encoding session.
Definition base64.hpp:100
size_t enc_size(size_t size) const noexcept
Returns maximum encoded size.
Definition base64.hpp:112
Converts from Base64 when reading from a stream.
Definition base64.hpp:375
void decode()
Decodes one complete internal buffer of data.
Definition base64.hpp:431
char m_temp[3]
Temporary buffer.
Definition base64.hpp:448
size_t m_temp_len
Number of bytes of data in m_temp
Definition base64.hpp:451
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:384
size_t m_temp_off
Index of data start in m_temp
Definition base64.hpp:450
Converts to Base64 when writing to a stream.
Definition base64.hpp:169
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:262
void encode()
Encodes one complete internal buffer of data.
Definition base64.hpp:218
void encode(size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:231
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:189
UTF-8 byte-order-mark
Definition stream.hpp:79
bool ok() const
Returns true if the stream state is clean i.e. previous operation was succesful.
Definition stream.hpp:175
state_t state() const
Returns stream state after last operation.
Definition stream.hpp:170
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:388
Modifies data on the fly when reading from/writing to a source stream. Could also be used to modify r...
Definition stream.hpp:1012