#428 byte_stream_reader can't be used to read a span of const data

This commit is contained in:
John Wellbelove 2021-09-24 09:44:49 +01:00
parent 49c9393537
commit 9f976d98b9
3 changed files with 62 additions and 17 deletions

View File

@ -417,11 +417,9 @@ namespace etl
/// Read a range of T from the stream.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_integral<T>::value || etl::is_floating_point<T>::value, bool>::type
typename etl::enable_if<etl::is_integral<T>::value || etl::is_floating_point<T>::value, etl::optional<etl::span<const T> > >::type
read(etl::span<T> range)
{
bool result = false;
// Do we have enough room?
if (available<T>() >= range.size())
{
@ -432,14 +430,16 @@ namespace etl
*destination++ = from_bytes<T>();
}
result = true;
return etl::optional<etl::span<const T> >(etl::span<const T>(range.begin(), range.end()));
}
return result;
return etl::optional<etl::span<const T> >();
}
//***************************************************************************
/// Skip n items of T, up to the maximum space available.
/// Returns <b>true</b> if the skip was possible.
/// Returns <b>false</b> if the full skip size was not possible.
//***************************************************************************
template <typename T>
bool skip(size_t n)

View File

@ -44,6 +44,10 @@ SOFTWARE.
/// A wrapper for arrays
///\ingroup containers
#if ETL_USING_STL
#include <array>
#endif
namespace etl
{
static ETL_CONSTANT size_t dynamic_extent = etl::integral_limits<size_t>::max;
@ -80,22 +84,44 @@ namespace etl
}
//*************************************************************************
/// Construct from std::array or etl::array or other type that supports
/// Construct from etl::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR span(const etl::array<U, N>& a) ETL_NOEXCEPT
: mbegin(a.data())
, mend(a.data() + a.size())
{
}
#if ETL_USING_STL
//*************************************************************************
/// Construct from std::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR span(const std::array<U, N>& 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 <typename TSpan>
ETL_CONSTEXPR span(TSpan& a) ETL_NOEXCEPT
template <typename TContainer>
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 <typename TSpan>
ETL_CONSTEXPR span(const TSpan& a) ETL_NOEXCEPT
template <typename TContainer>
ETL_CONSTEXPR span(const TContainer& a) ETL_NOEXCEPT
: mbegin(a.data())
, mend(a.data() + a.size())
{

View File

@ -909,8 +909,8 @@ namespace
etl::span<int32_t> output(get_data.begin(), get_data.end());
bool result = reader.read<int32_t>(output);
CHECK(result);
etl::optional<etl::span<const int32_t> > result = reader.read<int32_t>(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<const int32_t, 4> storage = { 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) };
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::byte_stream_reader reader(reinterpret_cast<const char*>(storage.data()), storage.size() * sizeof(int32_t));
etl::span<int32_t> input(put_data.begin(), put_data.end());
bool result = reader.read(etl::span<int32_t>(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<const char*>(storage.data());
etl::byte_stream_reader reader(read_only_storage, storage.size() * sizeof(int32_t));
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]);
}
};
}