From 9f976d98b9d706e0f8b77e052271db24ae1428d4 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 24 Sep 2021 09:44:49 +0100 Subject: [PATCH] #428 byte_stream_reader can't be used to read a span of const data --- include/etl/byte_stream.h | 10 +++++----- include/etl/span.h | 38 ++++++++++++++++++++++++++++++++------ test/test_byte_stream.cpp | 31 +++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/include/etl/byte_stream.h b/include/etl/byte_stream.h index f97a6090..45fd3718 100644 --- a/include/etl/byte_stream.h +++ b/include/etl/byte_stream.h @@ -417,11 +417,9 @@ namespace etl /// Read a range of T from the stream. //*************************************************************************** template - typename etl::enable_if::value || etl::is_floating_point::value, bool>::type + typename etl::enable_if::value || etl::is_floating_point::value, etl::optional > >::type read(etl::span range) { - bool result = false; - // Do we have enough room? if (available() >= range.size()) { @@ -432,14 +430,16 @@ namespace etl *destination++ = from_bytes(); } - result = true; + return etl::optional >(etl::span(range.begin(), range.end())); } - return result; + return etl::optional >(); } //*************************************************************************** /// Skip n items of T, up to the maximum space available. + /// Returns true if the skip was possible. + /// Returns false if the full skip size was not possible. //*************************************************************************** template bool skip(size_t n) diff --git a/include/etl/span.h b/include/etl/span.h index 12587528..127e0415 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -44,6 +44,10 @@ SOFTWARE. /// A wrapper for arrays ///\ingroup containers +#if ETL_USING_STL + #include +#endif + namespace etl { static ETL_CONSTANT size_t dynamic_extent = etl::integral_limits::max; @@ -80,22 +84,44 @@ namespace etl } //************************************************************************* - /// Construct from std::array or etl::array or other type that supports + /// Construct from etl::array. + //************************************************************************* + template + ETL_CONSTEXPR span(const etl::array& a) ETL_NOEXCEPT + : mbegin(a.data()) + , mend(a.data() + a.size()) + { + } + +#if ETL_USING_STL + //************************************************************************* + /// Construct from std::array. + //************************************************************************* + template + ETL_CONSTEXPR span(const std::array& a) ETL_NOEXCEPT + : mbegin(a.data()) + , mend(a.data() + a.size()) + { + } +#endif + + //************************************************************************* + /// Construct from a container or other type that supports /// data() and size() member functions. //************************************************************************* - template - ETL_CONSTEXPR span(TSpan& a) ETL_NOEXCEPT + template + ETL_CONSTEXPR span(TContainer& a) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { } //************************************************************************* - /// Construct from std::array or etl::array or other type that supports + /// Construct from a container or other type that supports /// data() and size() member functions. //************************************************************************* - template - ETL_CONSTEXPR span(const TSpan& a) ETL_NOEXCEPT + template + ETL_CONSTEXPR span(const TContainer& a) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { diff --git a/test/test_byte_stream.cpp b/test/test_byte_stream.cpp index b2045624..d840d089 100644 --- a/test/test_byte_stream.cpp +++ b/test/test_byte_stream.cpp @@ -909,8 +909,8 @@ namespace etl::span output(get_data.begin(), get_data.end()); - bool result = reader.read(output); - CHECK(result); + etl::optional > result = reader.read(output); + CHECK(result.has_value()); CHECK_EQUAL(put_data[0], get_data[0]); CHECK_EQUAL(put_data[1], get_data[1]); CHECK_EQUAL(put_data[2], get_data[2]); @@ -1075,12 +1075,31 @@ namespace //************************************************************************* TEST(read_span_int32_t) { - std::array storage = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) }; - std::array get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) }; + std::array storage; + std::array put_data = { int32_t(0x00000001), int32_t(0xA55AA55A), int32_t(0x5AA55AA5), int32_t(0xFFFFFFFF) }; + std::array get_data = { int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000), int32_t(0x00000000) }; - etl::byte_stream_reader reader(reinterpret_cast(storage.data()), storage.size() * sizeof(int32_t)); + etl::span input(put_data.begin(), put_data.end()); - bool result = reader.read(etl::span(get_data.begin(), get_data.end())); + etl::byte_stream_writer writer(storage.data(), storage.size()); + writer.write(input); + + const char* read_only_storage = reinterpret_cast(storage.data()); + etl::byte_stream_reader reader(read_only_storage, storage.size() * sizeof(int32_t)); + + etl::optional > result = reader.read(etl::span(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]); } }; }