Renamed test file

This commit is contained in:
John Wellbelove 2023-10-21 18:18:26 +01:00 committed by John Wellbelove
parent 02e69f5757
commit 9a5ed96f8e
2 changed files with 255 additions and 59 deletions

View File

@ -29,7 +29,6 @@ SOFTWARE.
#define ETL_BASE64_INCLUDED
#include "etl/platform.h"
#include "etl/span.h"
#include "etl/static_assert.h"
#include "etl/error_handler.h"
#include "etl/exception.h"
@ -38,13 +37,26 @@ SOFTWARE.
#include "etl/algorithm.h"
#include "etl/integral_limits.h"
#include "etl/iterator.h"
#include "etl/string.h"
#include "enum_type.h"
#include <stdint.h>
#define ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(Type) (etl::is_integral<typename etl::iterator_traits<typename etl::remove_cv<Type>::type>::value_type>::value && \
(etl::integral_limits<typename etl::iterator_traits<typename etl::remove_cv<Type>::type>::value_type>::bits == 8U))
/**************************************************************************************************************************************************************************
* See https://en.wikipedia.org/wiki/Base64
*
* Encoding Encoding characters Separate encoding of lines Decoding non-encoding characters
* 62nd 63rd Pad Separators Length Checksum
* RFC 1421 : Base64 for Privacy - Enhanced Mail(deprecated) + / = mandatory CR + LF 64, or lower for the last line No No
* RFC 2045 : Base64 transfer encoding for MIME + / = mandatory CR + LF At most 76 No Discarded
* RFC 2152 : Base64 for UTF - 7 + / No No No
* RFC 3501 : Base64 encoding for IMAP mailbox names + , No No No
* RFC 4648 : base64(standard)[a] + / = optional No No
* RFC 4648 : base64url(URL - and filename - safe standard) - _ = optional No No
**************************************************************************************************************************************************************************/
namespace etl
{
//***************************************************************************
@ -61,7 +73,7 @@ namespace etl
};
//***************************************************************************
/// Memory misalignment exception.
/// buffer overflow exception.
//***************************************************************************
class base64_overflow : public base64_exception
{
@ -73,6 +85,19 @@ namespace etl
}
};
//***************************************************************************
/// Illegal character exception.
//***************************************************************************
class base64_illegal_character : public base64_exception
{
public:
base64_illegal_character(string_type file_name_, numeric_type line_number_)
: base64_exception(ETL_ERROR_TEXT("base64:illegal character", ETL_BASE64_FILE_ID"B"), file_name_, line_number_)
{
}
};
//*************************************************************************
/// Codec for Base64 (RFC 4648)
//*************************************************************************
@ -80,15 +105,145 @@ namespace etl
{
public:
struct Encoding
{
enum enum_type
{
RFC_1421,
RFC_2045,
RFC_2152,
RFC_3501,
RFC_4648,
RFC_4648_URL,
};
ETL_DECLARE_ENUM_TYPE(Encoding, int)
ETL_ENUM_TYPE(RFC_1421, "RFC 1421")
ETL_ENUM_TYPE(RFC_2045, "RFC 2045")
ETL_END_ENUM_TYPE
};
struct Padding
{
enum enum_type
{
No_Padding = 0,
Use_Padding = 1
};
ETL_DECLARE_ENUM_TYPE(Padding, bool)
ETL_ENUM_TYPE(Use_Padding, "Use padding")
ETL_ENUM_TYPE(No_Padding, "No padding")
ETL_END_ENUM_TYPE
};
//*************************************************************************
/// Default constructor
//*************************************************************************
ETL_CONSTEXPR14
base64()
: use_padding(true)
base64()
: encoding(Encoding::RFC_4648)
, use_padding(true)
, max_line_length(etl::integral_limits<size_t>::max)
{
}
//*************************************************************************
/// Constructor
//*************************************************************************
ETL_CONSTEXPR14
base64(Encoding encoding_, bool use_padding_ = etl::base64::Padding::Use_Padding)
: encoding(Encoding::RFC_4648)
, use_padding(false)
, max_line_length(0)
{
switch (encoding)
{
case Encoding::RFC_1421:
{
use_padding = true;
max_line_length = 64;
break;
}
case Encoding::RFC_2045:
{
use_padding = true;
max_line_length = 76;
break;
}
case Encoding::RFC_2152:
{
use_padding = false;
max_line_length = etl::integral_limits<size_t>::max;
break;
}
case Encoding::RFC_3501:
{
use_padding = false;
max_line_length = etl::integral_limits<size_t>::max;
break;
}
case Encoding::RFC_4648:
{
use_padding = use_padding_;
max_line_length = etl::integral_limits<size_t>::max;
break;
}
case Encoding::RFC_4648_URL:
{
use_padding = use_padding_;
max_line_length = etl::integral_limits<size_t>::max;
break;
}
default:
{
break;
}
}
}
//*************************************************************************
/// Get the encoding standard
//*************************************************************************
ETL_CONSTEXPR14
Encoding get_encoding() const
{
return encoding;
}
//*************************************************************************
/// Get the maximum line length
//*************************************************************************
ETL_CONSTEXPR14
size_t get_max_line_length() const
{
return max_line_length;
}
//*************************************************************************
/// Get the padding flag
//*************************************************************************
ETL_CONSTEXPR14
bool using_padding() const
{
return use_padding;
}
//*************************************************************************
/// Get the line break flag
//*************************************************************************
ETL_CONSTEXPR14
bool has_line_breaks() const
{
return max_line_length != etl::integral_limits<size_t>::max;
}
//*************************************************************************
/// Encode to Base64
/// Four parameter
@ -491,8 +646,7 @@ namespace etl
}
else
{
// Should never get here.
assert(false);
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(base64_illegal_character), 0);
return padding<T>();
}
}
@ -525,9 +679,7 @@ namespace etl
}
else
{
// Should never get here.
assert(false);
return 0;
ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(base64_illegal_character), 0);
}
}
@ -537,11 +689,36 @@ namespace etl
template <typename T>
ETL_NODISCARD
ETL_CONSTEXPR14
static T padding()
static
T padding()
{
return static_cast<T>('=');
}
//*************************************************************************
/// Is the character a carriage return?
//*************************************************************************
template <typename T>
ETL_NODISCARD
ETL_CONSTEXPR14
static
bool is_carriage_return(T c)
{
return (static_cast<char>(c) == '\r');
}
//*************************************************************************
/// Is the character a line break?
//*************************************************************************
template <typename T>
ETL_NODISCARD
ETL_CONSTEXPR14
static
bool is_line_feed(T c)
{
return (static_cast<char>(c) == '\n');
}
//*************************************************************************
/// Encode to Base64 implementation
//*************************************************************************
@ -671,7 +848,9 @@ namespace etl
return output_length;
}
bool use_padding;
Encoding encoding;
bool use_padding;
size_t max_line_length;
};
}

