mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-26 20:38:45 +08:00
Static version of Base64 - RFC-6848 - No optional padding
This commit is contained in:
parent
58c55a8bb6
commit
0523fc869a
@ -42,11 +42,8 @@ SOFTWARE.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if ETL_USING_STL
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#define ETL_IS_8_BIT_INTEGRAL(Type) (etl::is_integral<Type>::value && (etl::integral_limits<Type>::bits == 8U))
|
||||
#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))
|
||||
|
||||
namespace etl
|
||||
{
|
||||
@ -77,200 +74,135 @@ namespace etl
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Codec for Base64
|
||||
/// Codec for Base64 (RFC 4648)
|
||||
//*************************************************************************
|
||||
class base64
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 from and to pointer/length
|
||||
/// Encode to Base64
|
||||
/// Four parameter
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const T* input, size_t input_length, char* output, size_t output_length)
|
||||
static size_t encode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin, TOutputIterator output_end)
|
||||
{
|
||||
if (input_length == 0U)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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<size_t>(etl::distance(input_begin, input_end));
|
||||
const size_t output_length = static_cast<size_t>(etl::distance(output_begin, output_end));
|
||||
|
||||
// Figure out if the output buffer is large enough.
|
||||
size_t required_output_length = encoded_size(input_length);
|
||||
|
||||
size_t required_output_length = etl::base64::encoded_size(input_length);
|
||||
ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U);
|
||||
|
||||
const T* p_in = input;
|
||||
const T* p_in_end = input + input_length;
|
||||
|
||||
char* p_out = output;
|
||||
char* p_out_end = output + required_output_length;
|
||||
|
||||
int next_sextet = First_Sextet;
|
||||
|
||||
// Step through the input buffer, creating the output sextets.
|
||||
while (p_in != p_in_end)
|
||||
{
|
||||
T c = *p_in;
|
||||
char index = 0;
|
||||
|
||||
switch (next_sextet)
|
||||
{
|
||||
//**************************
|
||||
case First_Sextet:
|
||||
{
|
||||
index = static_cast<char>((*p_in & b11111100) >> 2);
|
||||
next_sextet = Second_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Second_Sextet:
|
||||
{
|
||||
index = static_cast<char>((c & b00000011) << 4);
|
||||
++p_in;
|
||||
|
||||
// Next byte valid?
|
||||
if (p_in != p_in_end)
|
||||
{
|
||||
index = index | ((*p_in & b11110000) >> 4);
|
||||
}
|
||||
next_sextet = Third_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Third_Sextet:
|
||||
{
|
||||
index = (c & b00001111) << 2;
|
||||
++p_in;
|
||||
|
||||
// Next byte valid?
|
||||
if (p_in != p_in_end)
|
||||
{
|
||||
index = index | static_cast<char>((*p_in & b11000000) >> 6);
|
||||
}
|
||||
next_sextet = Fourth_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Fourth_Sextet:
|
||||
{
|
||||
index = static_cast<char>(c & b00111111);
|
||||
++p_in;
|
||||
next_sextet = First_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
default:
|
||||
{
|
||||
// Should never get here.
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*p_out = get_sextet_from_index(index);
|
||||
++p_out;
|
||||
}
|
||||
|
||||
// Pad out the end of the output buffer.
|
||||
while (p_out != p_out_end)
|
||||
{
|
||||
*p_out++ = padding();
|
||||
}
|
||||
|
||||
return static_cast<size_t>(etl::distance(output, p_out));
|
||||
return process_encode(input_begin, input_length, output_begin, required_output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 from and to pointer/pointer
|
||||
/// Encode to Base64
|
||||
/// For TOutputIterator not derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const T* input_begin, const T* input_end, char* output_begin, char* output_end)
|
||||
static typename etl::enable_if<!etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
encode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin)
|
||||
{
|
||||
return encode(input_begin, static_cast<size_t>(etl::distance(input_begin, input_end)),
|
||||
output_begin, static_cast<size_t>(etl::distance(output_begin, 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<size_t>(etl::distance(input_begin, input_end));
|
||||
const size_t output_length = encoded_size(input_length);
|
||||
|
||||
return process_encode(input_begin, input_length, output_begin, output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 from and to span/span
|
||||
/// Encode to Base64
|
||||
/// For TOutputIterator derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T, size_t Length1, size_t Length2>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const etl::span<const T, Length1>& input_span,
|
||||
const etl::span<char, Length2>& output_span)
|
||||
static typename etl::enable_if<etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
encode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin)
|
||||
{
|
||||
return encode(input_span.begin(), input_span.size(),
|
||||
output_span.begin(), output_span.size());
|
||||
ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral");
|
||||
|
||||
const size_t input_length = static_cast<size_t>(etl::distance(input_begin, input_end));
|
||||
const size_t output_length = encoded_size(input_length);
|
||||
|
||||
return process_encode(input_begin, input_length, output_begin, output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 from pointer/length to etl::istring
|
||||
/// Encode to Base64
|
||||
/// Four parameter
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const T* input_begin, size_t input_length,
|
||||
etl::istring& output)
|
||||
static size_t encode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin, size_t output_length)
|
||||
{
|
||||
output.resize(etl::base64::encoded_size(input_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");
|
||||
|
||||
return encode(input_begin, input_length,
|
||||
output.data(), output.size());
|
||||
// Figure out if the output buffer is large enough.
|
||||
size_t required_output_length = etl::base64::encoded_size(input_length);
|
||||
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 from pointer/pointer to etl::istring
|
||||
/// Encode to Base64
|
||||
/// For TOutputIterator not derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const T* input_begin, const T* input_end,
|
||||
etl::istring& output)
|
||||
static typename etl::enable_if<!etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
encode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin)
|
||||
{
|
||||
output.resize(etl::base64::encoded_size(etl::distance(input_begin, input_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");
|
||||
|
||||
return encode(input_begin, static_cast<size_t>(etl::distance(input_begin, input_end)),
|
||||
output.data(), output.size());
|
||||
const size_t output_length = encoded_size(input_length);
|
||||
|
||||
return process_encode(input_begin, input_length, output_begin, output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 from span to etl::istring
|
||||
/// Encode to Base64
|
||||
/// For TOutputIterator derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T, size_t Length1>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
encode(const etl::span<const T, Length1>& input_span,
|
||||
etl::istring& output)
|
||||
static typename etl::enable_if<etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
encode(TInputIterator input_begin, size_t input_length, TOutputIterator output_begin)
|
||||
{
|
||||
output.resize(etl::base64::encoded_size(Length1));
|
||||
ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral");
|
||||
|
||||
return encode(input_span.begin(), input_span.size(),
|
||||
output.data(), output.size());
|
||||
const size_t output_length = encoded_size(input_length);
|
||||
|
||||
return process_encode(input_begin, input_length, output_begin, output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the buffer size required to encode to Base64
|
||||
/// Calculates the minimum buffer size required to encode to Base64
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
size_t encoded_size(size_t input_length)
|
||||
static size_t encoded_size(size_t input_length)
|
||||
{
|
||||
size_t required_output_length = (input_length * 8U) / 6U;
|
||||
size_t required_output_length = (input_length * 4U) / 3U;
|
||||
|
||||
while ((required_output_length % 4U) != 0)
|
||||
{
|
||||
@ -281,175 +213,238 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decode from Base64 from and to pointer/length
|
||||
/// Decode from Base64
|
||||
/// Four parameter
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
decode(const char* input, size_t input_length, T* output, size_t output_length)
|
||||
static size_t decode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin, TOutputIterator output_end)
|
||||
{
|
||||
if (input_length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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_input_length(input_begin, input_end);
|
||||
const size_t output_length = static_cast<size_t>(etl::distance(output_begin, output_end));
|
||||
|
||||
// Figure out if the output buffer is large enough.
|
||||
size_t required_output_length = etl::base64::decoded_size(input, input_length);
|
||||
|
||||
size_t required_output_length = etl::base64::decoded_size_from_valid_input_length(input_length);
|
||||
ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), 0U);
|
||||
|
||||
const char* p_in = input;
|
||||
const char* p_in_end = input + input_length;
|
||||
|
||||
T* p_out = output;
|
||||
|
||||
T c = 0;
|
||||
int next_sextet = First_Sextet;
|
||||
|
||||
// Step through the input buffer, creating the output binary.
|
||||
while (p_in != p_in_end)
|
||||
{
|
||||
char sextet = *p_in++; // Get the sextet as a T.
|
||||
|
||||
if (sextet == padding())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
char index = get_index_from_sextet(sextet);
|
||||
|
||||
switch (next_sextet)
|
||||
{
|
||||
//**************************
|
||||
case First_Sextet:
|
||||
{
|
||||
c = (index & b00111111) << 2;
|
||||
next_sextet = Second_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Second_Sextet:
|
||||
{
|
||||
c |= (index & b00110000) >> 4;
|
||||
*p_out++ = static_cast<T>(c);
|
||||
c = (index & b00001111) << 4;
|
||||
next_sextet = Third_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Third_Sextet:
|
||||
{
|
||||
c |= (index & b00111100) >> 2;
|
||||
*p_out++ = static_cast<T>(c);
|
||||
c = (index & b00000011) << 6;
|
||||
next_sextet = Fourth_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
case Fourth_Sextet:
|
||||
{
|
||||
c |= (index & b00111111);
|
||||
*p_out++ = static_cast<T>(c);
|
||||
next_sextet = First_Sextet;
|
||||
break;
|
||||
}
|
||||
|
||||
//**************************
|
||||
default:
|
||||
{
|
||||
// Should never get here.
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<size_t>(etl::distance(output, p_out));
|
||||
return process_decode(input_begin, input_length, output_begin, required_output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decode from Base64 from and to pointer/pointer
|
||||
/// Decode from Base64
|
||||
/// For TOutputIterator not derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
decode(const char* input_begin, const char* input_end, T* output_begin, T* output_end)
|
||||
static typename etl::enable_if<!etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
decode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin)
|
||||
{
|
||||
return decode(input_begin, static_cast<size_t>(etl::distance(input_begin, input_end)),
|
||||
output_begin, static_cast<size_t>(etl::distance(output_begin, 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");
|
||||
|
||||
// Find the length of decodable characters.
|
||||
const size_t input_length = valid_input_length(input_begin, input_end);
|
||||
|
||||
// Find the length of the decoded output.
|
||||
const size_t required_output_length = decoded_size(input_begin, input_length);
|
||||
|
||||
return process_decode(input_begin, input_length, output_begin, required_output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decode from Base64 from and to span/span
|
||||
/// Decode from Base64
|
||||
/// For TOutputIterator derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename T, size_t Length1, size_t Length2>
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
typename etl::enable_if<ETL_IS_8_BIT_INTEGRAL(T), size_t>::type
|
||||
decode(const etl::span<const char, Length1>& input_span,
|
||||
const etl::span<T, Length2>& output_span)
|
||||
static typename etl::enable_if<etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
decode(TInputIterator input_begin, TInputIterator input_end, TOutputIterator output_begin)
|
||||
{
|
||||
return decode(input_span.begin(), input_span.size(),
|
||||
output_span.begin(), output_span.size());
|
||||
ETL_STATIC_ASSERT(ETL_IS_ITERATOR_TYPE_8_BIT_INTEGRAL(TInputIterator), "Input type must be an 8 bit integral");
|
||||
|
||||
// Find the length of decodable characters.
|
||||
const size_t input_length = valid_input_length(input_begin, input_end);
|
||||
|
||||
// Find the length of the decoded output.
|
||||
const size_t required_output_length = decoded_size(input_begin, input_length);
|
||||
|
||||
return process_decode(input_begin, input_length, output_begin, required_output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the buffer size required to decode from Base64
|
||||
/// Decode from Base64
|
||||
/// Four parameter
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static 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_input_length(input_begin, input_length);
|
||||
|
||||
// Figure out if the output buffer is large enough.
|
||||
size_t required_output_length = etl::base64::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
|
||||
/// For TOutputIterator not derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static typename etl::enable_if<!etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
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_input_length(input_begin, input_length);
|
||||
|
||||
// Find the length of the decoded output.
|
||||
const size_t required_output_length = decoded_size(input_begin, input_length);
|
||||
|
||||
return process_decode(input_begin, input_length, output_begin, required_output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decode from Base64
|
||||
/// For TOutputIterator derived from etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
|
||||
/// Three parameter
|
||||
/// Assumes the output container is large enough.
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static typename etl::enable_if<etl::is_void<typename etl::iterator_traits<TOutputIterator>::value_type>::value, size_t>::type
|
||||
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");
|
||||
|
||||
// Find the length of decodable characters.
|
||||
input_length = valid_input_length(input_begin, input_length);
|
||||
|
||||
// Find the length of the decoded output.
|
||||
const size_t output_length = decoded_size(input_begin, input_length);
|
||||
|
||||
return process_decode(input_begin, input_length, output_begin, output_length);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Discovers the number of valid decodable characters
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static size_t decoded_size(const char* input, size_t input_length)
|
||||
static size_t valid_input_length(TInputIterator input_begin, size_t input_length)
|
||||
{
|
||||
if (input_length == 0U)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
// Figure out the minimum output buffer size.
|
||||
size_t length = static_cast<size_t>(etl::distance(input, etl::find(input, input + input_length, padding())) - 1);
|
||||
size_t required_output_length = length - (length / 4U);
|
||||
TInputIterator input_end = input_begin;
|
||||
|
||||
return required_output_length;
|
||||
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 etl::iterator_traits<TInputIterator>::value_type input_type;
|
||||
|
||||
if (*input_end != padding<input_type>())
|
||||
{
|
||||
++input_end;
|
||||
++input_length;
|
||||
|
||||
if (*input_end != padding<input_type>())
|
||||
{
|
||||
++input_end;
|
||||
++input_length;
|
||||
}
|
||||
}
|
||||
|
||||
return input_length;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the buffer size required to decode from Base64
|
||||
/// Discovers the number of valid decodable characters
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static size_t decoded_size(const char* input_begin, const char* input_end)
|
||||
static size_t valid_input_length(TInputIterator input_begin, TInputIterator input_end)
|
||||
{
|
||||
return valid_input_length(input_begin, static_cast<size_t>(etl::distance(input_begin, input_end)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the minimum buffer size required to decode from Base64
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
size_t decoded_size(TInputIterator input_begin, size_t input_length)
|
||||
{
|
||||
if (input_length == 0U)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
input_length = valid_input_length(input_begin, input_length);
|
||||
--input_length;
|
||||
return input_length - (input_length / 4U);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the minimum buffer size required to decode from Base64
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
size_t decoded_size(TInputIterator input_begin, TInputIterator input_end)
|
||||
{
|
||||
return decoded_size(input_begin, static_cast<size_t>(etl::distance(input_begin, input_end)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Calculates the buffer size required to decode from Base64
|
||||
/// Calculates the minimum buffer size required to decode from Base64
|
||||
//*************************************************************************
|
||||
template <size_t Length>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static size_t decoded_size(etl::span<const char, Length> sp)
|
||||
static
|
||||
size_t decoded_size_from_valid_input_length(size_t input_length)
|
||||
{
|
||||
return decoded_size(sp.begin(), sp.size());
|
||||
if (input_length == 0U)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
--input_length;
|
||||
return input_length - (input_length / 4U);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
/// Sextet index id.
|
||||
enum
|
||||
{
|
||||
First_Sextet,
|
||||
Second_Sextet,
|
||||
Third_Sextet,
|
||||
Fourth_Sextet
|
||||
};
|
||||
|
||||
// Sextets
|
||||
// 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
// 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
@ -463,42 +458,44 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Translates an index into a sextet
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 static char get_sextet_from_index(char index)
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR14 static T get_sextet_from_index(char index)
|
||||
{
|
||||
if ((index >= 0) && (index < 26))
|
||||
{
|
||||
return 'A' + index;
|
||||
return static_cast<T>('A' + index);
|
||||
}
|
||||
else if ((index >= 26) && (index < 52))
|
||||
{
|
||||
index -= 26;
|
||||
return 'a' + index;
|
||||
return static_cast<T>('a' + index);
|
||||
}
|
||||
else if ((index >= 52) && (index < 62))
|
||||
{
|
||||
index -= 52;
|
||||
return '0' + index;
|
||||
return static_cast<T>('0' + index);
|
||||
}
|
||||
else if (index == 62)
|
||||
{
|
||||
return '+';
|
||||
return static_cast<T>('+');
|
||||
}
|
||||
else if (index == 63)
|
||||
{
|
||||
return '/';
|
||||
return static_cast<T>('/');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should never get here.
|
||||
assert(false);
|
||||
return padding();
|
||||
return padding<T>();
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Translates a sextet into an index
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 static char get_index_from_sextet(char sextet)
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR14 static uint32_t get_index_from_sextet(T sextet)
|
||||
{
|
||||
if ((sextet >= 'A') && (sextet <= 'Z'))
|
||||
{
|
||||
@ -512,11 +509,11 @@ namespace etl
|
||||
{
|
||||
return sextet - '0' + 52;
|
||||
}
|
||||
else if (sextet == '+')
|
||||
else if ((sextet == '+'))
|
||||
{
|
||||
return 62;
|
||||
}
|
||||
else if (sextet == '/')
|
||||
else if ((sextet == '/'))
|
||||
{
|
||||
return 63;
|
||||
}
|
||||
@ -531,15 +528,142 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the padding character
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
static char padding()
|
||||
static T padding()
|
||||
{
|
||||
return '=';
|
||||
return static_cast<T>('=');
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Encode to Base64 implementation
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
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<uint32_t>(static_cast<unsigned char>(*input++)) << 16);
|
||||
octets = octets | (static_cast<uint32_t>(static_cast<unsigned char>(*input++)) << 8);
|
||||
octets = octets | static_cast<uint32_t>(static_cast<unsigned char>(*input++));
|
||||
|
||||
// Write out four sextets
|
||||
*output++ = get_sextet_from_index<char>((octets >> 18) & b00111111);
|
||||
*output++ = get_sextet_from_index<char>((octets >> 12) & b00111111);
|
||||
*output++ = get_sextet_from_index<char>((octets >> 6) & b00111111);
|
||||
*output++ = get_sextet_from_index<char>((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<uint32_t>(static_cast<unsigned char>(*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<uint32_t>(static_cast<unsigned char>(*input++));
|
||||
octets <<= 8;
|
||||
octets = octets | static_cast<uint32_t>(static_cast<unsigned char>(*input++));
|
||||
octets <<= 2; // Adjust two octets (16 bits) for three sextets worth of data (18 bits)
|
||||
output_count += 3U;
|
||||
}
|
||||
|
||||
int shift = static_cast<int>(input_length * 6U);
|
||||
|
||||
while (shift >= 0)
|
||||
{
|
||||
*output++ = get_sextet_from_index<char>((octets >> shift) & b00111111);
|
||||
shift -= 6;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad out the end of the output buffer.
|
||||
while (output_count != output_length)
|
||||
{
|
||||
*output++ = padding<char>();
|
||||
++output_count;
|
||||
}
|
||||
|
||||
return output_length;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Decode from Base64 implementation
|
||||
//*************************************************************************
|
||||
template <typename TInputIterator, typename TOutputIterator>
|
||||
ETL_CONSTEXPR14
|
||||
static
|
||||
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) |
|
||||
(get_index_from_sextet(*input++) << 12) |
|
||||
(get_index_from_sextet(*input++) << 6) |
|
||||
(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) |
|
||||
(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) |
|
||||
(get_index_from_sextet(*input++) << 6) |
|
||||
(get_index_from_sextet(*input++));
|
||||
*output++ = (sextets >> 10) & b11111111;
|
||||
*output++ = (sextets >> 2) & b11111111;
|
||||
input_length -= 3U;
|
||||
}
|
||||
|
||||
return output_length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_IS_8_BIT_INTEGRAL
|
||||
|
||||
#endif
|
||||
|
||||
@ -39,8 +39,8 @@ SOFTWARE.
|
||||
///\ingroup utilities
|
||||
|
||||
#define ETL_VERSION_MAJOR 20
|
||||
#define ETL_VERSION_MINOR 38
|
||||
#define ETL_VERSION_PATCH 6
|
||||
#define ETL_VERSION_MINOR 39
|
||||
#define ETL_VERSION_PATCH 0
|
||||
|
||||
#define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH)
|
||||
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Embedded Template Library",
|
||||
"version": "20.38.6",
|
||||
"version": "20.39.0",
|
||||
"authors": {
|
||||
"name": "John Wellbelove",
|
||||
"email": "john.wellbelove@etlcpp.com"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
name=Embedded Template Library
|
||||
version=20.38.6
|
||||
version=20.39.0
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
license=MIT
|
||||
|
||||
@ -38,6 +38,8 @@ SOFTWARE.
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "etl/integral_limits.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::array<unsigned char, 256> input_data_unsigned_char =
|
||||
@ -343,198 +345,109 @@ namespace
|
||||
|
||||
SUITE(test_base64)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_pointer_size)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
////*************************************************************************
|
||||
//TEST(test_encode_unsigned_char_pointer_size)
|
||||
//{
|
||||
// std::array<char, 344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
// for (size_t i = 0; i < 256; ++i)
|
||||
// {
|
||||
// encoded_output.fill(0);
|
||||
|
||||
auto size = etl::base64::encode(input_data_unsigned_char.data(), i,
|
||||
encoded_output.data(), encoded_output.size());
|
||||
// auto size = etl::base64::encode(input_data_unsigned_char.data(), i,
|
||||
// encoded_output.data(), encoded_output.size());
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
// std::string expected(encoded[i]);
|
||||
// std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
// CHECK_EQUAL(expected, actual);
|
||||
// CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
// }
|
||||
//}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_pointer_pointer)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
////*************************************************************************
|
||||
//TEST(test_encode_unsigned_char_pointer_size_no_output_length)
|
||||
//{
|
||||
// std::array<char, 344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
// for (size_t i = 0; i < 256; ++i)
|
||||
// {
|
||||
// encoded_output.fill(0);
|
||||
|
||||
auto size = etl::base64::encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
|
||||
encoded_output.data(), encoded_output.data() + encoded_output.size());
|
||||
// auto size = etl::base64::encode(input_data_unsigned_char.data(), i,
|
||||
// encoded_output.data());
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
// std::string expected(encoded[i]);
|
||||
// std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
// CHECK_EQUAL(expected, actual);
|
||||
// CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
// }
|
||||
//}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_span)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
////*************************************************************************
|
||||
//TEST(test_encode_unsigned_char_pointer_size_to_back_inserter)
|
||||
//{
|
||||
// for (size_t i = 0; i < 256; ++i)
|
||||
// {
|
||||
// std::string actual;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
// auto size = etl::base64::encode(input_data_unsigned_char.data(), i,
|
||||
// etl::back_inserter(actual));
|
||||
|
||||
etl::span<const unsigned char> input_span(input_data_unsigned_char.data(), i);
|
||||
etl::span<char> output_span(encoded_output.data(), encoded_output.size());
|
||||
// std::string expected(encoded[i]);
|
||||
//
|
||||
// CHECK_EQUAL(expected, actual);
|
||||
// CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
// }
|
||||
//}
|
||||
|
||||
auto size = etl::base64::encode(input_span, output_span);
|
||||
////*************************************************************************
|
||||
//TEST(test_encode_unsigned_char_pointer_pointer)
|
||||
//{
|
||||
// std::array<char, 344U> encoded_output;
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
// for (size_t i = 0; i < 256; ++i)
|
||||
// {
|
||||
// encoded_output.fill(0);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
// auto size = etl::base64::encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
|
||||
// encoded_output.data(), encoded_output.data() + encoded_output.size());
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_pointer_size_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
// std::string expected(encoded[i]);
|
||||
// std::string actual(encoded_output.data(), size);
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
// CHECK_EQUAL(expected, actual);
|
||||
// CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
// }
|
||||
//}
|
||||
|
||||
auto size = etl::base64::encode(input_data_unsigned_char.data(), i,
|
||||
encoded_output);
|
||||
////*************************************************************************
|
||||
//TEST(test_encode_unsigned_char_pointer_pointer_no_output_end_pointer)
|
||||
//{
|
||||
// std::array<char, 344U> encoded_output;
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
// for (size_t i = 6; i < 256; ++i)
|
||||
// {
|
||||
// encoded_output.fill(0);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
// auto size = etl::base64::encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
|
||||
// encoded_output.data());
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_pointer_pointer_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
// std::string expected(encoded[i]);
|
||||
// std::string actual(encoded_output.data(), size);
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
|
||||
auto size = etl::base64::encode(input_data_unsigned_char.data(), input_data_unsigned_char.data() + i,
|
||||
encoded_output);
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_unsigned_char_span_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
|
||||
etl::span<const unsigned char> input_span(input_data_unsigned_char.data(), i);
|
||||
|
||||
auto size = etl::base64::encode(input_span,
|
||||
encoded_output);
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_size_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), i,
|
||||
encoded_output);
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_pointer_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
|
||||
encoded_output);
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_span_to_etl_string)
|
||||
{
|
||||
etl::string<344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.clear();
|
||||
|
||||
etl::span<const int8_t> input_span(input_data_int8_t.data(), i);
|
||||
|
||||
auto size = etl::base64::encode(input_span,
|
||||
encoded_output);
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
// CHECK_EQUAL(expected, actual);
|
||||
// CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
// }
|
||||
//}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_size)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
for (size_t i = 11; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
|
||||
@ -550,16 +463,16 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_pointer)
|
||||
TEST(test_encode_int8_t_pointer_size_no_output_length)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
for (size_t i = 6; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
|
||||
encoded_output.data(), encoded_output.data() + encoded_output.size());
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), i,
|
||||
encoded_output.data());
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
@ -570,7 +483,24 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_span)
|
||||
TEST(test_encode_int8_t_pointer_size_to_back_inserter)
|
||||
{
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
std::string actual;
|
||||
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), i,
|
||||
etl::back_inserter(actual));
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_pointer)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
|
||||
@ -578,10 +508,28 @@ namespace
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
|
||||
etl::span<const int8_t> input_span(input_data_int8_t.data(), i);
|
||||
etl::span<char> output_span(encoded_output.data(), encoded_output.size());
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
|
||||
encoded_output.data(), encoded_output.data() + encoded_output.size());
|
||||
|
||||
auto size = etl::base64::encode(input_span, output_span);
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
|
||||
CHECK_EQUAL(expected, actual);
|
||||
CHECK_EQUAL(etl::base64::encoded_size(i), size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_int8_t_pointer_pointer_no_end_pointer)
|
||||
{
|
||||
std::array<char, 344U> encoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
encoded_output.fill(0);
|
||||
|
||||
auto size = etl::base64::encode(input_data_int8_t.data(), input_data_int8_t.data() + i,
|
||||
encoded_output.data());
|
||||
|
||||
std::string expected(encoded[i]);
|
||||
std::string actual(encoded_output.data(), size);
|
||||
@ -600,7 +548,7 @@ namespace
|
||||
etl::array<char, etl::base64::encoded_size(Size)> output{ 0 };
|
||||
|
||||
etl::base64::encode(input.begin(), Size,
|
||||
output._buffer, encoded_size);
|
||||
output._buffer, encoded_size);
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -625,19 +573,12 @@ namespace
|
||||
std::array<char, 1> encoded_output{ 0 };
|
||||
|
||||
CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10,
|
||||
encoded_output.data(), encoded_output.size())), etl::base64_overflow);
|
||||
encoded_output.data(), encoded_output.size())),
|
||||
etl::base64_overflow);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_encode_overflow_for_etl_string)
|
||||
{
|
||||
etl::string<10> output;
|
||||
|
||||
CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, output)), etl::base64_overflow);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_unsigned_char)
|
||||
TEST(test_decode_unsigned_char_pointer_size)
|
||||
{
|
||||
std::array<unsigned char, 256> decoded_output;
|
||||
|
||||
@ -645,8 +586,8 @@ namespace
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].size(),
|
||||
decoded_output.data(), decoded_output.size());
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].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()));
|
||||
@ -655,7 +596,61 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t)
|
||||
TEST(test_decode_unsigned_char_pointer_size_no_end_pointer)
|
||||
{
|
||||
std::array<unsigned char, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_unsigned_char_pointer_pointer)
|
||||
{
|
||||
std::array<unsigned char, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].data() + encoded[i].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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_unsigned_char_pointer_pointer_no_end_pointer)
|
||||
{
|
||||
std::array<unsigned char, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_size)
|
||||
{
|
||||
std::array<int8_t, 256> decoded_output;
|
||||
|
||||
@ -672,6 +667,96 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_size_back_inserter)
|
||||
{
|
||||
std::vector<int8_t> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.clear();
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_size_no_output_size)
|
||||
{
|
||||
std::array<int8_t, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_pointer)
|
||||
{
|
||||
std::array<int8_t, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].data() + encoded[i].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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_pointer_back_inserter)
|
||||
{
|
||||
std::vector<int8_t> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.clear();
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_int8_t_pointer_pointer_no_end_pointer)
|
||||
{
|
||||
std::array<int8_t, 256> decoded_output;
|
||||
|
||||
for (size_t i = 0; i < 256; ++i)
|
||||
{
|
||||
decoded_output.fill(0);
|
||||
|
||||
auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].data() + encoded[i].size(),
|
||||
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()));
|
||||
CHECK_EQUAL(i, decoded_size);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_decode_overflow)
|
||||
{
|
||||
@ -689,9 +774,6 @@ namespace
|
||||
size_t length = etl::base64::decoded_size(encoded[i].data(), encoded[i].size());
|
||||
|
||||
CHECK_EQUAL(length, etl::base64::decoded_size(encoded[i].data(), encoded[i].data() + encoded[i].size()));
|
||||
|
||||
etl::span<const char> sp(encoded[i].data(), encoded[i].size());
|
||||
CHECK_EQUAL(length, etl::base64::decoded_size(sp));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user