fsfw/contrib/fsfw_contrib/etl-20.39.4/test/test_byte_stream.cpp

1353 lines
50 KiB
C++

/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 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/byte_stream.h"
#include "etl/optional.h"
#include "etl/span.h"
#include "etl/array.h"
#include <array>
#include <numeric>
#include <vector>
#include "etl/private/diagnostic_useless_cast_push.h"
namespace
{
//***********************************
struct Object
{
int16_t i;
double d;
uint8_t c;
};
}
namespace etl
{
//***********************************
template <>
void write_unchecked<Object>(etl::byte_stream_writer& stream, const Object& object)
{
stream.write_unchecked(object.i);
stream.write_unchecked(object.d);
stream.write_unchecked(object.c);
}
//***********************************
template <>
bool write<Object>(etl::byte_stream_writer& stream, const Object& object)
{
bool success_i = stream.write(object.i);
bool success_d = stream.write(object.d);
bool success_c = stream.write(object.c);
return success_i && success_d && success_c;
}
//***********************************
template <>
Object read_unchecked<Object>(etl::byte_stream_reader& stream)
{
int16_t i = stream.read_unchecked<int16_t>();
double d = stream.read_unchecked<double>();
uint8_t c = stream.read_unchecked<uint8_t>();
Object object{ i, d, c };
return object;
}
//***********************************
template <>
etl::optional<Object> read<Object>(etl::byte_stream_reader& stream)
{
etl::optional<Object> result;
etl::optional<int16_t> i = stream.read<int16_t>();
etl::optional<double> d = stream.read<double>();
etl::optional<uint8_t> c = stream.read<uint8_t>();
Object object{ i.value(), d.value(), c.value() };
result = object;
return result;
}
}
namespace
{
SUITE(test_byte_stream)
{
//*************************************************************************
TEST(byte_stream_default_properties)
{
char storage[7];
etl::byte_stream_writer writer(storage, ETL_OR_STD17::size(storage), etl::endian::big);
etl::byte_stream_reader reader(storage, writer.size_bytes(), etl::endian::big); // Capacity is zero.
CHECK(writer.empty());
CHECK(reader.empty());
CHECK(!writer.full());
CHECK_EQUAL(0U, writer.size_bytes());
CHECK_EQUAL(0U, reader.size_bytes());
CHECK_EQUAL(ETL_OR_STD17::size(storage), writer.capacity());
CHECK_EQUAL(0U, reader.available<int8_t>());
CHECK_EQUAL(7U, writer.available_bytes());
CHECK_EQUAL(7U, writer.available<int8_t>());
CHECK_EQUAL(3U, writer.available<int16_t>());
CHECK_EQUAL(1U, writer.available<int32_t>());
CHECK_EQUAL(0U, writer.available<int64_t>());
}
//*************************************************************************
TEST(byte_stream_properties)
{
char storage[8];
etl::byte_stream_writer writer(storage, ETL_OR_STD17::size(storage), etl::endian::big);
etl::span<char> storage_span(storage, storage + ETL_OR_STD17::size(storage));
etl::span<char> writer_span = writer.data();
CHECK(writer_span.begin() == storage_span.begin());
CHECK(writer_span.end() == storage_span.end());
CHECK(writer.write(uint8_t(0x12U))); // 1 written.
CHECK(writer.write(uint16_t(0x1234U))); // 2 more written.
etl::span<char> used_span = writer.used_data();
etl::span<char> free_span = writer.free_data();
CHECK_EQUAL(sizeof(uint8_t) + sizeof(uint16_t), (std::distance(used_span.begin(), used_span.end())));
CHECK_EQUAL(ETL_OR_STD17::size(storage) - sizeof(uint8_t) - sizeof(uint16_t), (std::distance(free_span.begin(), free_span.end())));
CHECK(writer.write(uint32_t(0x12345678U))); // 4 more written.
CHECK_FALSE(writer.write(uint32_t(0x12345678U))); // Can't write 4 more.
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<int8_t>());
CHECK_EQUAL(7U, writer.size_bytes());
CHECK_EQUAL(8U, writer.capacity());
etl::byte_stream_reader reader(storage, writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(7U, reader.available<int8_t>());
CHECK_EQUAL(7U, reader.size_bytes());
}
//*************************************************************************
TEST(write_bool)
{
char storage[8];
char result[8] = { 0, 1, 0, 1, 1, 0, 1, 0 };
etl::byte_stream_writer byte_stream(storage, 8U, etl::endian::big);
CHECK(byte_stream.write(false));
CHECK(byte_stream.write(true));
CHECK(byte_stream.write(false));
CHECK(byte_stream.write(true));
CHECK(byte_stream.write(true));
CHECK(byte_stream.write(false));
CHECK(byte_stream.write(true));
CHECK(byte_stream.write(false));
// One too many.
CHECK_FALSE(byte_stream.write(true));
CHECK_ARRAY_EQUAL(result, storage, 8);
}
//*************************************************************************
TEST(write_int8_t)
{
std::array<char, 256> storage;
std::array<char, 256> compare_data;
std::iota(compare_data.begin(), compare_data.end(), 0);
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
for (size_t i = 0; i < 256; ++i)
{
CHECK(byte_stream.write(int8_t(i)));
}
// One too many.
CHECK_FALSE(byte_stream.write(int8_t(0)));
for (size_t i = 0; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_uint8_t)
{
std::array<char, 256> storage;
std::array<char, 256> compare_data;
std::iota(compare_data.begin(), compare_data.end(), 0);
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
for (size_t i = 0U; i < 256U; ++i)
{
CHECK(byte_stream.write(uint8_t(i)));
}
// One too many.
CHECK_FALSE(byte_stream.write(uint8_t(0U)));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_int16_t)
{
std::array<char, sizeof(int16_t) * 4> storage;
std::array<char, sizeof(int16_t) * 4> compare_data = { char(0x00), char(0x01), char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(int16_t(0x0001)));
CHECK(byte_stream.write(int16_t(0x5AA5)));
CHECK(byte_stream.write(int16_t(0xA55A)));
CHECK(byte_stream.write(int16_t(0xFFFF)));
// One too many.
CHECK_FALSE(byte_stream.write(int16_t(0)));
for (size_t i = 0; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_uint16_t)
{
std::array<char, sizeof(uint16_t) * 4> storage;
std::array<char, sizeof(uint16_t) * 4> compare_data = { char(0x00), char(0x01), char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(uint16_t(0x0001U)));
CHECK(byte_stream.write(uint16_t(0x5AA5U)));
CHECK(byte_stream.write(uint16_t(0xA55AU)));
CHECK(byte_stream.write(uint16_t(0xFFFFU)));
// One too many.
CHECK_FALSE(byte_stream.write(uint16_t(0U)));
for (size_t i = 0; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_int32_t)
{
std::array<char, sizeof(int32_t) * 4> storage;
std::array<char, sizeof(int32_t) * 4> compare_data = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0x5A), char(0xA5), char(0xA5), char(0x5A),
char(0xA5), char(0x5A), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(int32_t(0x00000001)));
CHECK(byte_stream.write(int32_t(0x5AA5A55A)));
CHECK(byte_stream.write(int32_t(0xA55A5AA5)));
CHECK(byte_stream.write(int32_t(0xFFFFFFFF)));
// One too many.
CHECK_FALSE(byte_stream.write(int32_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_uint32_t)
{
std::array<char, sizeof(uint32_t) * 4> storage;
std::array<char, sizeof(uint32_t) * 4> compare_data = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0x5A), char(0xA5), char(0xA5), char(0x5A),
char(0xA5), char(0x5A), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(uint32_t(0x00000001U)));
CHECK(byte_stream.write(uint32_t(0x5AA5A55AU)));
CHECK(byte_stream.write(uint32_t(0xA55A5AA5U)));
CHECK(byte_stream.write(uint32_t(0xFFFFFFFFU)));
// One too many.
CHECK_FALSE(byte_stream.write(uint32_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_int64_t)
{
std::array<char, sizeof(int64_t) * 4> storage;
std::array<char, sizeof(int64_t) * 4> compare_data = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0x5A), char(0xA5),
char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0xA5), char(0x5A),
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(int64_t(0x0000000000000001)));
CHECK(byte_stream.write(int64_t(0x5AA5A55AA55A5AA5)));
CHECK(byte_stream.write(int64_t(0xA55A5AA55AA5A55A)));
CHECK(byte_stream.write(int64_t(0xFFFFFFFFFFFFFFFF)));
// One too many.
CHECK_FALSE(byte_stream.write(int64_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_uint64_t)
{
std::array<char, sizeof(uint64_t) * 4> storage;
std::array<char, sizeof(uint64_t) * 4> compare_data = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0x5A), char(0xA5),
char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0xA5), char(0x5A),
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
CHECK(compare_data.size() == storage.size());
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(uint64_t(0x0000000000000001U)));
CHECK(byte_stream.write(uint64_t(0x5AA5A55AA55A5AA5U)));
CHECK(byte_stream.write(uint64_t(0xA55A5AA55AA5A55AU)));
CHECK(byte_stream.write(uint64_t(0xFFFFFFFFFFFFFFFFU)));
// One too many.
CHECK_FALSE(byte_stream.write(uint64_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(write_and_skip_int32_t)
{
std::array<char, sizeof(int32_t) * 4> storage = { char(0xF0), char(0xF1), char(0xF2), char(0xF3),
char(0xF4), char(0xF5), char(0xF6), char(0xF7),
char(0xF8), char(0xF9), char(0xFA), char(0xFB),
char(0xFC), char(0xFD), char(0xFE), char(0xFF) };
std::array<char, sizeof(int32_t) * 4> compare_data = { char(0x01), char(0x02), char(0x03), char(0x04),
char(0xF4), char(0xF5), char(0xF6), char(0xF7),
char(0xF8), char(0xF9), char(0xFA), char(0xFB),
char(0x05), char(0x06), char(0x07), char(0x08) };
etl::byte_stream_writer byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(byte_stream.write(int32_t(0x01020304)));
CHECK(byte_stream.skip<int32_t>(2));
CHECK(byte_stream.write(int32_t(0x05060708)));
CHECK_FALSE(byte_stream.skip<int32_t>(1));
for (size_t i = 0U; i < storage.size(); ++i)
{
CHECK_EQUAL(int(compare_data[i]), int(storage[i]));
}
}
//*************************************************************************
TEST(read_and_skip_int32_t)
{
std::array<char, sizeof(int32_t) * 4> storage = { char(0x01), char(0x02), char(0x03), char(0x04),
char(0xF4), char(0xF5), char(0xF6), char(0xF7),
char(0xF8), char(0xF9), char(0xFA), char(0xFB),
char(0x05), char(0x06), char(0x07), char(0x08) };
std::array<etl::optional<int32_t>, 4> compare = { int32_t(0x01020304), int32_t(0xF4F5F6F7), int32_t(0xF8F9FAFB), int32_t(0x05060708) };
std::array<etl::optional<int32_t>, 4> result = { int32_t(0xF0F1F2F3), int32_t(0xF4F5F6F7), int32_t(0xF8F9FAFB), int32_t(0xFCFDFEFF) };
etl::byte_stream_reader byte_stream(storage.data(), storage.size(), etl::endian::big);
CHECK(result[0] = byte_stream.read<int32_t>());
CHECK(byte_stream.skip<int32_t>(2));
CHECK(result[3] = byte_stream.read<int32_t>());
CHECK_FALSE(byte_stream.skip<int32_t>(2));
for (size_t i = 0U; i < result.size(); ++i)
{
CHECK_EQUAL(compare[i].value(), result[i].value());
}
}
//*************************************************************************
TEST(write_read_bool)
{
std::array<bool, 8> flags =
{
false, true, false, true, true, false, true, false
};
char storage[8];
etl::byte_stream_writer writer(storage, 8, etl::endian::big);
for (size_t i = 0U; i < flags.size(); ++i)
{
writer.write(flags[i]);
}
etl::byte_stream_reader reader(storage, 8, etl::endian::big);
for (size_t i = 0; i < flags.size(); ++i)
{
etl::optional<bool> flag;
CHECK(flag = reader.read<bool>());
CHECK_EQUAL(flags[i], flag.value());
}
}
//*************************************************************************
TEST(write_read_int8_t)
{
std::array<char, 4 * sizeof(int8_t)> storage;
std::array<int8_t, 4> put_data = { int8_t(0x01), int8_t(0x5A), int8_t(0xA5), int8_t(0xFF) };
std::array<etl::optional<int8_t>, 4> get_data = { int8_t(0x00), int8_t(0x00), int8_t(0x00), int8_t(0x00) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<int8_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<int8_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<int8_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<int8_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<int8_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<int8_t>());
CHECK_EQUAL(4U, reader.available_bytes());
CHECK(get_data[0] = reader.read<int8_t>());
CHECK_EQUAL(3U, reader.available<int8_t>());
CHECK_EQUAL(put_data[0], int(get_data[0].value()));
CHECK(get_data[1] = reader.read<int8_t>());
CHECK_EQUAL(2U, reader.available<int8_t>());
CHECK_EQUAL(put_data[1], int(get_data[1].value()));
CHECK(get_data[2] = reader.read<int8_t>());
CHECK_EQUAL(1U, reader.available<int8_t>());
CHECK_EQUAL(put_data[2], int(get_data[2].value()));
CHECK(get_data[3] = reader.read<int8_t>());
CHECK_EQUAL(0U, reader.available<int8_t>());
CHECK_EQUAL(put_data[3], int(get_data[3].value()));
}
//*************************************************************************
TEST(write_read_uint8_t)
{
std::array<char, 4 * sizeof(uint8_t)> storage;
std::array<uint8_t, 4> put_data = { uint8_t(0x01U), uint8_t(0x5AU), uint8_t(0xA5U), uint8_t(0xFFU) };
std::array<etl::optional<uint8_t>, 4> get_data = { uint8_t(0x00U), uint8_t(0x00U), uint8_t(0x00U), uint8_t(0x00U) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<uint8_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<uint8_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<uint8_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<uint8_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<uint8_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<uint8_t>());
CHECK(get_data[0] = reader.read<uint8_t>());
CHECK_EQUAL(3U, reader.available<uint8_t>());
CHECK_EQUAL(put_data[0], int(get_data[0].value()));
CHECK(get_data[1] = reader.read<uint8_t>());
CHECK_EQUAL(2U, reader.available<uint8_t>());
CHECK_EQUAL(put_data[1], int(get_data[1].value()));
CHECK(get_data[2] = reader.read<uint8_t>());
CHECK_EQUAL(1U, reader.available<uint8_t>());
CHECK_EQUAL(put_data[2], int(get_data[2].value()));
CHECK(get_data[3] = reader.read<uint8_t>());
CHECK_EQUAL(0U, reader.available<uint8_t>());
CHECK_EQUAL(put_data[3], int(get_data[3].value()));
}
//*************************************************************************
TEST(write_read_int16_t)
{
std::array<char, 4 * sizeof(int16_t)> storage;
std::array<int16_t, 4> put_data = { int16_t(0x0001), int16_t(0xA55A), int16_t(0x5AA5), int16_t(0xFFFF) };
std::array<etl::optional<int16_t>, 4> get_data = { int16_t(0x0000), int16_t(0x0000), int16_t(0x0000), int16_t(0x0000) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<int16_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<int16_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<int16_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<int16_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<int16_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<int16_t>());
CHECK(get_data[0] = reader.read<int16_t>());
CHECK_EQUAL(3U, reader.available<int16_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<int16_t>());
CHECK_EQUAL(2U, reader.available<int16_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<int16_t>());
CHECK_EQUAL(1U, reader.available<int16_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<int16_t>());
CHECK_EQUAL(0U, reader.available<int16_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_uint16_t)
{
std::array<char, 4 * sizeof(uint16_t)> storage;
std::array<uint16_t, 4> put_data = { uint16_t(0x0001U), uint16_t(0xA55AU), uint16_t(0x5AA5U), uint16_t(0xFFFFU) };
std::array<etl::optional<uint16_t>, 4> get_data = { uint16_t(0x0000U), uint16_t(0x0000U), uint16_t(0x0000U), uint16_t(0x0000U) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<uint16_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<uint16_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<uint16_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<uint16_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<uint16_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<uint16_t>());
CHECK(get_data[0] = reader.read<uint16_t>());
CHECK_EQUAL(3U, reader.available<uint16_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<uint16_t>());
CHECK_EQUAL(2U, reader.available<uint16_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<uint16_t>());
CHECK_EQUAL(1U, reader.available<uint16_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<uint16_t>());
CHECK_EQUAL(0U, reader.available<uint16_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_int32_t)
{
std::array<char, 4 * sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::array<etl::optional<int32_t>, 4> get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<int32_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<int32_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<int32_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<int32_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<int32_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<int32_t>());
CHECK(get_data[0] = reader.read<int32_t>());
CHECK_EQUAL(3U, reader.available<int32_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<int32_t>());
CHECK_EQUAL(2U, reader.available<int32_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<int32_t>());
CHECK_EQUAL(1U, reader.available<int32_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<int32_t>());
CHECK_EQUAL(0U, reader.available<int32_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_uint32_t)
{
std::array<char, 4 * sizeof(uint32_t)> storage;
std::array<uint32_t, 4> put_data = { uint32_t(0x00000001U), uint32_t(0xA55AA55AU), uint32_t(0x5AA55AA5U), uint32_t(0xFFFFFFFFU) };
std::array<etl::optional<uint32_t>, 4> get_data = { uint32_t(0x00000000U), uint32_t(0x00000000U), uint32_t(0x00000000U), uint32_t(0x00000000U) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<uint32_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<uint32_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<uint32_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<uint32_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<uint32_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<uint32_t>());
CHECK(get_data[0] = reader.read<uint32_t>());
CHECK_EQUAL(3U, reader.available<uint32_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<uint32_t>());
CHECK_EQUAL(2U, reader.available<uint32_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<uint32_t>());
CHECK_EQUAL(1U, reader.available<uint32_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<uint32_t>());
CHECK_EQUAL(0U, reader.available<uint32_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_int64_t)
{
std::array<char, 4 * sizeof(int64_t)> storage;
std::array<int64_t, 4> put_data = { int64_t(0x0000000000000001), int64_t(0xA55AA55AA55AA55A), int64_t(0x5AA55AA55AA55AA5), int64_t(0xFFFFFFFFFFFFFFFF) };
std::array<etl::optional<int64_t>, 4> get_data = { int64_t(0x0000000000000000), int64_t(0x0000000000000000), int64_t(0x0000000000000000), int64_t(0x0000000000000000) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<int64_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<int64_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<int64_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<int64_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<int64_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<int64_t>());
CHECK(get_data[0] = reader.read<int64_t>());
CHECK_EQUAL(3U, reader.available<int64_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<int64_t>());
CHECK_EQUAL(2U, reader.available<int64_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<int64_t>());
CHECK_EQUAL(1U, reader.available<int64_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<int64_t>());
CHECK_EQUAL(0U, reader.available<int64_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_uint64_t)
{
std::array<char, 4 * sizeof(uint64_t)> storage;
std::array<uint64_t, 4> put_data = { uint64_t(0x0000000000000001U), uint64_t(0xA55AA55AA55AA55AU), uint64_t(0x5AA55AA55AA55AA5U), uint64_t(0xFFFFFFFFFFFFFFFFU) };
std::array<etl::optional<uint64_t>, 4> get_data = { uint64_t(0x0000000000000000U), uint64_t(0x0000000000000000U), uint64_t(0x0000000000000000U), uint64_t(0x0000000000000000U) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
CHECK(writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(4U, writer.available<uint64_t>());
CHECK_EQUAL(0U, writer.size_bytes());
writer.write(put_data[0]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(3U, writer.available<uint64_t>());
writer.write(put_data[1]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(2U, writer.available<uint64_t>());
writer.write(put_data[2]);
CHECK(!writer.empty());
CHECK(!writer.full());
CHECK_EQUAL(1U, writer.available<uint64_t>());
writer.write(put_data[3]);
CHECK(!writer.empty());
CHECK(writer.full());
CHECK_EQUAL(0U, writer.available<uint64_t>());
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(!reader.empty());
CHECK_EQUAL(4U, reader.available<uint64_t>());
CHECK(get_data[0] = reader.read<uint64_t>());
CHECK_EQUAL(3U, reader.available<uint64_t>());
CHECK_EQUAL(put_data[0], get_data[0].value());
CHECK(get_data[1] = reader.read<uint64_t>());
CHECK_EQUAL(2U, reader.available<uint64_t>());
CHECK_EQUAL(put_data[1], get_data[1].value());
CHECK(get_data[2] = reader.read<uint64_t>());
CHECK_EQUAL(1U, reader.available<uint64_t>());
CHECK_EQUAL(put_data[2], get_data[2].value());
CHECK(get_data[3] = reader.read<uint64_t>());
CHECK_EQUAL(0U, reader.available<uint64_t>());
CHECK_EQUAL(put_data[3], get_data[3].value());
}
//*************************************************************************
TEST(write_read_char_range)
{
std::array<char, 5 * sizeof(char)> storage;
std::array<char, 4> put_data = { char(0x01), char(0x5A), char(0xA5), char(0xFF) };
etl::span<char> input(put_data.begin(), put_data.end());
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
CHECK(writer.write(input));
CHECK(writer.write(char(0x99))); // Write an extra value.
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
etl::optional<etl::span<const char>> output = reader.read<char>(4U);
CHECK_EQUAL(4U, output.value().size());
CHECK_EQUAL(int(put_data[0]), int(output.value()[0]));
CHECK_EQUAL(int(put_data[1]), int(output.value()[1]));
CHECK_EQUAL(int(put_data[2]), int(output.value()[2]));
CHECK_EQUAL(int(put_data[3]), int(output.value()[3]));
etl::optional<char> i = reader.read<char>(); // Read back the extra value to ensure that the current index is correct.
CHECK_EQUAL(int(char(0x99)), int(i.value()));
}
//*************************************************************************
TEST(write_read_int32_t_span_range)
{
std::array<char, 5 * sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::array<int32_t, 4> get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) };
etl::span<int32_t> input(put_data.begin(), put_data.end());
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
CHECK(writer.write(input));
CHECK(writer.write(0x12345678)); // Write an extra value.
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
etl::span<int32_t> output(get_data.begin(), get_data.end());
etl::optional<etl::span<const int32_t> > result = reader.read<int32_t>(output);
CHECK(result.has_value());
CHECK_EQUAL(sizeof(const int32_t), result.value().size());
CHECK_EQUAL(put_data[0], get_data[0]);
CHECK_EQUAL(put_data[1], get_data[1]);
CHECK_EQUAL(put_data[2], get_data[2]);
CHECK_EQUAL(put_data[3], get_data[3]);
etl::optional<int32_t> i = reader.read<int32_t>(); // Read back the extra value to ensure that the current index is correct.
CHECK_EQUAL(0x12345678, i.value());
}
//*************************************************************************
TEST(write_read_int32_t_start_length_range)
{
std::array<char, 5 * sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::array<int32_t, 4> get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
CHECK(writer.write(put_data.data(), put_data.size()));
CHECK(writer.write(0x12345678)); // Write an extra value.
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
etl::optional<etl::span<const int32_t> > result = reader.read<int32_t>(get_data.data(), get_data.size());
CHECK(result.has_value());
CHECK_EQUAL(sizeof(const int32_t), result.value().size());
CHECK_EQUAL(put_data[0], get_data[0]);
CHECK_EQUAL(put_data[1], get_data[1]);
CHECK_EQUAL(put_data[2], get_data[2]);
CHECK_EQUAL(put_data[3], get_data[3]);
etl::optional<int32_t> i = reader.read<int32_t>(); // Read back the extra value to ensure that the current index is correct.
CHECK_EQUAL(0x12345678, i.value());
}
//*************************************************************************
TEST(write_read_multiple_big_endian)
{
char c1 = 90;
char c2 = -91;
unsigned short s1 = 23205;
unsigned short s2 = 42330;
int32_t i1 = 1520786085; // 0x5AA55AA5
int32_t i2 = -1520786086; // 0xA55AA55A
float f = 3.1415927f;
double d = 3.1415927;
std::array<char, 100> storage;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream.
writer.write(c1);
writer.write(s1);
writer.write(i1);
writer.write(f);
writer.write(i2);
writer.write(d);
writer.write(s2);
writer.write(c2);
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
etl::optional<char> rc1;
etl::optional<char> rc2;
etl::optional<unsigned short> rs1;
etl::optional<unsigned short> rs2;
etl::optional<int32_t> ri1;
etl::optional<int32_t> ri2;
etl::optional<float> rf;
etl::optional<double> rd;
// Read them all back.
CHECK(rc1 = reader.read<char>());
CHECK_EQUAL(int(c1), int(rc1.value()));
CHECK(rs1 = reader.read<unsigned short>());
CHECK_EQUAL(s1, rs1.value());
CHECK(ri1 = reader.read<int32_t>());
CHECK_EQUAL(i1, ri1.value());
CHECK(rf = reader.read<float>());
CHECK_CLOSE(f, rf.value(), 0.1f);
CHECK(ri2 = reader.read<int32_t>());
CHECK_EQUAL(i2, ri2.value());
CHECK(rd = reader.read<double>());
CHECK_CLOSE(d, rd.value(), 0.1);
CHECK(rs2 = reader.read<unsigned short>());
CHECK_EQUAL(s2, rs2.value());
CHECK(rc2 = reader.read<char>());
CHECK_EQUAL(int(c2), int(rc2.value()));
}
//*************************************************************************
TEST(write_read_multiple_little_endian)
{
char c1 = 90;
char c2 = -91;
unsigned short s1 = 23205;
unsigned short s2 = 42330;
int32_t i1 = 1520786085; // 0x5AA55AA5
int32_t i2 = -1520786086; // 0xA55AA55A
float f = 3.1415927f;
double d = 3.1415927;
std::array<char, 100> storage;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::little);
// Insert into the stream.
writer.write(c1);
writer.write(s1);
writer.write(i1);
writer.write(f);
writer.write(i2);
writer.write(d);
writer.write(s2);
writer.write(c2);
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::little);
etl::optional<char> rc1;
etl::optional<char> rc2;
etl::optional<unsigned short> rs1;
etl::optional<unsigned short> rs2;
etl::optional<int32_t> ri1;
etl::optional<int32_t> ri2;
etl::optional<float> rf;
etl::optional<double> rd;
// Read them all back.
CHECK(rc1 = reader.read<char>());
CHECK_EQUAL(int(c1), int(rc1.value()));
CHECK(rs1 = reader.read<unsigned short>());
CHECK_EQUAL(s1, rs1.value());
CHECK(ri1 = reader.read<int32_t>());
CHECK_EQUAL(i1, ri1.value());
CHECK(rf = reader.read<float>());
CHECK_CLOSE(f, rf.value(), 0.1f);
CHECK(ri2 = reader.read<int32_t>());
CHECK_EQUAL(i2, ri2.value());
CHECK(rd = reader.read<double>());
CHECK_CLOSE(d, rd.value(), 0.1);
CHECK(rs2 = reader.read<unsigned short>());
CHECK_EQUAL(s2, rs2.value());
CHECK(rc2 = reader.read<char>());
CHECK_EQUAL(int(c2), int(rc2.value()));
}
//*************************************************************************
TEST(write_read_object)
{
std::array<char, 2 * sizeof(Object)> storage;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
Object object1 = { -1234, 2.71578369, 250 };
Object object2 = { 5678, 5.24685744, 126 };
CHECK(etl::write(writer, object1));
CHECK(etl::write(writer, object2));
etl::optional<Object> object1a;
etl::optional<Object> object2a;
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(object1a = etl::read<Object>(reader));
CHECK(object2a = etl::read<Object>(reader));
CHECK_EQUAL(object1.i, object1a.value().i);
CHECK_EQUAL(object1.d, object1a.value().d);
CHECK_EQUAL(int(object1.c), int(object1a.value().c));
CHECK_EQUAL(object2.i, object2a.value().i);
CHECK_EQUAL(object2.d, object2a.value().d);
CHECK_EQUAL(int(object2.c), int(object2a.value().c));
}
//*************************************************************************
TEST(write_read_object_unchecked)
{
std::array<char, 2 * sizeof(Object)> storage;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
Object object1 = { -1234, 2.71578369, 250 };
Object object2 = { 5678, 5.24685744, 126 };
etl::write_unchecked(writer, object1);
etl::write_unchecked(writer, object2);
Object object1a;
Object object2a;
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
object1a = etl::read_unchecked<Object>(reader);
object2a = etl::read_unchecked<Object>(reader);
CHECK_EQUAL(object1.i, object1a.i);
CHECK_EQUAL(object1.d, object1a.d);
CHECK_EQUAL(int(object1.c), int(object1a.c));
CHECK_EQUAL(object2.i, object2a.i);
CHECK_EQUAL(object2.d, object2a.d);
CHECK_EQUAL(int(object2.c), int(object2a.c));
}
//*************************************************************************
TEST(write_read_multiple_float)
{
float f = 3.1415927f;
double d = 3.1415927;
std::array<char, 12> storage;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
writer.write(f);
writer.write(d);
etl::byte_stream_reader reader(storage.data(), storage.size(), etl::endian::big);
etl::optional<float> rf;
etl::optional<double> rd;
CHECK(rf = reader.read<float>());
CHECK_CLOSE(f, rf.value(), 0.1f);
CHECK(rd = reader.read<double>());
CHECK_CLOSE(d, rd.value(), 0.1);
}
//*************************************************************************
TEST(write_read_int16_t_with_skip)
{
std::array<char, 4 * sizeof(int16_t)> storage;
std::array<int16_t, 4> put_data = { int16_t(0x0001), int16_t(0xA55A), int16_t(0x5AA5), int16_t(0xFFFF) };
std::array<etl::optional<int16_t>, 4> get_data = { int16_t(0x0000), int16_t(0x0000), int16_t(0x0000), int16_t(0x0000) };
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
// Insert into the stream
writer.write(put_data[0]);
writer.write(put_data[1]);
writer.write(put_data[2]);
writer.write(put_data[3]);
etl::byte_stream_reader reader(storage.data(), writer.size_bytes(), etl::endian::big);
CHECK(get_data[0] = reader.read<int16_t>());
CHECK_EQUAL(put_data[0], int(get_data[0].value()));
// Skip two int16_t
CHECK(reader.skip<int16_t>(2U));
CHECK(get_data[3] = reader.read<int16_t>());
CHECK_EQUAL(put_data[3], int(get_data[3].value()));
CHECK_EQUAL(int16_t(0x0000), int(get_data[1].value()));
CHECK_EQUAL(int16_t(0x0000), int(get_data[2].value()));
reader.restart();
// Skip five int16_t (too many)
CHECK_FALSE(reader.skip<int16_t>(5U));
}
//*************************************************************************
TEST(read_span_int32_t)
{
std::array<char, 4 * sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::array<int32_t, 4> get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) };
etl::span<int32_t> input(put_data.begin(), put_data.end());
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
writer.write(input);
const char* read_only_storage = reinterpret_cast<const char*>(storage.data());
etl::byte_stream_reader reader(read_only_storage, storage.size() * sizeof(int32_t), etl::endian::big);
etl::optional<etl::span<const int32_t> > result = reader.read(etl::span<int32_t>(get_data.begin(), get_data.end()));
CHECK(result.has_value());
CHECK_EQUAL(int32_t(0x00000001), result.value()[0]);
CHECK_EQUAL(int32_t(0xA55AA55A), result.value()[1]);
CHECK_EQUAL(int32_t(0x5AA55AA5), result.value()[2]);
CHECK_EQUAL(int32_t(0xFFFFFFFF), result.value()[3]);
CHECK_EQUAL(int32_t(0x00000001), get_data[0]);
CHECK_EQUAL(int32_t(0xA55AA55A), get_data[1]);
CHECK_EQUAL(int32_t(0x5AA55AA5), get_data[2]);
CHECK_EQUAL(int32_t(0xFFFFFFFF), get_data[3]);
}
//*************************************************************************
TEST(write_byte_stream_iterative_copy)
{
std::array<char, sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::vector<char> expected = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
std::vector<char> result;
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big);
for (auto i : put_data)
{
writer.write(i);
etl::span<char> s = writer.used_data();
std::copy(s.begin(), s.end(), std::back_inserter(result));
writer.restart();
}
for (size_t i = 0U; i < (4U * sizeof(int32_t)); ++i)
{
CHECK_EQUAL(expected[i], result[i]);
}
}
//*************************************************************************
TEST(write_byte_stream_callback)
{
std::array<char, sizeof(int32_t)> storage;
std::array<int32_t, 4> put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) };
std::vector<char> expected = { char(0x00), char(0x00), char(0x00), char(0x01),
char(0xA5), char(0x5A), char(0xA5), char(0x5A),
char(0x5A), char(0xA5), char(0x5A), char(0xA5),
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
static std::vector<char> result;
etl::byte_stream_writer::callback_type callback([&](etl::byte_stream_writer::callback_parameter_type sp)
{
std::copy(sp.begin(), sp.end(), std::back_inserter(result));
});
etl::byte_stream_writer writer(storage.data(), storage.size(), etl::endian::big, callback);
for (auto i : put_data)
{
writer.write(i);
writer.restart();
}
for (size_t i = 0U; i < (4U * sizeof(int32_t)); ++i)
{
CHECK_EQUAL(expected[i], result[i]);
}
}
//*************************************************************************
TEST(read_byte_stream_skip)
{
etl::array<uint8_t, 4> data;
etl::byte_stream_reader r(data.begin(), data.size(), etl::endian::little);
CHECK_TRUE(r.skip<uint8_t>(4));
etl::optional<etl::span<const uint8_t>> result = r.read<uint8_t>(4);
CHECK_FALSE(result.has_value());
CHECK_TRUE(r.empty());
}
};
}
#include "etl/private/diagnostic_pop.h"