View File

@ -40,6 +40,10 @@ SOFTWARE.
#include "etl/integral_limits.h"
//*****************************************************************************
// Ecode/decode using RFC-4648 with padding
//*****************************************************************************
namespace
{
std::array<unsigned char, 256> input_data_unsigned_char =
@ -343,12 +347,12 @@ namespace
"OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK302ALc3VWiamcRVCDj+ycBQpH40jLsHqzvl+bN8co4QrJDWnY8gLH4u6Ub/pUYDSI7XRtFmufTAdABzYcGwWccdWCP6BrvvgktjbuVd8mctC7/yzVh7RQtMMGLPurxp3qFI8ns3eITQ+H7VU1/u0vQ=="
};
SUITE(test_base64)
SUITE(test_base64_rfc4648_with_padding)
{
//*************************************************************************
TEST(test_encode_unsigned_char_pointer_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 0; i < 256; ++i)
@ -356,7 +360,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_unsigned_char.data(), i,
encoded_output.data(), encoded_output.size());
encoded_output.data(), encoded_output.size());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -369,7 +373,7 @@ namespace
//*************************************************************************
TEST(test_encode_unsigned_char_pointer_size_no_output_length)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 0; i < 256; ++i)
@ -377,7 +381,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_unsigned_char.data(), i,
encoded_output.data());
encoded_output.data());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -390,14 +394,14 @@ namespace
//*************************************************************************
TEST(test_encode_unsigned_char_pointer_size_to_back_inserter)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
for (size_t i = 0; i < 256; ++i)
{
std::string actual;
auto size = b64.encode(input_data_unsigned_char.data(), i,
etl::back_inserter(actual));
etl::back_inserter(actual));
std::string expected(encoded[i]);
@ -409,7 +413,7 @@ namespace
//*************************************************************************
TEST(test_encode_unsigned_char_pointer_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 0; i < 256; ++i)
@ -417,7 +421,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
encoded_output.data(), encoded_output.data() + encoded_output.size());
encoded_output.data(), encoded_output.data() + encoded_output.size());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -430,7 +434,7 @@ namespace
//*************************************************************************
TEST(test_encode_unsigned_char_pointer_pointer_no_output_end_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 6; i < 256; ++i)
@ -438,7 +442,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
encoded_output.data());
encoded_output.data());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -451,7 +455,7 @@ namespace
//*************************************************************************
TEST(test_encode_int8_t_pointer_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 11; i < 256; ++i)
@ -459,7 +463,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_int8_t.data(), i,
encoded_output.data(), encoded_output.size());
encoded_output.data(), encoded_output.size());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -472,7 +476,7 @@ namespace
//*************************************************************************
TEST(test_encode_int8_t_pointer_size_no_output_length)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 6; i < 256; ++i)
@ -480,7 +484,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_int8_t.data(), i,
encoded_output.data());
encoded_output.data());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -493,14 +497,14 @@ namespace
//*************************************************************************
TEST(test_encode_int8_t_pointer_size_to_back_inserter)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
for (size_t i = 0; i < 256; ++i)
{
std::string actual;
auto size = b64.encode(input_data_int8_t.data(), i,
etl::back_inserter(actual));
etl::back_inserter(actual));
std::string expected(encoded[i]);
@ -512,7 +516,7 @@ namespace
//*************************************************************************
TEST(test_encode_int8_t_pointer_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
for (size_t i = 0; i < 256; ++i)
@ -520,7 +524,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
encoded_output.data(), encoded_output.data() + encoded_output.size());
encoded_output.data(), encoded_output.data() + encoded_output.size());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -533,7 +537,7 @@ namespace
//*************************************************************************
TEST(test_encode_int8_t_pointer_pointer_no_end_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 344U> encoded_output;
@ -542,7 +546,7 @@ namespace
encoded_output.fill(0);
auto size = b64.encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
encoded_output.data());
encoded_output.data());
std::string expected(encoded[i]);
std::string actual(encoded_output.data(), size);
@ -557,7 +561,7 @@ namespace
template <size_t Size>
constexpr auto GetConstexprBase64(const etl::array<int8_t, Size> input) noexcept
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
constexpr size_t encoded_size = etl::base64::encoded_size(Size);
etl::array<char, etl::base64::encoded_size(Size)> output{ 0 };
@ -585,18 +589,18 @@ namespace
//*************************************************************************
TEST(test_encode_overflow)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<char, 1> encoded_output{ 0 };
CHECK_THROW((b64.encode(input_data_unsigned_char.data(), 10,
encoded_output.data(), encoded_output.size())),
encoded_output.data(), encoded_output.size())),
etl::base64_overflow);
}
//*************************************************************************
TEST(test_decode_unsigned_char_pointer_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -604,7 +608,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].size(),
decoded_output.data(), decoded_output.size());
decoded_output.data(), decoded_output.size());
CHECK_ARRAY_EQUAL(input_data_unsigned_char.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -615,7 +619,7 @@ namespace
//*************************************************************************
TEST(test_decode_unsigned_char_pointer_size_no_end_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -623,7 +627,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].size(),
decoded_output.data());
decoded_output.data());
CHECK_ARRAY_EQUAL(input_data_unsigned_char.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -634,7 +638,7 @@ namespace
//*************************************************************************
TEST(test_decode_unsigned_char_pointer_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -642,7 +646,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
decoded_output.data(), decoded_output.data() + decoded_output.size());
decoded_output.data(), decoded_output.data() + decoded_output.size());
CHECK_ARRAY_EQUAL(input_data_unsigned_char.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -653,7 +657,7 @@ namespace
//*************************************************************************
TEST(test_decode_unsigned_char_pointer_pointer_no_end_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -661,7 +665,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
decoded_output.data());
decoded_output.data());
CHECK_ARRAY_EQUAL(input_data_unsigned_char.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -672,7 +676,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<int8_t, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -680,7 +684,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].size(),
decoded_output.data(), decoded_output.size());
decoded_output.data(), decoded_output.size());
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -691,7 +695,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_size_back_inserter)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::vector<int8_t> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -699,7 +703,7 @@ namespace
decoded_output.clear();
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].size(),
etl::back_inserter(decoded_output));
etl::back_inserter(decoded_output));
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -710,7 +714,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_size_no_output_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<int8_t, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -718,7 +722,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].size(),
decoded_output.data());
decoded_output.data());
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -729,7 +733,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<int8_t, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -737,7 +741,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
decoded_output.data(), decoded_output.data() + decoded_output.size());
decoded_output.data(), decoded_output.data() + decoded_output.size());
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -748,7 +752,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_pointer_back_inserter)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::vector<int8_t> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -756,7 +760,7 @@ namespace
decoded_output.clear();
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
etl::back_inserter(decoded_output));
etl::back_inserter(decoded_output));
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -767,7 +771,7 @@ namespace
//*************************************************************************
TEST(test_decode_int8_t_pointer_pointer_no_end_pointer)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<int8_t, 256> decoded_output;
for (size_t i = 0; i < 256; ++i)
@ -775,7 +779,7 @@ namespace
decoded_output.fill(0);
auto decoded_size = b64.decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
decoded_output.data());
decoded_output.data());
CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i);
CHECK_EQUAL(i, etl::base64::decoded_size(encoded[i].data(), encoded[i].size()));
@ -786,17 +790,30 @@ namespace
//*************************************************************************
TEST(test_decode_overflow)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 1> decoded_output{ 0 };
CHECK_THROW((b64.decode(encoded[10].data(), encoded[10].size(),
decoded_output.data(), decoded_output.size())), etl::base64_overflow);
decoded_output.data(), decoded_output.size())), etl::base64_overflow);
}
//*************************************************************************
TEST(test_decode_invalid_character)
{
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
std::array<unsigned char, 50U> decoded_output{ 0 };
std::string invalid_chararacter("OycD£Qy37KA==");
std::string invalid_padding("OycDQy37KA&=");
CHECK_THROW((b64.decode(invalid_chararacter.data(), invalid_chararacter.size(),
decoded_output.data(), decoded_output.size())), etl::base64_illegal_character);
}
//*************************************************************************
TEST(test_decoded_size)
{
etl::base64 b64;
etl::base64 b64(etl::base64::Encoding::RFC_4648, etl::base64::Padding::Use_Padding);
for (size_t i = 0; i < 256; ++i)
{