From 211f872318964c1e8ea6473606fec86e1ec3ad82 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 14 Jun 2024 19:29:50 +0100 Subject: [PATCH] Refactored base64 encoder --- include/etl/base64.h | 40 +- include/etl/base64_encoder.h | 780 ++---------------- test/test_base64_RFC2152_encoder.cpp | 16 +- test/test_base64_RFC3501_encoder.cpp | 16 +- ...64_RFC4648_URL_encoder_with_no_padding.cpp | 16 +- ...ase64_RFC4648_URL_encoder_with_padding.cpp | 16 +- ...base64_RFC4648_encoder_with_no_padding.cpp | 16 +- ...st_base64_RFC4648_encoder_with_padding.cpp | 16 +- test/vs2022/etl.vcxproj | 2 + test/vs2022/etl.vcxproj.filters | 6 + 10 files changed, 155 insertions(+), 769 deletions(-) diff --git a/include/etl/base64.h b/include/etl/base64.h index 19e13d22..c80cfe51 100644 --- a/include/etl/base64.h +++ b/include/etl/base64.h @@ -125,9 +125,9 @@ namespace etl ETL_DECLARE_ENUM_TYPE(Encoding, int) //ETL_ENUM_TYPE(RFC_1421, "RFC_1421") // Not implemented yet //ETL_ENUM_TYPE(RFC_2045, "RFC_2045") // Not implemented yet - ETL_ENUM_TYPE(RFC_2152, "RFC_2152") - ETL_ENUM_TYPE(RFC_3501, "RFC_3501") - ETL_ENUM_TYPE(RFC_4648, "RFC_4648") + ETL_ENUM_TYPE(RFC_2152, "RFC_2152") + ETL_ENUM_TYPE(RFC_3501, "RFC_3501") + ETL_ENUM_TYPE(RFC_4648, "RFC_4648") ETL_ENUM_TYPE(RFC_4648_URL, "RFC_4648_URL") ETL_END_ENUM_TYPE }; @@ -163,37 +163,16 @@ namespace etl enum { Invalid_Data = etl::integral_limits::max, - Min_Buffer_Size = 4, + Min_Encode_Buffer_Size = 4, + Min_Decode_Buffer_Size = 3 }; - //************************************************************************* - /// Get the encoding standard - //************************************************************************* - ETL_NODISCARD - ETL_CONSTEXPR14 - Encoding get_encoding() const - { - return encoding; - } - - //************************************************************************* - /// Get the padding flag - //************************************************************************* - ETL_NODISCARD - ETL_CONSTEXPR14 - bool uses_padding() const - { - return use_padding; - } - protected: ETL_CONSTEXPR14 - base64(Encoding encoding_, - const char* encoder_table_, + base64(const char* encoder_table_, bool use_padding_) - : encoding(encoding_) - , encoder_table(encoder_table_) + : encoder_table(encoder_table_) , use_padding(use_padding_) { } @@ -228,9 +207,8 @@ namespace etl return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; } - const Encoding encoding; - const char* encoder_table; - const bool use_padding; + const char* encoder_table; + const bool use_padding; }; } #endif diff --git a/include/etl/base64_encoder.h b/include/etl/base64_encoder.h index f32909aa..fe458936 100644 --- a/include/etl/base64_encoder.h +++ b/include/etl/base64_encoder.h @@ -229,7 +229,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - size_t max_size() + size_t max_size() const { return output_buffer_max_size; } @@ -261,13 +261,12 @@ namespace etl /// Constructor //************************************************************************* ETL_CONSTEXPR14 - ibase64_encoder(Encoding encoding_, - const char* encoder_table_, + ibase64_encoder(const char* encoder_table_, bool use_padding_, char* p_output_buffer_, size_t ouput_buffer_max_size_, callback_type callback_) - : base64(encoding_, encoder_table_, use_padding_) + : base64(encoder_table_, use_padding_) , input_buffer() , input_buffer_length(0) , p_output_buffer(p_output_buffer_) @@ -466,706 +465,28 @@ namespace etl bool overflowed; }; - -// //************************************************************************* -// /// Base64 Decoder -// //************************************************************************* -// class ibase64_decoder : public base64 -// { -// public: -// -// //************************************************************************* -// /// Encode to Base64 -// /// Four parameter -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin, TOutputIterator output_end) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// const size_t input_length = static_cast(etl::distance(input_begin, input_end)); -// const size_t output_length = static_cast(etl::distance(output_begin, output_end)); -// -// // Figure out if the output buffer is large enough. -// size_t required_output_length = encoded_size(input_length, use_padding); -// ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U); -// -// return process_encode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Encode to Base64 -// /// For TOutputIterator value type not equal to void -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// const size_t input_length = static_cast(etl::distance(input_begin, input_end)); -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -// -// //************************************************************************* -// /// Encode to Base64 -// /// For etl::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, TInputIterator input_end, etl::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// const size_t input_length = static_cast(etl::distance(input_begin, input_end)); -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -// -//#if ETL_USING_STL -// //************************************************************************* -// /// Encode to Base64 -// /// For std::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, TInputIterator input_end, std::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// const size_t input_length = static_cast(etl::distance(input_begin, input_end)); -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -//#endif -// -// //************************************************************************* -// /// Encode to Base64 -// /// Four parameter -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin, size_t output_length) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// // Figure out if the output buffer is large enough. -// size_t required_output_length = encoded_size(input_length, use_padding); -// ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U); -// -// return process_encode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Encode to Base64 -// /// For TOutputIterator value_type not equal to void -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -// -// //************************************************************************* -// /// Encode to Base64 -// /// For etl::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, size_t input_length, etl::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -// -//#if ETL_USING_STL -// //************************************************************************* -// /// Encode to Base64 -// /// For std::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t encode(TInputIterator input_begin, size_t input_length, std::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// const size_t output_length = encoded_size(input_length, use_padding); -// -// return process_encode(input_begin, input_length, output_begin, output_length); -// } -//#endif -// -// //************************************************************************* -// /// Decode from Base64 -// /// Four parameter -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin, TOutputIterator output_end) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// const size_t input_length = valid_decode_input_length(input_begin, input_end, use_padding); -// const size_t output_length = static_cast(etl::distance(output_begin, output_end)); -// -// // Figure out if the output buffer is large enough. -// size_t required_output_length = decoded_size_from_valid_input_length(input_length); -// ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Decode from Base64 -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// const size_t input_length = valid_decode_input_length(input_begin, input_end, use_padding); -// -// // Find the length of the decoded output. -// const size_t required_output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Decode from Base64 -// /// For etl::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, TInputIterator input_end, etl::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// const size_t input_length = valid_decode_input_length(input_begin, input_end, use_padding); -// -// // Find the length of the decoded output. -// const size_t required_output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -// -//#if ETL_USING_STL -// //************************************************************************* -// /// Decode from Base64 -// /// For std::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, TInputIterator input_end, std::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// const size_t input_length = valid_decode_input_length(input_begin, input_end, use_padding); -// -// // Find the length of the decoded output. -// const size_t required_output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -//#endif -// -// //************************************************************************* -// /// Decode from Base64 -// /// Four parameter -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin, size_t output_length) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// input_length = valid_decode_input_length(input_begin, input_length, use_padding); -// -// // Figure out if the output buffer is large enough. -// size_t required_output_length = decoded_size_from_valid_input_length(input_length); -// ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Decode from Base64 -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TOutputIterator), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// input_length = valid_decode_input_length(input_begin, input_length, use_padding); -// -// // Find the length of the decoded output. -// const size_t required_output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, required_output_length); -// } -// -// //************************************************************************* -// /// Decode from Base64 -// /// For etl::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, size_t input_length, etl::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// input_length = valid_decode_input_length(input_begin, input_length, use_padding); -// -// // Find the length of the decoded output. -// const size_t output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, output_length); -// } -// -//#if ETL_USING_STL -// //************************************************************************* -// /// Decode from Base64 -// /// For std::back_insert_iterator -// /// Three parameter -// /// Assumes the output container is large enough. -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t decode(TInputIterator input_begin, size_t input_length, std::back_insert_iterator output_begin) -// { -// ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral"); -// ETL_STATIC_ASSERT(ETL_IS_8_BIT_INTEGRAL(typename TContainer::value_type), "Output type must be an 8 bit integral"); -// -// // Find the length of decodable characters. -// input_length = valid_decode_input_length(input_begin, input_length, use_padding); -// -// // Find the length of the decoded output. -// const size_t output_length = decoded_size_impl(input_begin, input_length, use_padding); -// -// return process_decode(input_begin, input_length, output_begin, output_length); -// } -//#endif -// -// protected: -// -// -// -// //************************************************************************* -// /// Calculates the minimum buffer size required to encode to Base64 -// //************************************************************************* -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t encoded_size(size_t input_length, Padding padding) -// { -// size_t required_output_length; -// -// if (input_length == 0U) -// { -// return 0U; -// } -// -// if (padding == Padding::Use_Padding) -// { -// required_output_length = (input_length * 4U) / 3U; -// -// while ((required_output_length % 4U) != 0) -// { -// ++required_output_length; -// } -// } -// else -// { -// required_output_length = input_length + (((input_length - 1U) / 3U) + 1U); -// } -// -// return required_output_length; -// } -// -// //************************************************************************* -// /// Discovers the number of valid decodable characters -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t valid_decode_input_length(TInputIterator input_begin, size_t input_length, bool use_padding) -// { -// if (input_length == 0U) -// { -// return 0U; -// } -// -// if (use_padding) -// { -// TInputIterator input_end = input_begin; -// -// if (input_length >= 2U) -// { -// // Jump forward to where padding characters possibly start. -// // There are never more than two padding characters. -// input_length -= 2U; -// etl::advance(input_end, input_length); -// } -// -// typedef typename etl::iterator_traits::value_type input_type; -// -// if (*input_end != padding()) -// { -// ++input_length; -// ++input_end; -// -// if (*input_end != padding()) -// { -// ++input_length; -// } -// } -// } -// -// // Not all input lengths are valid. -// ETL_ASSERT_OR_RETURN_VALUE((((input_length - 1U) % 4U) != 0U), ETL_ERROR(etl::base64_invalid_decode_input_length), 0U); -// -// return input_length; -// } -// -// //************************************************************************* -// /// Discovers the number of valid decodable characters -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t valid_decode_input_length(TInputIterator input_begin, TInputIterator input_end, bool use_padding) -// { -// return valid_decode_input_length(input_begin, static_cast(etl::distance(input_begin, input_end)), use_padding); -// } -// -// //************************************************************************* -// /// Calculates the minimum buffer size required to decode from Base64 -// //************************************************************************* -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t decoded_size_from_valid_input_length(size_t input_length) -// { -// if (input_length == 0U) -// { -// return 0U; -// } -// -// --input_length; -// return input_length - (input_length / 4U); -// } -// -// //************************************************************************* -// /// Calculates the minimum buffer size required to decode from Base64 -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t decoded_size_impl(TInputIterator input, size_t input_length, bool use_padding) -// { -// if (input_length == 0U) -// { -// return 0U; -// } -// -// input_length = valid_decode_input_length(input, input_length, use_padding); -// --input_length; -// return input_length - (input_length / 4U); -// } -// -// //************************************************************************* -// /// Calculates the minimum buffer size required to decode from Base64 -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// size_t decoded_size_impl(TInputIterator input_begin, TInputIterator input_end, bool use_padding) -// { -// return decoded_size_impl(static_cast(etl::distance(input_begin, input_end)), use_padding); -// } -// -// private: -// -// //************************************************************************* -// // Translates an index into a sextet -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// T get_sextet_from_index(int index) -// { -// return static_cast(p_lookup[index]); -// } -// -// //************************************************************************* -// // Translates a sextet into an index -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// uint32_t get_index_from_sextet(T sextet) -// { -// const char* p_lookup_end = p_lookup + 64; -// const char* p_sextet = etl::find(p_lookup, p_lookup_end, static_cast(sextet)); -// -// if (p_sextet != p_lookup_end) -// { -// return static_cast(etl::distance(p_lookup, p_sextet)); -// } -// else -// { -// ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(base64_invalid_character), 0); -// } -// } -// -// //************************************************************************* -// /// Gets the padding character -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// T padding() -// { -// return static_cast('='); -// } -// -// //************************************************************************* -// /// Is the character a carriage return? -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// bool is_carriage_return(T c) -// { -// return (static_cast(c) == '\r'); -// } -// -// //************************************************************************* -// /// Is the character a line break? -// //************************************************************************* -// template -// ETL_NODISCARD -// static -// ETL_CONSTEXPR14 -// bool is_line_feed(T c) -// { -// return (static_cast(c) == '\n'); -// } -// -// //************************************************************************* -// /// Encode to Base64 implementation -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t process_encode(TInputIterator input, size_t input_length, -// TOutputIterator output, size_t output_length) -// { -// if (input_length == 0U) -// { -// return 0; -// } -// -// // Count the actual number of sextets written. -// size_t output_count = 0; -// -// uint32_t octets = 0; -// -// // Read octet triplets and write sextet quartets -// while (input_length >= 3U) -// { -// // Read in three octets -// octets = (static_cast(static_cast(*input++)) << 16); -// octets = octets | (static_cast(static_cast(*input++)) << 8); -// octets = octets | static_cast(static_cast(*input++)); -// -// // Write out four sextets -// *output++ = get_sextet_from_index((octets >> 18) & b00111111); -// *output++ = get_sextet_from_index((octets >> 12) & b00111111); -// *output++ = get_sextet_from_index((octets >> 6) & b00111111); -// *output++ = get_sextet_from_index((octets >> 0) & b00111111); -// -// input_length -= 3U; -// output_count += 4U; -// } -// -// // Any input left? -// if (input_length > 0) -// { -// // Write out any remaining sextets -// if (input_length == 1U) -// { -// // There is one octet remaining -// octets = static_cast(static_cast(*input++)); -// octets <<= 4; // Adjust one octet (8 bits) for two sextets worth of data (12 bits) -// output_count += 2U; -// } -// else if (input_length == 2U) -// { -// // There are two octets remaining -// octets = static_cast(static_cast(*input++)); -// octets <<= 8; -// octets = octets | static_cast(static_cast(*input++)); -// octets <<= 2; // Adjust two octets (16 bits) for three sextets worth of data (18 bits) -// output_count += 3U; -// } -// -// int shift = static_cast(input_length * 6U); -// -// while (shift >= 0) -// { -// *output++ = get_sextet_from_index((octets >> shift) & b00111111); -// shift -= 6; -// } -// } -// -// if (use_padding) -// { -// // Pad out the end of the output buffer. -// while (output_count != output_length) -// { -// *output++ = padding(); -// ++output_count; -// } -// } -// -// return output_length; -// } -// -// //************************************************************************* -// /// Decode from Base64 implementation -// //************************************************************************* -// template -// ETL_CONSTEXPR14 -// size_t process_decode(TInputIterator input, size_t input_length, TOutputIterator output, size_t output_length) -// { -// if (input_length == 0) -// { -// return 0; -// } -// -// // Read sextet quartets and write octet triplets -// while (input_length >= 4U) -// { -// // Read in four sextets -// uint32_t sextets = (get_index_from_sextet(*input++) << 18); -// sextets = sextets | (get_index_from_sextet(*input++) << 12); -// sextets = sextets | (get_index_from_sextet(*input++) << 6); -// sextets = sextets | (get_index_from_sextet(*input++)); -// -// // Write out three octets -// *output++ = (sextets >> 16) & b11111111; -// *output++ = (sextets >> 8) & b11111111; -// *output++ = (sextets >> 0) & b11111111; -// -// input_length -= 4U; -// } -// -// // Write out any remaining octets -// if (input_length == 2U) -// { -// uint32_t sextets = (get_index_from_sextet(*input++) << 6); -// sextets = sextets | (get_index_from_sextet(*input++)); -// *output++ = (sextets >> 4) & b11111111; -// input_length -= 2U; -// } -// else if (input_length == 3U) -// { -// uint32_t sextets = (get_index_from_sextet(*input++) << 12); -// sextets = sextets | (get_index_from_sextet(*input++) << 6); -// sextets = sextets | (get_index_from_sextet(*input++)); -// *output++ = (sextets >> 10) & b11111111; -// *output++ = (sextets >> 2) & b11111111; -// input_length -= 3U; -// } -// -// return output_length; -// } -// }; - //************************************************************************* /// Base64 RFC-2152 Encoder //************************************************************************* - template + template class base64_rfc2152_encoder : public ibase64_encoder { public: - static ETL_CONSTANT size_t Min_Buffer_Size = etl::base64::Min_Buffer_Size; + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_2152; + static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? Min_Buffer_Size - : Buffer_Size_ + ((Min_Buffer_Size - (Buffer_Size_ % Min_Buffer_Size)) % Min_Buffer_Size); + ? etl::base64::Min_Encode_Buffer_Size + : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); //************************************************************************* - /// Base64 RFC-2152-URL constructor. + /// Base64 RFC-2152 constructor. //************************************************************************* ETL_CONSTEXPR14 base64_rfc2152_encoder() - : ibase64_encoder(etl::base64::Encoding::RFC_2152, - etl::base64::character_set_1(), + : ibase64_encoder(etl::base64::character_set_1(), etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, @@ -1175,12 +496,11 @@ namespace etl } //************************************************************************* - /// Base64 RFC-2152-URL constructor. + /// Base64 RFC-2152 constructor. //************************************************************************* ETL_CONSTEXPR14 base64_rfc2152_encoder(callback_type callback_) - : ibase64_encoder(etl::base64::Encoding::RFC_2152, - etl::base64::character_set_1(), + : ibase64_encoder(etl::base64::character_set_1(), etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, @@ -1207,33 +527,36 @@ namespace etl }; template - ETL_CONSTANT size_t base64_rfc2152_encoder::Min_Buffer_Size; + ETL_CONSTANT etl::base64::Encoding base64_rfc2152_encoder::Encoding; template - ETL_CONSTEXPR size_t base64_rfc2152_encoder::Buffer_Size; + ETL_CONSTANT etl::base64::Padding base64_rfc2152_encoder::Padding; + + template + ETL_CONSTANT size_t base64_rfc2152_encoder::Buffer_Size; //************************************************************************* /// Base64 RFC-3501 Encoder //************************************************************************* - template + template class base64_rfc3501_encoder : public ibase64_encoder { public: - static ETL_CONSTANT size_t Min_Buffer_Size = etl::base64::Min_Buffer_Size; + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_3501; + static ETL_CONSTANT etl::base64::Padding Padding = etl::base64::Padding::No_Padding; // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? Min_Buffer_Size - : Buffer_Size_ + ((Min_Buffer_Size - (Buffer_Size_ % Min_Buffer_Size)) % Min_Buffer_Size); + ? etl::base64::Min_Encode_Buffer_Size + : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); //************************************************************************* - /// Base64 RFC-2152 constructor. + /// Base64 RFC-3501 constructor. //************************************************************************* ETL_CONSTEXPR14 base64_rfc3501_encoder() - : ibase64_encoder(etl::base64::Encoding::RFC_3501, - etl::base64::character_set_3(), + : ibase64_encoder(etl::base64::character_set_3(), etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, @@ -1247,8 +570,7 @@ namespace etl //************************************************************************* ETL_CONSTEXPR14 base64_rfc3501_encoder(callback_type callback_) - : ibase64_encoder(etl::base64::Encoding::RFC_3501, - etl::base64::character_set_3(), + : ibase64_encoder(etl::base64::character_set_3(), etl::base64::Padding::No_Padding, output_buffer, Buffer_Size, @@ -1275,33 +597,36 @@ namespace etl }; template - ETL_CONSTANT size_t base64_rfc3501_encoder::Min_Buffer_Size; + ETL_CONSTANT etl::base64::Encoding base64_rfc3501_encoder::Encoding; template - ETL_CONSTEXPR size_t base64_rfc3501_encoder::Buffer_Size; + ETL_CONSTANT etl::base64::Padding base64_rfc3501_encoder::Padding; + + template + ETL_CONSTANT size_t base64_rfc3501_encoder::Buffer_Size; //************************************************************************* /// Base64 RFC-4648 Encoder //************************************************************************* - template + template class base64_rfc4648_encoder : public ibase64_encoder { public: - static ETL_CONSTANT size_t Min_Buffer_Size = etl::base64::Min_Buffer_Size; + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648; + static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? Min_Buffer_Size - : Buffer_Size_ + ((Min_Buffer_Size - (Buffer_Size_ % Min_Buffer_Size)) % Min_Buffer_Size); + ? etl::base64::Min_Encode_Buffer_Size + : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); //************************************************************************* /// Base64 RFC-4648 constructor. //************************************************************************* ETL_CONSTEXPR14 base64_rfc4648_encoder() - : ibase64_encoder(etl::base64::Encoding::RFC_2152, - etl::base64::character_set_1(), + : ibase64_encoder(etl::base64::character_set_1(), Use_Padding, output_buffer, Buffer_Size, @@ -1315,8 +640,7 @@ namespace etl //************************************************************************* ETL_CONSTEXPR14 base64_rfc4648_encoder(callback_type callback_) - : ibase64_encoder(etl::base64::Encoding::RFC_2152, - etl::base64::character_set_1(), + : ibase64_encoder(etl::base64::character_set_1(), Use_Padding, output_buffer, Buffer_Size, @@ -1343,34 +667,36 @@ namespace etl }; template - ETL_CONSTANT size_t base64_rfc4648_encoder::Min_Buffer_Size; + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_encoder::Encoding; template - ETL_CONSTEXPR size_t base64_rfc4648_encoder::Buffer_Size; + ETL_CONSTANT etl::base64::Padding base64_rfc4648_encoder::Padding; + + template + ETL_CONSTANT size_t base64_rfc4648_encoder::Buffer_Size; //************************************************************************* /// Base64 RFC-4648-URL Encoder //************************************************************************* - template + template class base64_rfc4648_url_encoder : public ibase64_encoder { public: - static ETL_CONSTANT size_t Min_Buffer_Size = etl::base64::Min_Buffer_Size; + static ETL_CONSTANT etl::base64::Encoding Encoding = etl::base64::Encoding::RFC_4648_URL; + static ETL_CONSTANT etl::base64::Padding Padding = Use_Padding ? etl::base64::Padding::Use_Padding : etl::base64::Padding::No_Padding; // Round up the buffer size to a multiple of Min_Buffer_Size. - // Round up the buffer size to a multiple of Min_Buffer_Size. static ETL_CONSTANT size_t Buffer_Size = (Buffer_Size_ == 0) - ? Min_Buffer_Size - : Buffer_Size_ + ((Min_Buffer_Size - (Buffer_Size_ % Min_Buffer_Size)) % Min_Buffer_Size); + ? etl::base64::Min_Encode_Buffer_Size + : Buffer_Size_ + ((etl::base64::Min_Encode_Buffer_Size - (Buffer_Size_ % etl::base64::Min_Encode_Buffer_Size)) % etl::base64::Min_Encode_Buffer_Size); //************************************************************************* /// Base64 RFC-4648-URL constructor. //************************************************************************* ETL_CONSTEXPR14 base64_rfc4648_url_encoder() - : ibase64_encoder(etl::base64::Encoding::RFC_4648_URL, - etl::base64::character_set_2(), + : ibase64_encoder(etl::base64::character_set_2(), Use_Padding, output_buffer, Buffer_Size, @@ -1384,8 +710,7 @@ namespace etl //************************************************************************* ETL_CONSTEXPR14 base64_rfc4648_url_encoder(callback_type callback_) - : ibase64_encoder(etl::base64::Encoding::RFC_4648_URL, - etl::base64::character_set_2(), + : ibase64_encoder(etl::base64::character_set_2(), Use_Padding, output_buffer, Buffer_Size, @@ -1412,10 +737,13 @@ namespace etl }; template - ETL_CONSTANT size_t base64_rfc4648_url_encoder::Min_Buffer_Size; + ETL_CONSTANT etl::base64::Encoding base64_rfc4648_url_encoder::Encoding; template - ETL_CONSTEXPR size_t base64_rfc4648_url_encoder::Buffer_Size; + ETL_CONSTANT etl::base64::Padding base64_rfc4648_url_encoder::Padding; + + template + ETL_CONSTANT size_t base64_rfc4648_url_encoder::Buffer_Size; } #undef ETL_IS_TYPE_8_BIT_INTEGRAL diff --git a/test/test_base64_RFC2152_encoder.cpp b/test/test_base64_RFC2152_encoder.cpp index 0832234f..2728b390 100644 --- a/test/test_base64_RFC2152_encoder.cpp +++ b/test/test_base64_RFC2152_encoder.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc2152_encoder; - using codec_larger_buffer = etl::base64_rfc2152_encoder; + using codec = etl::base64_rfc2152_encoder; + using codec_larger_buffer = etl::base64_rfc2152_encoder; using codec_full_buffer = etl::base64_rfc2152_encoder<344>; std::array input_data = @@ -338,6 +338,18 @@ namespace SUITE(test_base64_rfc4648_with_no_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_2152, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_2152", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::No_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/test_base64_RFC3501_encoder.cpp b/test/test_base64_RFC3501_encoder.cpp index e863eb3a..7fe04033 100644 --- a/test/test_base64_RFC3501_encoder.cpp +++ b/test/test_base64_RFC3501_encoder.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc3501_encoder; - using codec_larger_buffer = etl::base64_rfc3501_encoder; + using codec = etl::base64_rfc3501_encoder; + using codec_larger_buffer = etl::base64_rfc3501_encoder; using codec_full_buffer = etl::base64_rfc3501_encoder<344>; std::array input_data = @@ -338,6 +338,18 @@ namespace SUITE(test_base64_rfc3501_with_no_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_3501, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_3501", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::No_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp b/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp index 69313e20..979087dd 100644 --- a/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_URL_encoder_with_no_padding.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_encoder; - using codec_larger_buffer = etl::base64_rfc4648_url_encoder; + using codec = etl::base64_rfc4648_url_encoder; + using codec_larger_buffer = etl::base64_rfc4648_url_encoder; using codec_full_buffer = etl::base64_rfc4648_url_encoder; std::array input_data = @@ -338,6 +338,18 @@ namespace SUITE(test_base64_rfc4648_url_with_no_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::No_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/test_base64_RFC4648_URL_encoder_with_padding.cpp b/test/test_base64_RFC4648_URL_encoder_with_padding.cpp index 8b8698ae..b2de7761 100644 --- a/test/test_base64_RFC4648_URL_encoder_with_padding.cpp +++ b/test/test_base64_RFC4648_URL_encoder_with_padding.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_url_encoder; - using codec_larger_buffer = etl::base64_rfc4648_url_encoder; + using codec = etl::base64_rfc4648_url_encoder; + using codec_larger_buffer = etl::base64_rfc4648_url_encoder; using codec_full_buffer = etl::base64_rfc4648_url_encoder; std::array input_data = @@ -338,6 +338,18 @@ namespace SUITE(test_base64_rfc4648_url_with_no_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_4648_URL, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648_URL", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::Use_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/test_base64_RFC4648_encoder_with_no_padding.cpp b/test/test_base64_RFC4648_encoder_with_no_padding.cpp index 87185af6..7b258f71 100644 --- a/test/test_base64_RFC4648_encoder_with_no_padding.cpp +++ b/test/test_base64_RFC4648_encoder_with_no_padding.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_encoder; - using codec_larger_buffer = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; + using codec_larger_buffer = etl::base64_rfc4648_encoder; using codec_full_buffer = etl::base64_rfc4648_encoder; std::array input_data = @@ -338,6 +338,18 @@ namespace SUITE(test_base64_rfc4648_with_no_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::No_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("No_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/test_base64_RFC4648_encoder_with_padding.cpp b/test/test_base64_RFC4648_encoder_with_padding.cpp index 76a0c5f0..84e5d390 100644 --- a/test/test_base64_RFC4648_encoder_with_padding.cpp +++ b/test/test_base64_RFC4648_encoder_with_padding.cpp @@ -51,8 +51,8 @@ SOFTWARE. namespace { - using codec = etl::base64_rfc4648_encoder; - using codec_larger_buffer = etl::base64_rfc4648_encoder; + using codec = etl::base64_rfc4648_encoder; + using codec_larger_buffer = etl::base64_rfc4648_encoder; using codec_full_buffer = etl::base64_rfc4648_encoder; std::array input_data = @@ -339,6 +339,18 @@ namespace SUITE(test_base64_rfc4648_with_padding) { + //************************************************************************* + TEST(test_basic_information) + { + codec_full_buffer b64; + + CHECK_EQUAL(etl::base64::Encoding::RFC_4648, codec_full_buffer::Encoding); + CHECK_EQUAL("RFC_4648", codec_full_buffer::Encoding.c_str()); + CHECK_EQUAL(etl::base64::Padding::Use_Padding, codec_full_buffer::Padding); + CHECK_EQUAL("Use_Padding", codec_full_buffer::Padding.c_str()); + CHECK_EQUAL(344, codec_full_buffer::Buffer_Size); + } + //************************************************************************* TEST(test_encode_pointer_size_single_pass_with_callback) { diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 3d49c35c..74fa01c4 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3010,6 +3010,8 @@ + + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 1ae42ef0..a184b7da 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1404,6 +1404,12 @@ ETL\Private + + ETL\Codecs + + + ETL\Codecs +