21 const char base64_enc_lookup[64] = {
22 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
23 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
24 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
25 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'
31 const uint8_t base64_dec_lookup[256] = {
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 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, 62, 255, 255, 255, 63,
36 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
37 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
38 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
39 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
40 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 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,
47 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
76 template<
class _Elem,
class _Traits,
class _Ax>
77 void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size)
const void *data, _In_
size_t size, _In_opt_
bool is_last =
true)
79 _Assume_(data || !size);
82 out.reserve(out.size() +
enc_size(size));
85 for (
size_t i = 0;; i++) {
94 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
98 if (is_last &&
m_num) {
121 return ((
m_num + size + 2)/3)*4;
128 template<
class _Elem,
class _Traits,
class _Ax>
129 void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out)
131 out += base64_enc_lookup[
m_buf[0] >> 2 ];
132 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
133 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
134 out += base64_enc_lookup[
m_buf[2] & 0x3f];
140 template<
class _Elem,
class _Traits,
class _Ax>
141 void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_
size_t size)
144 out += base64_enc_lookup[
m_buf[0] >> 2];
146 out += base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
148 out += base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
149 out += base64_enc_lookup[
m_buf[2] & 0x3f];
151 out += base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
155 out += base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
180 m_max_blocks(max_blocks),
196 virtual _Success_(
return != 0) size_t
write(
197 _In_reads_bytes_opt_(length) const
void* data, _In_
size_t length)
199 _Assume_(data || !length);
200 for (
size_t i = 0;; i++) {
207 if (!m_source->
ok()) _Unlikely_ {
208 m_state = m_source->
state();
214 m_state = stdex::stream::state_t::ok;
217 m_buf[
m_num++] =
reinterpret_cast<const uint8_t*
>(data)[i];
228 out[0] = base64_enc_lookup[
m_buf[0] >> 2 ];
229 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
230 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
231 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
232 m_source->
write_array(out,
sizeof(*out), _countof(out));
242 out[0] = base64_enc_lookup[
m_buf[0] >> 2];
244 out[1] = base64_enc_lookup[((
m_buf[0] << 4) | (
m_buf[1] >> 4)) & 0x3f];
246 out[2] = base64_enc_lookup[((
m_buf[1] << 2) | (
m_buf[2] >> 6)) & 0x3f];
247 out[3] = base64_enc_lookup[
m_buf[2] & 0x3f];
249 out[2] = base64_enc_lookup[(
m_buf[1] << 2) & 0x3f];
253 out[1] = base64_enc_lookup[(
m_buf[0] << 4) & 0x3f];
263 m_source->
write_array(out,
sizeof(*out), _countof(out));
297 template<
class _Ty,
class _Ax,
class _Tchr>
298 void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_
bool &is_last, _In_z_count_(size)
const _Tchr *data, _In_
size_t size)
303 for (
size_t k = 0; k < size; k++)
304 if (!data[k]) { size = k;
break; }
307 out.reserve(out.size() +
dec_size(size));
309 for (
size_t i = 0;; i++) {
312 size_t nibbles =
decode(out);
323 if ((
m_buf[
m_num] = x < _countof(base64_dec_lookup) ? base64_dec_lookup[x] : 255) != 255)
345 return ((
m_num + size + 3)/4)*3;
352 template<
class _Ty,
class _Ax>
353 size_t decode(_Inout_ std::vector<_Ty, _Ax> &out)
356 out.push_back((_Ty)(((
m_buf[0] << 2) | (
m_buf[1] >> 4)) & 0xff));
358 out.push_back((_Ty)(((
m_buf[1] << 4) | (
m_buf[2] >> 2)) & 0xff));
360 out.push_back((_Ty)(((
m_buf[2] << 6) |
m_buf[3]) & 0xff));
375#pragma warning(disable: 26495)
390#pragma warning(suppress: 6101)
391 virtual _Success_(
return != 0 || length == 0) size_t
read(
392 _Out_writes_bytes_to_opt_(length, return)
void* data, _In_
size_t length)
394 _Assume_(data || !length);
395 for (
size_t to_read = length;;) {
400 m_state = stdex::stream::state_t::ok;
405 reinterpret_cast<uint8_t*&
>(data) +=
m_temp_len;
414 if (!m_source->
ok()) _Unlikely_ {
415 m_state = m_source->
state();
416 return length - to_read;
418 if ((
m_buf[
m_num] = base64_dec_lookup[x]) != 255)
422 if (m_temp_len < 3 && to_read >= 3) {
428 m_state = stdex::stream::state_t::ok;
429 return length - to_read;
Base64 decoding session.
Definition base64.hpp:276
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:370
base64_dec() noexcept
Constructs blank decoding session.
Definition base64.hpp:281
void decode(std::vector< _Ty, _Ax > &out, bool &is_last, const _Tchr *data, size_t size)
Decodes one block of information, and appends it to the output.
Definition base64.hpp:298
size_t dec_size(size_t size) const noexcept
Returns maximum decoded size.
Definition base64.hpp:343
size_t decode(std::vector< _Ty, _Ax > &out)
Decodes one complete internal buffer of data.
Definition base64.hpp:353
void clear() noexcept
Resets decoding session.
Definition base64.hpp:331
uint8_t m_buf[4]
Internal buffer.
Definition base64.hpp:369
Base64 encoding session.
Definition base64.hpp:56
void encode(std::basic_string< _Elem, _Traits, _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:77
void encode(std::basic_string< _Elem, _Traits, _Ax > &out)
Encodes one complete internal buffer of data.
Definition base64.hpp:129
size_t m_num
Number of bytes used in m_buf
Definition base64.hpp:169
uint8_t m_buf[3]
Internal buffer.
Definition base64.hpp:168
void encode(std::basic_string< _Elem, _Traits, _Ax > &out, size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:141
base64_enc() noexcept
Constructs blank encoding session.
Definition base64.hpp:61
void clear() noexcept
Resets encoding session.
Definition base64.hpp:107
size_t enc_size(size_t size) const noexcept
Returns maximum encoded size.
Definition base64.hpp:119
Converts from Base64 when reading from a stream.
Definition base64.hpp:382
void decode()
Decodes one complete internal buffer of data.
Definition base64.hpp:438
char m_temp[3]
Temporary buffer.
Definition base64.hpp:455
size_t m_temp_len
Number of bytes of data in m_temp
Definition base64.hpp:458
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:391
size_t m_temp_off
Index of data start in m_temp
Definition base64.hpp:457
Converts to Base64 when writing to a stream.
Definition base64.hpp:176
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:269
void encode()
Encodes one complete internal buffer of data.
Definition base64.hpp:225
void encode(size_t size)
Encodes partial internal buffer of data.
Definition base64.hpp:238
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:196
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:400
Modifies data on the fly when reading from/writing to a source stream. Could also be used to modify r...
Definition stream.hpp:1022