28#ifndef ETL_BASE64_DECODER_INCLUDED
29#define ETL_BASE64_DECODER_INCLUDED
40#include "static_assert.h"
51#define ETL_IS_8_BIT_INTEGRAL(Type) \
52 (etl::is_integral<typename etl::remove_cv<Type>::type>::value && (etl::integral_limits<typename etl::remove_cv<Type>::type>::bits == 8U))
54#define ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(Type) \
55 (etl::is_integral< typename etl::iterator_traits< typename etl::remove_cv<Type>::type>::value_type>::value \
56 && (etl::integral_limits< typename etl::iterator_traits< typename etl::remove_cv<Type>::type>::value_type>::bits == 8U))
76 ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(T),
"Input type must be an 8 bit integral");
78 push_to_input_buffer(value);
80 if (input_buffer_is_full())
84 if (callback.is_valid())
86 if (output_buffer_is_full())
89 reset_output_buffer();
103 template <
typename TInputIterator>
104 ETL_CONSTEXPR14
bool decode(TInputIterator input_begin, TInputIterator input_end)
106 ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator),
"Input type must be an 8 bit integral");
108 while (input_begin != input_end)
110 if (!
decode(*input_begin++))
122 template <
typename TInputIterator>
123 ETL_CONSTEXPR14
bool decode(TInputIterator input_begin,
size_t input_length)
125 ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator),
"Input type must be an 8 bit integral");
127 while (input_length-- != 0)
129 if (!
decode(*input_begin++))
141 template <
typename TInputIterator>
142 ETL_CONSTEXPR14
bool decode_final(TInputIterator input_begin, TInputIterator input_end)
150 template <
typename TInputIterator>
151 ETL_CONSTEXPR14
bool decode_final(TInputIterator input_begin,
size_t input_length)
153 return decode(input_begin, input_length) &&
flush();
162 bool success = decode_block();
164 reset_input_buffer();
168 if (callback.is_valid())
177 callback(span_type());
179 reset_output_buffer();
183 padding_received =
false;
193 reset_input_buffer();
194 reset_output_buffer();
195 overflow_detected =
false;
196 invalid_data_detected =
false;
197 padding_received =
false;
203 ETL_NODISCARD ETL_CONSTEXPR14
const unsigned char*
begin()
const
205 return p_output_buffer;
212 ETL_NODISCARD ETL_CONSTEXPR14
const unsigned char*
end()
const
214 return p_output_buffer + output_buffer_length;
220 ETL_NODISCARD ETL_CONSTEXPR14
const unsigned char*
cbegin()
const
222 return p_output_buffer;
229 ETL_NODISCARD ETL_CONSTEXPR14
const unsigned char*
cend()
const
231 return p_output_buffer + output_buffer_length;
239 ETL_NODISCARD ETL_CONSTEXPR14
size_t size()
const
241 return output_buffer_length;
249 return output_buffer_max_size;
257 ETL_NODISCARD ETL_CONSTEXPR14 span_type
span()
const
265 ETL_NODISCARD ETL_CONSTEXPR14
bool overflow()
const
267 return overflow_detected;
275 return invalid_data_detected;
281 ETL_NODISCARD ETL_CONSTEXPR14
bool error()
const
291 ETL_CONSTEXPR14
ibase64_decoder(
const char* encoder_table_,
bool use_padding_,
unsigned char* p_output_buffer_,
size_t ouput_buffer_max_size_,
292 callback_type callback_)
293 : base64(encoder_table_, use_padding_)
295 , input_buffer_length(0)
296 , p_output_buffer(p_output_buffer_)
297 , output_buffer_length(0)
298 , output_buffer_max_size(ouput_buffer_max_size_)
299 , callback(callback_)
300 , overflow_detected(false)
301 , invalid_data_detected(false)
302 , padding_received(false)
312 return input_length - (input_length / 4U);
320 template <
typename T>
321 ETL_CONSTEXPR14 uint32_t get_index_from_sextet(T sextet)
323 const char* encoder_table_end = encoder_table + 64;
324 const char* p_sextet = etl::find(encoder_table, encoder_table_end,
static_cast<char>(sextet));
326 if (p_sextet != encoder_table_end)
328 return static_cast<uint32_t
>(etl::distance(encoder_table, p_sextet));
332 invalid_data_detected =
true;
340 template <
typename T>
343 ETL_CONSTEXPR14 T padding()
345 return static_cast<T
>(
'=');
351 ETL_CONSTEXPR14
bool decode_block()
353 switch (input_buffer_length)
358 uint32_t sextets = (get_index_from_sextet(input_buffer[0]) << 6);
359 sextets = sextets | (get_index_from_sextet(input_buffer[1]));
360 push_to_output_buffer((sextets >> 4) & 0xFF);
367 uint32_t sextets = (get_index_from_sextet(input_buffer[0]) << 12);
368 sextets = sextets | (get_index_from_sextet(input_buffer[1]) << 6);
369 sextets = sextets | (get_index_from_sextet(input_buffer[2]));
370 push_to_output_buffer((sextets >> 10) & 0xFF);
371 push_to_output_buffer((sextets >> 2) & 0xFF);
379 uint32_t sextets = (get_index_from_sextet(input_buffer[0]) << 18);
380 sextets = sextets | (get_index_from_sextet(input_buffer[1]) << 12);
381 sextets = sextets | (get_index_from_sextet(input_buffer[2]) << 6);
382 sextets = sextets | (get_index_from_sextet(input_buffer[3]));
385 push_to_output_buffer((sextets >> 16) & 0xFF);
386 push_to_output_buffer((sextets >> 8) & 0xFF);
387 push_to_output_buffer((sextets >> 0) & 0xFF);
397 ETL_ASSERT(!invalid_data_detected, ETL_ERROR(etl::base64_invalid_data));
398 ETL_ASSERT(!overflow_detected, ETL_ERROR(etl::base64_overflow));
400 return (!invalid_data_detected && !overflow_detected);
406 ETL_CONSTEXPR14
void push_to_output_buffer(
unsigned char c)
408 if (output_buffer_length < output_buffer_max_size)
410 p_output_buffer[output_buffer_length++] = c;
414 overflow_detected =
true;
421 ETL_CONSTEXPR14
bool output_buffer_is_full()
const
423 return output_buffer_length == output_buffer_max_size;
429 ETL_CONSTEXPR14
bool output_buffer_is_empty()
const
431 return output_buffer_length == 0;
437 ETL_CONSTEXPR14
void reset_output_buffer()
439 output_buffer_length = 0;
445 template <
typename T>
446 ETL_CONSTEXPR14
void push_to_input_buffer(T value)
448 if (value == padding<T>())
450 padding_received =
true;
454 if (padding_received)
456 ETL_ASSERT_FAIL(ETL_ERROR(etl::base64_invalid_data));
457 invalid_data_detected =
true;
461 input_buffer[input_buffer_length++] =
static_cast<char>(value);
469 ETL_CONSTEXPR14
bool input_buffer_is_full()
const
471 return input_buffer_length == 4U;
477 ETL_CONSTEXPR14
void reset_input_buffer()
479 input_buffer_length = 0;
482 char input_buffer[4];
483 size_t input_buffer_length;
485 unsigned char* p_output_buffer;
486 size_t output_buffer_length;
487 const size_t output_buffer_max_size;
489 callback_type callback;
491 bool overflow_detected;
492 bool invalid_data_detected;
493 bool padding_received;
499 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
504 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
537 unsigned char output_buffer[Buffer_Size];
543 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
548 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
581 unsigned char output_buffer[Buffer_Size];
587 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
592 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
625 unsigned char output_buffer[Buffer_Size];
631 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
636 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
669 unsigned char output_buffer[Buffer_Size];
675 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
680 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
713 unsigned char output_buffer[Buffer_Size];
719 template <
size_t Buffer_Size = etl::base64::Min_Decode_Buffer_Size>
724 ETL_STATIC_ASSERT((Buffer_Size >= etl::base64::Min_Decode_Buffer_Size),
"Buffer size must be greater than etl::base64::Min_Decode_Buffer_Size");
757 unsigned char output_buffer[Buffer_Size];
761#undef ETL_IS_TYPE_8_BIT_INTEGRAL
762#undef ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL
ETL_CONSTEXPR14 base64_rfc2152_decoder()
Base64 RFC-2152 constructor.
Definition base64_decoder.h:509
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:529
ETL_CONSTEXPR14 base64_rfc2152_decoder(callback_type callback_)
Base64 RFC-2152 constructor.
Definition base64_decoder.h:518
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:573
ETL_CONSTEXPR14 base64_rfc3501_decoder()
Base64 RFC-3501 constructor.
Definition base64_decoder.h:553
ETL_CONSTEXPR14 base64_rfc3501_decoder(callback_type callback_)
Base64 RFC-3501 constructor.
Definition base64_decoder.h:562
ETL_CONSTEXPR14 base64_rfc4648_decoder(callback_type callback_)
Base64 RFC-4648 constructor.
Definition base64_decoder.h:606
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:617
ETL_CONSTEXPR14 base64_rfc4648_decoder()
Base64 RFC-4648 constructor.
Definition base64_decoder.h:597
ETL_CONSTEXPR14 base64_rfc4648_padding_decoder(callback_type callback_)
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:650
ETL_CONSTEXPR14 base64_rfc4648_padding_decoder()
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:641
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:661
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:705
ETL_CONSTEXPR14 base64_rfc4648_url_decoder()
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:685
ETL_CONSTEXPR14 base64_rfc4648_url_decoder(callback_type callback_)
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:694
ETL_CONSTEXPR14 base64_rfc4648_url_padding_decoder()
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:729
static ETL_NODISCARD ETL_CONSTEXPR14 size_t safe_output_buffer_size(size_t input_length)
Calculate the required output encode buffer size.
Definition base64_decoder.h:749
ETL_CONSTEXPR14 base64_rfc4648_url_padding_decoder(callback_type callback_)
Base64 RFC-4648-Padding constructor.
Definition base64_decoder.h:738
Common Base64 definitions.
Definition base64.h:112
Declaration.
Definition delegate_cpp03.h:191
ETL_NODISCARD ETL_CONSTEXPR14 size_t buffer_size() const
Returns the maximum size of the output buffer.
Definition base64_decoder.h:247
ETL_NODISCARD ETL_CONSTEXPR14 const unsigned char * end() const
Definition base64_decoder.h:212
ETL_CONSTEXPR14 bool decode(TInputIterator input_begin, size_t input_length)
Decode from Base64.
Definition base64_decoder.h:123
ETL_NODISCARD ETL_CONSTEXPR14 const unsigned char * cbegin() const
Returns the beginning of the output buffer.
Definition base64_decoder.h:220
ETL_NODISCARD ETL_CONSTEXPR14 span_type span() const
Definition base64_decoder.h:257
ETL_CONSTEXPR14 ibase64_decoder(const char *encoder_table_, bool use_padding_, unsigned char *p_output_buffer_, size_t ouput_buffer_max_size_, callback_type callback_)
Constructor.
Definition base64_decoder.h:291
ETL_NODISCARD ETL_CONSTEXPR14 size_t size() const
Definition base64_decoder.h:239
ETL_NODISCARD ETL_CONSTEXPR14 const unsigned char * cend() const
Definition base64_decoder.h:229
ETL_CONSTEXPR14 bool decode_final(TInputIterator input_begin, size_t input_length)
Decode from Base64.
Definition base64_decoder.h:151
ETL_CONSTEXPR14 bool flush()
Flush any remaining data to the output.
Definition base64_decoder.h:159
static ETL_NODISCARD ETL_CONSTEXPR14 size_t decoded_size_from_valid_input_length(size_t input_length)
Calculates the minimum buffer size required to decode from Base64.
Definition base64_decoder.h:310
ETL_CONSTEXPR14 bool decode(T value)
Decode to Base64.
Definition base64_decoder.h:74
ETL_NODISCARD ETL_CONSTEXPR14 bool error() const
Returns true if an error was detected.
Definition base64_decoder.h:281
ETL_NODISCARD ETL_CONSTEXPR14 bool overflow() const
Returns true if the output buffer has overflowed.
Definition base64_decoder.h:265
ETL_CONSTEXPR14 void restart()
Reset the encoder.
Definition base64_decoder.h:191
ETL_CONSTEXPR14 bool decode_final(TInputIterator input_begin, TInputIterator input_end)
Decode from Base64.
Definition base64_decoder.h:142
ETL_NODISCARD ETL_CONSTEXPR14 const unsigned char * begin() const
Returns the beginning of the output buffer.
Definition base64_decoder.h:203
ETL_NODISCARD ETL_CONSTEXPR14 bool invalid_data() const
Returns true if an invalid character was detected.
Definition base64_decoder.h:273
ETL_CONSTEXPR14 bool decode(TInputIterator input_begin, TInputIterator input_end)
Decode from Base64.
Definition base64_decoder.h:104
Span - Fixed Extent.
Definition span.h:208
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
bitset_ext
Definition absolute.h:40