From 4489416abc780980c4ac8d17f0c0b6497cc354b7 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 29 Sep 2023 11:15:08 +0100 Subject: [PATCH 1/6] Initial code --- include/etl/base64.h | 387 +++++++++++++++++++++++++++++++ include/etl/file_error_numbers.h | 1 + test/test_base64.cpp | 345 +++++++++++++++++++++++++++ test/vs2022/etl.vcxproj | 2 + test/vs2022/etl.vcxproj.filters | 12 + 5 files changed, 747 insertions(+) create mode 100644 include/etl/base64.h create mode 100644 test/test_base64.cpp diff --git a/include/etl/base64.h b/include/etl/base64.h new file mode 100644 index 000000000..d79b5541c --- /dev/null +++ b/include/etl/base64.h @@ -0,0 +1,387 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com +Copyright(c) 2023 John Wellbelove +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_BASE64_INCLUDED +#define ETL_BASE64_INCLUDED + +#include "etl/platform.h" +#include "etl/span.h" +#include "etl/error_handler.h" +#include "etl/exception.h" +#include "etl/type_traits.h" +#include "etl/binary.h" +#include "etl/algorithm.h" +#include "etl/integral_limits.h" + +#include + +namespace etl +{ + //*************************************************************************** + /// Exception base for base64 + //*************************************************************************** + class base64_exception : public etl::exception + { + public: + + base64_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Memory misalignment exception. + //*************************************************************************** + class base64_overflow : public base64_exception + { + public: + + base64_overflow(string_type file_name_, numeric_type line_number_) + : base64_exception(ETL_ERROR_TEXT("base64:overflow", ETL_BASE64_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + class base64 + { + public: + + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + encode(const T* input, size_t input_length, char* output, size_t output_length) + { + etl::span result; + + int count = 0; + + if (input_length > 0U) + { + // Figure out if the output buffer is large enough. + size_t required_output_length = (input_length * 8U) / 6U; + + if ((input_length % 3U) != 0U) + { + while ((required_output_length % 4U) != 0) + { + ++required_output_length; + } + } + + ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + + 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((c & b11111100) >> 2); + next_sextet = Second_Sextet; + break; + } + + case Second_Sextet: + { + index = static_cast((c & b00000011) << 4); + ++p_in; + ++count; + + // Next byte valid? + if (p_in != p_in_end) + { + c = *p_in; + index = index | ((c & b11110000) >> 4); + } + next_sextet = Third_Sextet; + break; + } + + case Third_Sextet: + { + index = (c & b00001111) << 2; + ++p_in; + ++count; + + // Next byte valid? + if (p_in != p_in_end) + { + c = *p_in; + index = index | static_cast((c & b11000000) >> 6); + } + next_sextet = Fourth_Sextet; + break; + } + + case Fourth_Sextet: + { + index = static_cast(c & b00111111); + ++p_in; + ++count; + next_sextet = First_Sextet; + break; + } + + default: + { + // Should never get here. + 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; + } + + result = etl::span(output, p_out); + } + + return result; + } + + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + encode(const etl::span& input_span, + const etl::span& output_span) + { + return encode(input_span.begin(), input_span.size(), + output_span.begin(), output_span.size()); + } + + //************************************************************************* + ETL_CONSTEXPR14 + static + size_t encode_size(size_t input_length) + { + size_t required_output_length = (input_length * 8U) / 6U; + + if ((input_length % 3U) != 0U) + { + while ((required_output_length % 4U) != 0) + { + ++required_output_length; + } + } + + return required_output_length; + } + + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + decode(const char* input, size_t input_length, T* output, size_t output_length) + { + etl::span result; + + if (input_length > 0) + { + // Figure out if the output buffer is large enough. + size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; + size_t required_output_length = length - (length / 4U); + + ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + + const char* p_in = input; + const char* p_in_end = input + input_length; + + T* p_out = output; + T* p_out_end = output + output_length; + + 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(c); + c = (index & b00001111) << 4; + next_sextet = Third_Sextet; + break; + } + + case Third_Sextet: + { + c |= (index & b00111100) >> 2; + *p_out++ = static_cast(c); + c = (index & b00000011) << 6; + next_sextet = Fourth_Sextet; + break; + } + + case Fourth_Sextet: + { + c |= (index & b00111111); + *p_out++ = static_cast(c); + next_sextet = First_Sextet; + break; + } + + default: + { + // Should never get here. + break; + } + } + } + + result = etl::span(output, p_out); + } + + return result; + } + + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + decode(const etl::span& input_span, + const etl::span& output_span) + { + return decode(input_span.begin(), input_span.size(), + output_span.begin(), output_span.size()); + } + + ////************************************************************************* + //template + //ETL_CONSTEXPR14 + //static + //typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + // decode_size(const etl::span& input_span) + //{ + // // Figure out the minimum output buffer size. + // size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; + // size_t required_output_length = length - (length / 4U); + + // return required_output_length; + //} + + //************************************************************************* + ETL_CONSTEXPR14 + static size_t decode_size(const char* input, size_t input_length) + { + // Figure out the minimum output buffer size. + size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; + size_t required_output_length = length - (length / 4U); + + return required_output_length; + } + + private: + + //************************************************************************* + /// Sextet index id. + enum + { + First_Sextet, + Second_Sextet, + Third_Sextet, + Fourth_Sextet + }; + + //************************************************************************* + /// The Base64 padding character + static ETL_CONSTANT char Padding = '='; + + //************************************************************************* + // Sextet lookup. + static ETL_CONSTANT char lookup_char[64] = + { + 'A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N' , 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V' , 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd' , 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l' , 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't' , 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1' , '2', '3', + '4', '5', '6', '7', '8', '9' , '+', '/' + }; + + //************************************************************************* + // Translates an index into a sextet + ETL_CONSTEXPR14 static char get_sextet_from_index(char index) + { + return lookup_char[index]; + } + + //************************************************************************* + // Translates a sextet into an index + ETL_CONSTEXPR14 static char get_index_from_sextet(char sextet) + { + const char* p = etl::find(lookup_char, lookup_char + 64, sextet); + + return static_cast(etl::distance(lookup_char, p)); + } + }; +} + +#endif diff --git a/include/etl/file_error_numbers.h b/include/etl/file_error_numbers.h index 1bc5bc5fb..a866ce417 100644 --- a/include/etl/file_error_numbers.h +++ b/include/etl/file_error_numbers.h @@ -102,5 +102,6 @@ SOFTWARE. #define ETL_TO_ARITHMETIC_FILE_ID "69" #define ETL_EXPECTED_FILE_ID "70" #define ETL_ALIGNMENT_FILE_ID "71" +#define ETL_BASE64_FILE_ID "72" #endif diff --git a/test/test_base64.cpp b/test/test_base64.cpp new file mode 100644 index 000000000..10be6c877 --- /dev/null +++ b/test/test_base64.cpp @@ -0,0 +1,345 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/base64.h" + +#include +#include + +namespace +{ + std::array input_data = + { + 0x3B, 0x27, 0x03, 0x43, 0x2D, 0xFB, 0x28, 0x2A, 0x61, 0xAE, 0xBC, 0x49, 0x71, 0x32, 0x01, 0x15, + 0x69, 0x5C, 0x5E, 0xF5, 0xD5, 0x9B, 0xDE, 0xA5, 0x57, 0xC9, 0xC1, 0x7D, 0x80, 0xDE, 0x4C, 0x81, + 0xC0, 0xCF, 0x2A, 0xD1, 0x86, 0x56, 0xD5, 0x71, 0x37, 0xEB, 0x80, 0x32, 0xDF, 0xE4, 0xDF, 0xB6, + 0xEE, 0x3F, 0xDC, 0x79, 0xB3, 0x17, 0x8E, 0x76, 0x65, 0x8E, 0x96, 0x21, 0xB9, 0x88, 0xD1, 0x6D, + 0xD0, 0xDD, 0xFF, 0xDA, 0xA8, 0x7A, 0x4D, 0xF5, 0x71, 0x77, 0xFD, 0x2E, 0xF2, 0xE4, 0x40, 0x72, + 0x8C, 0x83, 0x00, 0x6F, 0x13, 0x72, 0x53, 0xE4, 0x6B, 0x70, 0x0E, 0x37, 0xCA, 0x25, 0xCD, 0x68, + 0x62, 0xC0, 0xAB, 0x14, 0xC7, 0x59, 0x83, 0xD2, 0x82, 0x8C, 0x93, 0x6D, 0x13, 0x21, 0xC0, 0x08, + 0xF9, 0x6D, 0xAC, 0x84, 0x78, 0x49, 0x84, 0x6F, 0x6B, 0xFB, 0x20, 0x3B, 0x9C, 0x49, 0xFB, 0x4E, + 0x80, 0x69, 0x82, 0x25, 0x86, 0x95, 0xD5, 0x4D, 0x91, 0xED, 0xD2, 0x77, 0x2A, 0x24, 0x40, 0x8A, + 0xDF, 0x4D, 0x80, 0x2D, 0xCD, 0xD5, 0x5A, 0x26, 0xA6, 0x71, 0x15, 0x42, 0x0E, 0x3F, 0xB2, 0x70, + 0x14, 0x29, 0x1F, 0x8D, 0x23, 0x2E, 0xC1, 0xEA, 0xCE, 0xF9, 0x7E, 0x6C, 0xDF, 0x1C, 0xA3, 0x84, + 0x2B, 0x24, 0x35, 0xA7, 0x63, 0xC8, 0x0B, 0x1F, 0x8B, 0xBA, 0x51, 0xBF, 0xE9, 0x51, 0x80, 0xD2, + 0x23, 0xB5, 0xD1, 0xB4, 0x59, 0xAE, 0x7D, 0x30, 0x1D, 0x00, 0x1C, 0xD8, 0x70, 0x6C, 0x16, 0x71, + 0xC7, 0x56, 0x08, 0xFE, 0x81, 0xAE, 0xFB, 0xE0, 0x92, 0xD8, 0xDB, 0xB9, 0x57, 0x7C, 0x99, 0xCB, + 0x42, 0xEF, 0xFC, 0xB3, 0x56, 0x1E, 0xD1, 0x42, 0xD3, 0x0C, 0x18, 0xB3, 0xEE, 0xAF, 0x1A, 0x77, + 0xA8, 0x52, 0x3C, 0x9E, 0xCD, 0xDE, 0x21, 0x34, 0x3E, 0x1F, 0xB5, 0x54, 0xD7, 0xFB, 0xB4, 0xBD + }; + + std::array encoded = + { + "", + "Ow==", + "Oyc=", + "OycD", + "OycDQw==", + "OycDQy0=", + "OycDQy37", + "OycDQy37KA==", + "OycDQy37KCo=", + "OycDQy37KCph", + "OycDQy37KCphrg==", + "OycDQy37KCphrrw=", + "OycDQy37KCphrrxJ", + "OycDQy37KCphrrxJcQ==", + "OycDQy37KCphrrxJcTI=", + "OycDQy37KCphrrxJcTIB", + "OycDQy37KCphrrxJcTIBFQ==", + "OycDQy37KCphrrxJcTIBFWk=", + "OycDQy37KCphrrxJcTIBFWlc", + "OycDQy37KCphrrxJcTIBFWlcXg==", + "OycDQy37KCphrrxJcTIBFWlcXvU=", + "OycDQy37KCphrrxJcTIBFWlcXvXV", + "OycDQy37KCphrrxJcTIBFWlcXvXVmw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm94=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96l", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lVw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8k=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nB", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYA=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDe", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIE=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHA", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyo=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrR", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlY=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbV", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTc=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfr", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDI=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5A==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N8=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+2", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27g==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j8=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/c", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/ceQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebM=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMX", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnY=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZl", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpY=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYh", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYg=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjR", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdA=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/w==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9o=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qo", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoeg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek0=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXc=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9Lg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvI=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLk", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHI=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKM", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwA=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBv", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvEw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3I=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5A==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5Gs=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5Gtw", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjc=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfK", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc0=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1o", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsA=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCr", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMc=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZ", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZgw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9I=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KC", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJM=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNt", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyE=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHA", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPk=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPlt", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIQ=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYQ=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRv", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRvaw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/s=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sg", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgOw==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5w=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+w==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+04=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06A", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYI=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIl", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhg==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpU=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXV", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZE=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0g==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0nc=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncq", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJA==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJEA=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK3w==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK300=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK302A", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK302ALQ==", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK302ALc0=", + "OycDQy37KCphrrxJcTIBFWlcXvXVm96lV8nBfYDeTIHAzyrRhlbVcTfrgDLf5N+27j/cebMXjnZljpYhuYjRbdDd/9qoek31cXf9LvLkQHKMgwBvE3JT5GtwDjfKJc1oYsCrFMdZg9KCjJNtEyHACPltrIR4SYRva/sgO5xJ+06AaYIlhpXVTZHt0ncqJECK302ALc3V", + "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" + }; + + SUITE(test_base64) + { + TEST(test_encode) + { + constexpr int length = 200; + + constexpr size_t require_encoded_length = etl::base64::encode_size(length); + + std::array encoded_output; + + auto result = etl::base64::encode(input_data.data(), length, encoded_output.data(), encoded_output.size()); + + std::string expected(encoded[length]); + std::string actual(result.begin(), result.end()); + + bool equal = actual == expected; + + CHECK_EQUAL(require_encoded_length, result.size()); + } + + TEST(test_decode) + { + + } + }; +} + diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index cb565df50..f0da849ec 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -2928,6 +2928,7 @@ + @@ -14319,6 +14320,7 @@ + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 5f5196403..641b2fbc3 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -220,6 +220,12 @@ {c75cedd3-8b6c-4662-b965-aecbe7fd5d1c} + + {6bbca8f0-f707-45ee-9dad-6d41d401bbaf} + + + {9713a35d-8f0e-4722-9b15-a5c477c9ecdb} + @@ -1362,6 +1368,9 @@ ETL\Utilities + + ETL\Codecs + @@ -3425,6 +3434,9 @@ Tests\Misc + + Tests\Codecs + From c8e69929292e2e583f51d57c107f395e97587773 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Oct 2023 10:49:45 +0100 Subject: [PATCH 2/6] Final changes --- include/etl/base64.h | 445 +- test/CMakeLists.txt | 1 + test/syntax_check/base64.h.t.cpp | 29 + test/syntax_check/c++03/CMakeLists.txt | 1 + test/syntax_check/c++11/CMakeLists.txt | 1 + test/syntax_check/c++14/CMakeLists.txt | 1 + test/syntax_check/c++17/CMakeLists.txt | 1 + test/syntax_check/c++20/CMakeLists.txt | 1 + test/test_base64.cpp | 227 +- test/vs2022/etl.vcxproj | 11780 +++++------------------ test/vs2022/etl.vcxproj.filters | 1147 +-- 11 files changed, 3367 insertions(+), 10267 deletions(-) create mode 100644 test/syntax_check/base64.h.t.cpp diff --git a/include/etl/base64.h b/include/etl/base64.h index d79b5541c..bc661deb4 100644 --- a/include/etl/base64.h +++ b/include/etl/base64.h @@ -1,4 +1,6 @@ -///\file +//************************************************************************* +///Decode from Base64 from and to pointer/length +//*************************************************************************///\file /****************************************************************************** The MIT License(MIT) @@ -34,6 +36,7 @@ SOFTWARE. #include "etl/binary.h" #include "etl/algorithm.h" #include "etl/integral_limits.h" +#include "etl/iterator.h" #include @@ -65,136 +68,156 @@ namespace etl } }; + //************************************************************************* + /// Codec for Base64 + //************************************************************************* class base64 { public: + //************************************************************************* + /// Encode to Base64 from and to pointer/length //************************************************************************* template ETL_CONSTEXPR14 static - typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type encode(const T* input, size_t input_length, char* output, size_t output_length) { - etl::span result; + if (input_length == 0U) + { + return 0; + } - int count = 0; + // Figure out if the output buffer is large enough. + size_t required_output_length = (input_length * 8U) / 6U; - if (input_length > 0U) + if ((input_length % 3U) != 0U) { - // Figure out if the output buffer is large enough. - size_t required_output_length = (input_length * 8U) / 6U; - - if ((input_length % 3U) != 0U) + while ((required_output_length % 4U) != 0) { - while ((required_output_length % 4U) != 0) - { - ++required_output_length; - } + ++required_output_length; } + } - ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); - const T* p_in = input; - const T* p_in_end = input + input_length; + 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; + char* p_out = output; + char* p_out_end = output + required_output_length; - int next_sextet = First_Sextet; + 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; - // Step through the input buffer, creating the output sextets. - while (p_in != p_in_end) + switch (next_sextet) { - T c = *p_in; - char index = 0; + //************************** + case First_Sextet: + { + index = static_cast((*p_in & b11111100) >> 2); + next_sextet = Second_Sextet; + break; + } - switch (next_sextet) + //************************** + case Second_Sextet: { - case First_Sextet: - { - index = static_cast((c & b11111100) >> 2); - next_sextet = Second_Sextet; - break; - } + index = static_cast((c & b00000011) << 4); + ++p_in; - case Second_Sextet: + // Next byte valid? + if (p_in != p_in_end) { - index = static_cast((c & b00000011) << 4); - ++p_in; - ++count; - - // Next byte valid? - if (p_in != p_in_end) - { - c = *p_in; - index = index | ((c & b11110000) >> 4); - } - next_sextet = Third_Sextet; - break; + index = index | ((*p_in & b11110000) >> 4); } + next_sextet = Third_Sextet; + break; + } - case Third_Sextet: - { - index = (c & b00001111) << 2; - ++p_in; - ++count; - - // Next byte valid? - if (p_in != p_in_end) - { - c = *p_in; - index = index | static_cast((c & b11000000) >> 6); - } - next_sextet = Fourth_Sextet; - break; - } + //************************** + case Third_Sextet: + { + index = (c & b00001111) << 2; + ++p_in; - case Fourth_Sextet: + // Next byte valid? + if (p_in != p_in_end) { - index = static_cast(c & b00111111); - ++p_in; - ++count; - next_sextet = First_Sextet; - break; + index = index | static_cast((*p_in & b11000000) >> 6); } + next_sextet = Fourth_Sextet; + break; + } - default: - { - // Should never get here. - break; - } + //************************** + case Fourth_Sextet: + { + index = static_cast(c & b00111111); + ++p_in; + next_sextet = First_Sextet; + break; } - *p_out = get_sextet_from_index(index); - ++p_out; + //************************** + default: + { + // Should never get here. + assert(false); + break; + } } - // Pad out the end of the output buffer. - while (p_out != p_out_end) - { - *p_out++ = Padding; - } + *p_out = get_sextet_from_index(index); + ++p_out; + } - result = etl::span(output, p_out); + // Pad out the end of the output buffer. + while (p_out != p_out_end) + { + *p_out++ = padding(); } - return result; + return static_cast(etl::distance(output, p_out)); } + //************************************************************************* + /// Encode to Base64 from and to span/span //************************************************************************* template ETL_CONSTEXPR14 static - typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type - encode(const etl::span& input_span, - const etl::span& output_span) + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + encode(const etl::span& input_span, + const etl::span& output_span) + { + return encode(input_span.begin(), input_span.size(), + output_span.begin(), output_span.size()); + } + + //************************************************************************* + /// Encode to Base64 from and to pointer/pointer + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + encode(const T* input_begin, const T* input_end, char* output_begin, char* output_end) { - return encode(input_span.begin(), input_span.size(), - output_span.begin(), output_span.size()); + return encode(input_begin, static_cast(etl::distance(input_begin, input_end)), + output_begin, static_cast(etl::distance(output_begin, output_end))); } //************************************************************************* + /// Calculates the buffer size required to encode to Base64 + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR14 static size_t encode_size(size_t input_length) @@ -212,98 +235,105 @@ namespace etl return required_output_length; } + //************************************************************************* + /// Decode from Base64 from and to pointer/length //************************************************************************* template ETL_CONSTEXPR14 static - typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type decode(const char* input, size_t input_length, T* output, size_t output_length) { - etl::span result; - - if (input_length > 0) + if (input_length == 0) { - // Figure out if the output buffer is large enough. - size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; - size_t required_output_length = length - (length / 4U); + return 0; + } + + // Figure out if the output buffer is large enough. + size_t length = static_cast(etl::distance(input, etl::find(input, input + input_length, padding())) - 1); + size_t required_output_length = length - (length / 4U); + + ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); - ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + const char* p_in = input; + const char* p_in_end = input + input_length; - const char* p_in = input; - const char* p_in_end = input + input_length; + T* p_out = output; - T* p_out = output; - T* p_out_end = output + output_length; + T c = 0; + int next_sextet = First_Sextet; - 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. - // Step through the input buffer, creating the output binary. - while (p_in != p_in_end) + if (sextet == padding()) { - char sextet = *p_in++; // Get the sextet as a T. + break; + } - if (sextet == Padding) + char index = get_index_from_sextet(sextet); + + switch (next_sextet) + { + //************************** + case First_Sextet: { + c = (index & b00111111) << 2; + next_sextet = Second_Sextet; break; } - char index = get_index_from_sextet(sextet); - - switch (next_sextet) + //************************** + case Second_Sextet: { - case First_Sextet: - { - c = (index & b00111111) << 2; - next_sextet = Second_Sextet; - break; - } - - case Second_Sextet: - { - c |= (index & b00110000) >> 4; - *p_out++ = static_cast(c); - c = (index & b00001111) << 4; - next_sextet = Third_Sextet; - break; - } + c |= (index & b00110000) >> 4; + *p_out++ = static_cast(c); + c = (index & b00001111) << 4; + next_sextet = Third_Sextet; + break; + } - case Third_Sextet: - { - c |= (index & b00111100) >> 2; - *p_out++ = static_cast(c); - c = (index & b00000011) << 6; - next_sextet = Fourth_Sextet; - break; - } + //************************** + case Third_Sextet: + { + c |= (index & b00111100) >> 2; + *p_out++ = static_cast(c); + c = (index & b00000011) << 6; + next_sextet = Fourth_Sextet; + break; + } - case Fourth_Sextet: - { - c |= (index & b00111111); - *p_out++ = static_cast(c); - next_sextet = First_Sextet; - break; - } + //************************** + case Fourth_Sextet: + { + c |= (index & b00111111); + *p_out++ = static_cast(c); + next_sextet = First_Sextet; + break; + } - default: - { - // Should never get here. - break; - } + //************************** + default: + { + // Should never get here. + assert(false); + break; } } - - result = etl::span(output, p_out); } - return result; + return static_cast(etl::distance(output, p_out)); } + //************************************************************************* + /// Decode from Base64 from and to span/span //************************************************************************* template ETL_CONSTEXPR14 static - typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type decode(const etl::span& input_span, const etl::span& output_span) { @@ -311,26 +341,33 @@ namespace etl output_span.begin(), output_span.size()); } - ////************************************************************************* - //template - //ETL_CONSTEXPR14 - //static - //typename etl::enable_if::value && (etl::integral_limits::bits == 8U), etl::span >::type - // decode_size(const etl::span& input_span) - //{ - // // Figure out the minimum output buffer size. - // size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; - // size_t required_output_length = length - (length / 4U); - - // return required_output_length; - //} + //************************************************************************* + /// Decode from Base64 from and to pointer/pointer + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + decode(const char* input_begin, const char* input_end, T* output_begin, T* output_end) + { + return decode(input_begin, static_cast(etl::distance(input_begin, input_end)), + output_begin, static_cast(etl::distance(output_begin, output_end))); + } //************************************************************************* + /// Calculates the buffer size required to decode from Base64 + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR14 static size_t decode_size(const char* input, size_t input_length) { + if (input_length == 0U) + { + return 0U; + } + // Figure out the minimum output buffer size. - size_t length = etl::distance(input, etl::find(input, input + input_length, Padding)) - 1; + size_t length = static_cast(etl::distance(input, etl::find(input, input + input_length, padding())) - 1); size_t required_output_length = length - (length / 4U); return required_output_length; @@ -348,38 +385,92 @@ namespace etl Fourth_Sextet }; - //************************************************************************* - /// The Base64 padding character - static ETL_CONSTANT char Padding = '='; - - //************************************************************************* - // Sextet lookup. - static ETL_CONSTANT char lookup_char[64] = - { - 'A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N' , 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V' , 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd' , 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l' , 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't' , 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1' , '2', '3', - '4', '5', '6', '7', '8', '9' , '+', '/' - }; + // Sextets + // 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + // 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + // 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + // 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + // 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + // 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + // 'w', 'x', 'y', 'z', '0', '1', '2', '3', + // '4', '5', '6', '7', '8', '9', '+', '/' //************************************************************************* // Translates an index into a sextet + //************************************************************************* ETL_CONSTEXPR14 static char get_sextet_from_index(char index) { - return lookup_char[index]; + if ((index >= 0) && (index < 26)) + { + return 'A' + index; + } + else if ((index >= 26) && (index < 52)) + { + index -= 26; + return 'a' + index; + } + else if ((index >= 52) && (index < 62)) + { + index -= 52; + return '0' + index; + } + else if (index == 62) + { + return '+'; + } + else if (index == 63) + { + return '/'; + } + else + { + // Should never get here. + assert(false); + return padding(); + } } //************************************************************************* // Translates a sextet into an index + //************************************************************************* ETL_CONSTEXPR14 static char get_index_from_sextet(char sextet) { - const char* p = etl::find(lookup_char, lookup_char + 64, sextet); + if ((sextet >= 'A') && (sextet <= 'Z')) + { + return sextet - 'A'; + } + else if ((sextet >= 'a') && (sextet <= 'z')) + { + return sextet - 'a' + 26; + } + else if ((sextet >= '0') && (sextet <= '9')) + { + return sextet - '0' + 52; + } + else if (sextet == '+') + { + return 62; + } + else if (sextet == '/') + { + return 63; + } + else + { + // Should never get here. + assert(false); + return 0; + } + } - return static_cast(etl::distance(lookup_char, p)); + //************************************************************************* + /// Gets the padding character + //************************************************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + static char padding() + { + return '='; } }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af3359bd6..e8ecf1830 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(etl_tests test_array_view.cpp test_array_wrapper.cpp test_atomic.cpp + test_base64.cpp test_binary.cpp test_bip_buffer_spsc_atomic.cpp test_bit.cpp diff --git a/test/syntax_check/base64.h.t.cpp b/test/syntax_check/base64.h.t.cpp new file mode 100644 index 000000000..184c72bce --- /dev/null +++ b/test/syntax_check/base64.h.t.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include diff --git a/test/syntax_check/c++03/CMakeLists.txt b/test/syntax_check/c++03/CMakeLists.txt index 79058adcd..7d5f43c1f 100644 --- a/test/syntax_check/c++03/CMakeLists.txt +++ b/test/syntax_check/c++03/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(t98 PRIVATE etl_profile.h ../array_view.h.t.cpp ../array_wrapper.h.t.cpp ../atomic.h.t.cpp + ../base64.h.t.cpp ../basic_format_spec.h.t.cpp ../basic_string.h.t.cpp ../basic_string_stream.h.t.cpp diff --git a/test/syntax_check/c++11/CMakeLists.txt b/test/syntax_check/c++11/CMakeLists.txt index 178387ef0..25a620bb8 100644 --- a/test/syntax_check/c++11/CMakeLists.txt +++ b/test/syntax_check/c++11/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(t11 PRIVATE etl_profile.h ../array_view.h.t.cpp ../array_wrapper.h.t.cpp ../atomic.h.t.cpp + ../base64.h.t.cpp ../basic_format_spec.h.t.cpp ../basic_string.h.t.cpp ../basic_string_stream.h.t.cpp diff --git a/test/syntax_check/c++14/CMakeLists.txt b/test/syntax_check/c++14/CMakeLists.txt index 7eed29fbc..9c28613bf 100644 --- a/test/syntax_check/c++14/CMakeLists.txt +++ b/test/syntax_check/c++14/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(t14 PRIVATE etl_profile.h ../array_view.h.t.cpp ../array_wrapper.h.t.cpp ../atomic.h.t.cpp + ../base64.h.t.cpp ../basic_format_spec.h.t.cpp ../basic_string.h.t.cpp ../basic_string_stream.h.t.cpp diff --git a/test/syntax_check/c++17/CMakeLists.txt b/test/syntax_check/c++17/CMakeLists.txt index fbe3c6d87..3c1fe0baa 100644 --- a/test/syntax_check/c++17/CMakeLists.txt +++ b/test/syntax_check/c++17/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(t17 PRIVATE etl_profile.h ../array_view.h.t.cpp ../array_wrapper.h.t.cpp ../atomic.h.t.cpp + ../base64.h.t.cpp ../basic_format_spec.h.t.cpp ../basic_string.h.t.cpp ../basic_string_stream.h.t.cpp diff --git a/test/syntax_check/c++20/CMakeLists.txt b/test/syntax_check/c++20/CMakeLists.txt index ae020085a..4d05bc196 100644 --- a/test/syntax_check/c++20/CMakeLists.txt +++ b/test/syntax_check/c++20/CMakeLists.txt @@ -46,6 +46,7 @@ target_sources(t20 PRIVATE etl_profile.h ../array_view.h.t.cpp ../array_wrapper.h.t.cpp ../atomic.h.t.cpp + ../base64.h.t.cpp ../basic_format_spec.h.t.cpp ../basic_string.h.t.cpp ../basic_string_stream.h.t.cpp diff --git a/test/test_base64.cpp b/test/test_base64.cpp index 10be6c877..fc4d4ed3e 100644 --- a/test/test_base64.cpp +++ b/test/test_base64.cpp @@ -32,10 +32,12 @@ SOFTWARE. #include #include +#include +#include namespace { - std::array input_data = + std::array input_data_unsigned_char = { 0x3B, 0x27, 0x03, 0x43, 0x2D, 0xFB, 0x28, 0x2A, 0x61, 0xAE, 0xBC, 0x49, 0x71, 0x32, 0x01, 0x15, 0x69, 0x5C, 0x5E, 0xF5, 0xD5, 0x9B, 0xDE, 0xA5, 0x57, 0xC9, 0xC1, 0x7D, 0x80, 0xDE, 0x4C, 0x81, @@ -55,6 +57,26 @@ namespace 0xA8, 0x52, 0x3C, 0x9E, 0xCD, 0xDE, 0x21, 0x34, 0x3E, 0x1F, 0xB5, 0x54, 0xD7, 0xFB, 0xB4, 0xBD }; + std::array input_data_int8_t = + { + int8_t(0x3B), int8_t(0x27), int8_t(0x03), int8_t(0x43), int8_t(0x2D), int8_t(0xFB), int8_t(0x28), int8_t(0x2A), int8_t(0x61), int8_t(0xAE), int8_t(0xBC), int8_t(0x49), int8_t(0x71), int8_t(0x32), int8_t(0x01), int8_t(0x15), + int8_t(0x69), int8_t(0x5C), int8_t(0x5E), int8_t(0xF5), int8_t(0xD5), int8_t(0x9B), int8_t(0xDE), int8_t(0xA5), int8_t(0x57), int8_t(0xC9), int8_t(0xC1), int8_t(0x7D), int8_t(0x80), int8_t(0xDE), int8_t(0x4C), int8_t(0x81), + int8_t(0xC0), int8_t(0xCF), int8_t(0x2A), int8_t(0xD1), int8_t(0x86), int8_t(0x56), int8_t(0xD5), int8_t(0x71), int8_t(0x37), int8_t(0xEB), int8_t(0x80), int8_t(0x32), int8_t(0xDF), int8_t(0xE4), int8_t(0xDF), int8_t(0xB6), + int8_t(0xEE), int8_t(0x3F), int8_t(0xDC), int8_t(0x79), int8_t(0xB3), int8_t(0x17), int8_t(0x8E), int8_t(0x76), int8_t(0x65), int8_t(0x8E), int8_t(0x96), int8_t(0x21), int8_t(0xB9), int8_t(0x88), int8_t(0xD1), int8_t(0x6D), + int8_t(0xD0), int8_t(0xDD), int8_t(0xFF), int8_t(0xDA), int8_t(0xA8), int8_t(0x7A), int8_t(0x4D), int8_t(0xF5), int8_t(0x71), int8_t(0x77), int8_t(0xFD), int8_t(0x2E), int8_t(0xF2), int8_t(0xE4), int8_t(0x40), int8_t(0x72), + int8_t(0x8C), int8_t(0x83), int8_t(0x00), int8_t(0x6F), int8_t(0x13), int8_t(0x72), int8_t(0x53), int8_t(0xE4), int8_t(0x6B), int8_t(0x70), int8_t(0x0E), int8_t(0x37), int8_t(0xCA), int8_t(0x25), int8_t(0xCD), int8_t(0x68), + int8_t(0x62), int8_t(0xC0), int8_t(0xAB), int8_t(0x14), int8_t(0xC7), int8_t(0x59), int8_t(0x83), int8_t(0xD2), int8_t(0x82), int8_t(0x8C), int8_t(0x93), int8_t(0x6D), int8_t(0x13), int8_t(0x21), int8_t(0xC0), int8_t(0x08), + int8_t(0xF9), int8_t(0x6D), int8_t(0xAC), int8_t(0x84), int8_t(0x78), int8_t(0x49), int8_t(0x84), int8_t(0x6F), int8_t(0x6B), int8_t(0xFB), int8_t(0x20), int8_t(0x3B), int8_t(0x9C), int8_t(0x49), int8_t(0xFB), int8_t(0x4E), + int8_t(0x80), int8_t(0x69), int8_t(0x82), int8_t(0x25), int8_t(0x86), int8_t(0x95), int8_t(0xD5), int8_t(0x4D), int8_t(0x91), int8_t(0xED), int8_t(0xD2), int8_t(0x77), int8_t(0x2A), int8_t(0x24), int8_t(0x40), int8_t(0x8A), + int8_t(0xDF), int8_t(0x4D), int8_t(0x80), int8_t(0x2D), int8_t(0xCD), int8_t(0xD5), int8_t(0x5A), int8_t(0x26), int8_t(0xA6), int8_t(0x71), int8_t(0x15), int8_t(0x42), int8_t(0x0E), int8_t(0x3F), int8_t(0xB2), int8_t(0x70), + int8_t(0x14), int8_t(0x29), int8_t(0x1F), int8_t(0x8D), int8_t(0x23), int8_t(0x2E), int8_t(0xC1), int8_t(0xEA), int8_t(0xCE), int8_t(0xF9), int8_t(0x7E), int8_t(0x6C), int8_t(0xDF), int8_t(0x1C), int8_t(0xA3), int8_t(0x84), + int8_t(0x2B), int8_t(0x24), int8_t(0x35), int8_t(0xA7), int8_t(0x63), int8_t(0xC8), int8_t(0x0B), int8_t(0x1F), int8_t(0x8B), int8_t(0xBA), int8_t(0x51), int8_t(0xBF), int8_t(0xE9), int8_t(0x51), int8_t(0x80), int8_t(0xD2), + int8_t(0x23), int8_t(0xB5), int8_t(0xD1), int8_t(0xB4), int8_t(0x59), int8_t(0xAE), int8_t(0x7D), int8_t(0x30), int8_t(0x1D), int8_t(0x00), int8_t(0x1C), int8_t(0xD8), int8_t(0x70), int8_t(0x6C), int8_t(0x16), int8_t(0x71), + int8_t(0xC7), int8_t(0x56), int8_t(0x08), int8_t(0xFE), int8_t(0x81), int8_t(0xAE), int8_t(0xFB), int8_t(0xE0), int8_t(0x92), int8_t(0xD8), int8_t(0xDB), int8_t(0xB9), int8_t(0x57), int8_t(0x7C), int8_t(0x99), int8_t(0xCB), + int8_t(0x42), int8_t(0xEF), int8_t(0xFC), int8_t(0xB3), int8_t(0x56), int8_t(0x1E), int8_t(0xD1), int8_t(0x42), int8_t(0xD3), int8_t(0x0C), int8_t(0x18), int8_t(0xB3), int8_t(0xEE), int8_t(0xAF), int8_t(0x1A), int8_t(0x77), + int8_t(0xA8), int8_t(0x52), int8_t(0x3C), int8_t(0x9E), int8_t(0xCD), int8_t(0xDE), int8_t(0x21), int8_t(0x34), int8_t(0x3E), int8_t(0x1F), int8_t(0xB5), int8_t(0x54), int8_t(0xD7), int8_t(0xFB), int8_t(0xB4), int8_t(0xBD) + }; + std::array encoded = { "", @@ -318,27 +340,210 @@ namespace SUITE(test_base64) { - TEST(test_encode) + //************************************************************************* + TEST(test_encode_unsigned_char_pointer_size) + { + std::array encoded_output; + + 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()); + + std::string expected(encoded[i]); + std::string actual(encoded_output.data(), size); + + CHECK_EQUAL(expected, actual); + CHECK_EQUAL(etl::base64::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_unsigned_char_pointer_pointer) + { + std::array encoded_output; + + 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()); + + std::string expected(encoded[i]); + std::string actual(encoded_output.data(), size); + + CHECK_EQUAL(expected, actual); + CHECK_EQUAL(etl::base64::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_unsigned_char_span) { - constexpr int length = 200; + std::array encoded_output; + + for (size_t i = 0; i < 256; ++i) + { + encoded_output.fill(0); + + etl::span input_span(input_data_unsigned_char.data(), i); + etl::span output_span(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::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_int8_t_pointer_size) + { + std::array encoded_output; + + for (size_t i = 0; i < 256; ++i) + { + encoded_output.fill(0); + + auto size = etl::base64::encode(input_data_int8_t.data(), i, + encoded_output.data(), encoded_output.size()); + + std::string expected(encoded[i]); + std::string actual(encoded_output.data(), size); + + CHECK_EQUAL(expected, actual); + CHECK_EQUAL(etl::base64::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_int8_t_pointer_pointer) + { + std::array encoded_output; + + for (size_t i = 0; i < 256; ++i) + { + encoded_output.fill(0); - constexpr size_t require_encoded_length = etl::base64::encode_size(length); + 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()); - std::array encoded_output; + std::string expected(encoded[i]); + std::string actual(encoded_output.data(), size); - auto result = etl::base64::encode(input_data.data(), length, encoded_output.data(), encoded_output.size()); + CHECK_EQUAL(expected, actual); + CHECK_EQUAL(etl::base64::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_int8_t_span) + { + std::array encoded_output; + + for (size_t i = 0; i < 256; ++i) + { + encoded_output.fill(0); + + etl::span input_span(input_data_int8_t.data(), i); + etl::span output_span(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::encode_size(i), size); + } + } + + //************************************************************************* +#if ETL_USING_CPP14 + template + constexpr auto GetConstexprBase64(const etl::array input) noexcept + { + constexpr size_t encode_size = etl::base64::encode_size(Size); + etl::array output{ 0 }; + + etl::base64::encode(input.begin(), Size, + output._buffer, encode_size); + + return output; + } + + TEST(test_encode_int8_t_constexpr) + { + constexpr etl::array input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + constexpr auto output{ GetConstexprBase64(input) }; + + std::string expected("AAECAwQFBgcICQ=="); + std::string actual(output.data(), output.size()); + + CHECK_EQUAL(expected, actual); + CHECK_EQUAL(etl::base64::encode_size(10), output.size()); + } +#endif + + //************************************************************************* + TEST(test_encode_overflow) + { + std::array encoded_output; + + CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, + encoded_output.data(), encoded_output.size())), etl::base64_overflow); + } + + //************************************************************************* + TEST(test_decode_unsigned_char) + { + std::array 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(), decoded_output.size()); + + CHECK_ARRAY_EQUAL(input_data_unsigned_char.data(), decoded_output.data(), i); + CHECK_EQUAL(i, etl::base64::decode_size(encoded[i].data(), encoded[i].size())); + CHECK_EQUAL(i, decoded_size); + } + } + + //************************************************************************* + TEST(test_decode_int8_t) + { + std::array decoded_output; - std::string expected(encoded[length]); - std::string actual(result.begin(), result.end()); + for (size_t i = 0; i < 256; ++i) + { + decoded_output.fill(0); - bool equal = actual == expected; + auto decoded_size = etl::base64::decode(encoded[i].data(), encoded[i].size(), + decoded_output.data(), decoded_output.size()); - CHECK_EQUAL(require_encoded_length, result.size()); + CHECK_ARRAY_EQUAL(input_data_int8_t.data(), decoded_output.data(), i); + CHECK_EQUAL(i, etl::base64::decode_size(encoded[i].data(), encoded[i].size())); + CHECK_EQUAL(i, decoded_size); + } } - TEST(test_decode) + //************************************************************************* + TEST(test_decode_overflow) { + std::array decoded_output; + CHECK_THROW((etl::base64::decode(encoded[10].data(), encoded[10].size(), + decoded_output.data(), decoded_output.size())), etl::base64_overflow); } }; } diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index f0da849ec..6d02d9024 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3595,10727 +3595,3617 @@ - - true - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true + true - true - true true true - true + true true + true true true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true + true + true true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true + true + true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true + true - true - true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true + true + true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true - true - true + true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true + true - true - true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true - - true - true + true - true - true true true - true + true true + true true true - true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true - - true - true - true + true - true - true true true - true + true true + true true true - true + true + true true - true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true + + + true + true + true + true + true + true + true + true + true true + true + true + + + true true true - true + true true + true true true - true - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true true - true - true - true - true - true - true - true true - true + + + true true true - true + true true + true true true + true + true + true + true + + + true + true + true true + true true - true - true - true - true - true - true - true - true - true - true - true + true + true + true + true + true + true @@ -15573,6 +8463,20 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 641b2fbc3..04a0462b9 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -2282,1160 +2282,1022 @@ Tests\Messaging - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + + Tests\Types - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files - - Tests\Syntax Checks\Source + + UnitTest++\Source Files\Win32 - - Tests\Syntax Checks\Source + + Tests\Types - - Tests\Syntax Checks\Source + + Tests\Patterns - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source - - - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - Tests\Syntax Checks\Source + Tests\Sanity Checks\Source - - Tests\Syntax Checks\Source + + Tests\Sanity Checks\Source - - Tests\Syntax Checks\Source + + Tests\Sanity Checks\Source - - Tests\Syntax Checks\Source + + Tests\Sanity Checks\Source - - Tests\Syntax Checks\Source + + Tests\Sanity Checks\Source - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Atomic - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Initializer List - - Tests\Syntax Checks\Source + + Tests\Error Handler\Log Errors - - Tests\Syntax Checks\Source + + Tests\Error Handler\Exceptions - - Tests\Syntax Checks\Source + + Tests\Messaging - - Tests\Syntax Checks\Source + + Tests\Misc - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Memory & Iterators - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Binary - - Tests\Syntax Checks\Source + + Tests\Strings - - Tests\Syntax Checks\Source + + Tests\Strings - - Tests\Syntax Checks\Source + + Tests\Strings - - Tests\Syntax Checks\Source + + Tests\Strings - - Tests\Syntax Checks\Source + + Tests\CRC - - Tests\Syntax Checks\Source + + Tests\Misc - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Error Handler\Exceptions_And_Log_Errors - - Tests\Syntax Checks\Source + + Tests\State Machines - - Tests\Syntax Checks\Source + + Tests\Containers - - Tests\Syntax Checks\Source + + Tests\Misc - - Tests\Syntax Checks\Source + + Tests\Misc - - Tests\Syntax Checks\Source + + Tests\Codecs - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source - - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Types + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files + + Tests\Syntax Checks\Source - - UnitTest++\Source Files\Win32 + + Tests\Syntax Checks\Source - - Tests\Types + + Tests\Syntax Checks\Source - - Tests\Patterns + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - - Tests\Sanity Checks\Source + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - - Tests\Atomic + + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - - Tests\Initializer List + + Tests\Syntax Checks\Source - - Tests\Error Handler\Log Errors + + Tests\Syntax Checks\Source - - Tests\Error Handler\Exceptions + + Tests\Syntax Checks\Source - - Tests\Messaging + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Misc + + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Memory & Iterators + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Binary + + Tests\Syntax Checks\Source - - Tests\Strings + + Tests\Syntax Checks\Source - - Tests\Strings + + Tests\Syntax Checks\Source - - Tests\Strings + + Tests\Syntax Checks\Source - - Tests\Strings + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\CRC + + Tests\Syntax Checks\Source - - Tests\Misc + + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - + Tests\Syntax Checks\Source - - Tests\Error Handler\Exceptions_And_Log_Errors + + Tests\Syntax Checks\Source - - Tests\State Machines + + Tests\Syntax Checks\Source - - Tests\Containers + + Tests\Syntax Checks\Source - - Tests\Misc + + Tests\Syntax Checks\Source - - Tests\Misc + + Tests\Syntax Checks\Source - - Tests\Codecs + + Tests\Syntax Checks\Source + + + Tests\Syntax Checks\Source @@ -3609,6 +3471,9 @@ Tests\Syntax Checks\C++20 + + Tests\Syntax Checks\Source + From 785d97fb3591854152a1ec93f824b9460edb253d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Oct 2023 11:23:16 +0100 Subject: [PATCH 3/6] Fix maybe-uninitialized warning --- test/test_base64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_base64.cpp b/test/test_base64.cpp index fc4d4ed3e..a104acaf9 100644 --- a/test/test_base64.cpp +++ b/test/test_base64.cpp @@ -495,7 +495,7 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - std::array encoded_output; + std::array encoded_output{ 0 }; CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, encoded_output.data(), encoded_output.size())), etl::base64_overflow); From c9056b6e3addf9f03a6104c11cf91f30a2c41081 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Oct 2023 11:23:16 +0100 Subject: [PATCH 4/6] Fix maybe-uninitialized warning --- test/test_base64.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_base64.cpp b/test/test_base64.cpp index fc4d4ed3e..470cbca71 100644 --- a/test/test_base64.cpp +++ b/test/test_base64.cpp @@ -495,7 +495,7 @@ namespace //************************************************************************* TEST(test_encode_overflow) { - std::array encoded_output; + std::array encoded_output{ 0 }; CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, encoded_output.data(), encoded_output.size())), etl::base64_overflow); @@ -540,7 +540,7 @@ namespace //************************************************************************* TEST(test_decode_overflow) { - std::array decoded_output; + std::array decoded_output{ 0 }; CHECK_THROW((etl::base64::decode(encoded[10].data(), encoded[10].size(), decoded_output.data(), decoded_output.size())), etl::base64_overflow); From 6b7093dc17ecc16a763ef8f9beb706b34f8ae2b7 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Oct 2023 18:51:50 +0100 Subject: [PATCH 5/6] Added etl::string::fill() --- include/etl/basic_string.h | 10 ++++++++++ test/test_string_char.cpp | 16 ++++++++++++++++ test/test_string_u16.cpp | 16 ++++++++++++++++ test/test_string_u16_external_buffer.cpp | 18 ++++++++++++++++++ test/test_string_u32.cpp | 16 ++++++++++++++++ test/test_string_u32_external_buffer.cpp | 18 ++++++++++++++++++ test/test_string_wchar_t.cpp | 16 ++++++++++++++++ test/test_string_wchar_t_external_buffer.cpp | 18 ++++++++++++++++++ 8 files changed, 128 insertions(+) diff --git a/include/etl/basic_string.h b/include/etl/basic_string.h index b9d8a4a1c..cfeaf0717 100644 --- a/include/etl/basic_string.h +++ b/include/etl/basic_string.h @@ -502,6 +502,16 @@ namespace etl p_buffer[new_size] = 0; } + //********************************************************************* + /// Fills the string with the specified character. + /// Does not change the string length. + ///\param value The character used to fill the string. + //********************************************************************* + void fill(T value) + { + etl::fill(begin(), end(), value); + } + //********************************************************************* /// Returns a reference to the value at index 'i' ///\param i The index. diff --git a/test/test_string_char.cpp b/test/test_string_char.cpp index 7cb2c4748..fd7b2f163 100644 --- a/test/test_string_char.cpp +++ b/test/test_string_char.cpp @@ -753,6 +753,22 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + Text text(SIZE, STR('A')); + Text expected(SIZE, STR('B')); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_u16.cpp b/test/test_string_u16.cpp index 6b229c35c..6a848b187 100644 --- a/test/test_string_u16.cpp +++ b/test/test_string_u16.cpp @@ -768,6 +768,22 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + Text text(SIZE, STR('A')); + Text expected(SIZE, STR('B')); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_u16_external_buffer.cpp b/test/test_string_u16_external_buffer.cpp index e89414dd8..a23724303 100644 --- a/test/test_string_u16_external_buffer.cpp +++ b/test/test_string_u16_external_buffer.cpp @@ -917,6 +917,24 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + TextBuffer buffer1{ 0 }; + TextBuffer buffer2{ 0 }; + Text text(11, STR('A'), buffer1.data(), buffer1.size()); + Text expected(11, STR('B'), buffer2.data(), buffer2.size()); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_u32.cpp b/test/test_string_u32.cpp index 3ebb4bdba..b6f1e915f 100644 --- a/test/test_string_u32.cpp +++ b/test/test_string_u32.cpp @@ -768,6 +768,22 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + Text text(SIZE, STR('A')); + Text expected(SIZE, STR('B')); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_u32_external_buffer.cpp b/test/test_string_u32_external_buffer.cpp index 931937e16..76b0ac309 100644 --- a/test/test_string_u32_external_buffer.cpp +++ b/test/test_string_u32_external_buffer.cpp @@ -916,6 +916,24 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + TextBuffer buffer1{ 0 }; + TextBuffer buffer2{ 0 }; + Text text(11, STR('A'), buffer1.data(), buffer1.size()); + Text expected(11, STR('B'), buffer2.data(), buffer2.size()); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_wchar_t.cpp b/test/test_string_wchar_t.cpp index 30820defd..3fad55e93 100644 --- a/test/test_string_wchar_t.cpp +++ b/test/test_string_wchar_t.cpp @@ -768,6 +768,22 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + Text text(SIZE, STR('A')); + Text expected(SIZE, STR('B')); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { diff --git a/test/test_string_wchar_t_external_buffer.cpp b/test/test_string_wchar_t_external_buffer.cpp index cda41521b..f309cffb7 100644 --- a/test/test_string_wchar_t_external_buffer.cpp +++ b/test/test_string_wchar_t_external_buffer.cpp @@ -918,6 +918,24 @@ namespace CHECK_EQUAL(text.size(), NEW_SIZE); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_fill) + { + TextBuffer buffer1{ 0 }; + TextBuffer buffer2{ 0 }; + Text text(11, STR('A'), buffer1.data(), buffer1.size()); + Text expected(11, STR('B'), buffer2.data(), buffer2.size()); + + text.fill(STR('B')); + + bool is_equal = Equal(expected, text); + CHECK(is_equal); + +#if ETL_HAS_STRING_TRUNCATION_CHECKS + CHECK(!text.is_truncated()); +#endif + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_full) { From 5437b4b55a82a2b1b74b266a4d18db090a43ecb1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Oct 2023 13:29:45 +0100 Subject: [PATCH 6/6] Added etl::string interface to etl::base64 --- include/etl/base64.h | 105 ++++++++++++++++------- include/etl/basic_string.h | 4 +- include/etl/vector.h | 4 +- test/test_base64.cpp | 171 +++++++++++++++++++++++++++++++++---- 4 files changed, 232 insertions(+), 52 deletions(-) diff --git a/include/etl/base64.h b/include/etl/base64.h index bc661deb4..32217a964 100644 --- a/include/etl/base64.h +++ b/include/etl/base64.h @@ -30,6 +30,7 @@ SOFTWARE. #include "etl/platform.h" #include "etl/span.h" +#include "etl/static_assert.h" #include "etl/error_handler.h" #include "etl/exception.h" #include "etl/type_traits.h" @@ -37,9 +38,14 @@ SOFTWARE. #include "etl/algorithm.h" #include "etl/integral_limits.h" #include "etl/iterator.h" +#include "etl/string.h" #include +#if ETL_USING_STL + #include +#endif + namespace etl { //*************************************************************************** @@ -90,17 +96,9 @@ namespace etl } // Figure out if the output buffer is large enough. - size_t required_output_length = (input_length * 8U) / 6U; + size_t required_output_length = encode_size(input_length); - if ((input_length % 3U) != 0U) - { - while ((required_output_length % 4U) != 0) - { - ++required_output_length; - } - } - - ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + 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; @@ -187,6 +185,19 @@ namespace etl return static_cast(etl::distance(output, p_out)); } + //************************************************************************* + /// Encode to Base64 from and to pointer/pointer + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + encode(const T* input_begin, const T* input_end, char* output_begin, char* output_end) + { + return encode(input_begin, static_cast(etl::distance(input_begin, input_end)), + output_begin, static_cast(etl::distance(output_begin, output_end))); + } + //************************************************************************* /// Encode to Base64 from and to span/span //************************************************************************* @@ -202,16 +213,51 @@ namespace etl } //************************************************************************* - /// Encode to Base64 from and to pointer/pointer + /// Encode to Base64 from pointer/length to etl::istring //************************************************************************* template ETL_CONSTEXPR14 static typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type - encode(const T* input_begin, const T* input_end, char* output_begin, char* output_end) + encode(const T* input_begin, size_t input_length, + etl::istring& output) { - return encode(input_begin, static_cast(etl::distance(input_begin, input_end)), - output_begin, static_cast(etl::distance(output_begin, output_end))); + output.resize(etl::base64::encode_size(input_length)); + + return encode(input_begin, input_length, + output.data(), output.size()); + } + + //************************************************************************* + /// Encode to Base64 from pointer/pointer to etl::istring + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + encode(const T* input_begin, const T* input_end, + etl::istring& output) + { + output.resize(etl::base64::encode_size(etl::distance(input_begin, input_end))); + + return encode(input_begin, static_cast(etl::distance(input_begin, input_end)), + output.data(), output.size()); + } + + //************************************************************************* + /// Encode to Base64 from span to etl::istring + //************************************************************************* + template + ETL_CONSTEXPR14 + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + encode(const etl::span& input_span, + etl::istring& output) + { + output.resize(etl::base64::encode_size(Length1)); + + return encode(input_span.begin(), input_span.size(), + output.data(), output.size()); } //************************************************************************* @@ -250,10 +296,9 @@ namespace etl } // Figure out if the output buffer is large enough. - size_t length = static_cast(etl::distance(input, etl::find(input, input + input_length, padding())) - 1); - size_t required_output_length = length - (length / 4U); + size_t required_output_length = etl::base64::decode_size(input, input_length); - ETL_ASSERT_OR_RETURN_VALUE(output_length >= required_output_length, ETL_ERROR(base64_overflow), etl::span()); + 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; @@ -328,30 +373,30 @@ namespace etl } //************************************************************************* - /// Decode from Base64 from and to span/span + /// Decode from Base64 from and to pointer/pointer //************************************************************************* - template + template ETL_CONSTEXPR14 static typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type - decode(const etl::span& input_span, - const etl::span& output_span) + decode(const char* input_begin, const char* input_end, T* output_begin, T* output_end) { - return decode(input_span.begin(), input_span.size(), - output_span.begin(), output_span.size()); + return decode(input_begin, static_cast(etl::distance(input_begin, input_end)), + output_begin, static_cast(etl::distance(output_begin, output_end))); } //************************************************************************* - /// Decode from Base64 from and to pointer/pointer + /// Decode from Base64 from and to span/span //************************************************************************* - template + template ETL_CONSTEXPR14 - static - typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type - decode(const char* input_begin, const char* input_end, T* output_begin, T* output_end) + static + typename etl::enable_if::value && (etl::integral_limits::bits == 8U), size_t>::type + decode(const etl::span& input_span, + const etl::span& output_span) { - return decode(input_begin, static_cast(etl::distance(input_begin, input_end)), - output_begin, static_cast(etl::distance(output_begin, output_end))); + return decode(input_span.begin(), input_span.size(), + output_span.begin(), output_span.size()); } //************************************************************************* diff --git a/include/etl/basic_string.h b/include/etl/basic_string.h index cfeaf0717..05d79d3fe 100644 --- a/include/etl/basic_string.h +++ b/include/etl/basic_string.h @@ -173,7 +173,7 @@ namespace etl /// Gets the current size of the string. ///\return The current size of the string. //************************************************************************* - size_type size() const + ETL_CONSTEXPR size_type size() const { return current_size; } @@ -605,7 +605,7 @@ namespace etl /// Returns a const pointer to the beginning of the string data. ///\return A const pointer to the beginning of the string data. //********************************************************************* - const_pointer data() const + ETL_CONSTEXPR const_pointer data() const { return p_buffer; } diff --git a/include/etl/vector.h b/include/etl/vector.h index 23d332976..af236dc7f 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -365,7 +365,7 @@ namespace etl /// Returns a const pointer to the beginning of the vector data. ///\return A const pointer to the beginning of the vector data. //********************************************************************* - const_pointer data() const + ETL_CONSTEXPR const_pointer data() const { return p_buffer; } @@ -974,7 +974,7 @@ namespace etl /// Gets the current size of the vector. ///\return The current size of the vector. //************************************************************************* - size_type size() const + ETL_CONSTEXPR size_type size() const { return size_t(p_end - p_buffer); } diff --git a/test/test_base64.cpp b/test/test_base64.cpp index 470cbca71..b26423e4c 100644 --- a/test/test_base64.cpp +++ b/test/test_base64.cpp @@ -30,6 +30,9 @@ SOFTWARE. #include "etl/base64.h" +#include "etl/string.h" +#include "etl/vector.h" + #include #include #include @@ -349,8 +352,8 @@ namespace { 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); @@ -369,8 +372,8 @@ namespace { 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(), input_data_unsigned_char.data() + i, + encoded_output.data(), encoded_output.data() + encoded_output.size()); std::string expected(encoded[i]); std::string actual(encoded_output.data(), size); @@ -402,6 +405,130 @@ namespace } } + //************************************************************************* + TEST(test_encode_unsigned_char_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_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::encode_size(i), size); + } + } + + //************************************************************************* + TEST(test_encode_unsigned_char_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_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::encode_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 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::encode_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::encode_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::encode_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 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::encode_size(i), size); + } + } + //************************************************************************* TEST(test_encode_int8_t_pointer_size) { @@ -411,8 +538,8 @@ namespace { encoded_output.fill(0); - auto size = etl::base64::encode(input_data_int8_t.data(), i, - encoded_output.data(), encoded_output.size()); + auto size = etl::base64::encode(input_data_int8_t.data(), i, + encoded_output.data(), encoded_output.size()); std::string expected(encoded[i]); std::string actual(encoded_output.data(), size); @@ -431,8 +558,8 @@ namespace { 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(), input_data_int8_t.data() + i, + encoded_output.data(), encoded_output.data() + encoded_output.size()); std::string expected(encoded[i]); std::string actual(encoded_output.data(), size); @@ -472,8 +599,8 @@ namespace constexpr size_t encode_size = etl::base64::encode_size(Size); etl::array output{ 0 }; - etl::base64::encode(input.begin(), Size, - output._buffer, encode_size); + etl::base64::encode(input.begin(), Size, + output._buffer, encode_size); return output; } @@ -497,8 +624,16 @@ namespace { std::array encoded_output{ 0 }; - CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, - encoded_output.data(), encoded_output.size())), etl::base64_overflow); + CHECK_THROW((etl::base64::encode(input_data_unsigned_char.data(), 10, + 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); } //************************************************************************* @@ -510,8 +645,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::decode_size(encoded[i].data(), encoded[i].size())); @@ -528,8 +663,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_int8_t.data(), decoded_output.data(), i); CHECK_EQUAL(i, etl::base64::decode_size(encoded[i].data(), encoded[i].size())); @@ -542,8 +677,8 @@ namespace { std::array decoded_output{ 0 }; - CHECK_THROW((etl::base64::decode(encoded[10].data(), encoded[10].size(), - decoded_output.data(), decoded_output.size())), etl::base64_overflow); + CHECK_THROW((etl::base64::decode(encoded[10].data(), encoded[10].size(), + decoded_output.data(), decoded_output.size())), etl::base64_overflow); } }; }