diff --git a/include/etl/byte_stream.h b/include/etl/byte_stream.h index 09f7b643..d7e45a17 100644 --- a/include/etl/byte_stream.h +++ b/include/etl/byte_stream.h @@ -46,9 +46,38 @@ SOFTWARE. #include "iterator.h" #include "optional.h" #include "delegate.h" +#include "exception.h" +#include "error_handler.h" namespace etl { + //*************************************************************************** + /// Exception base for byte streams + //*************************************************************************** + class byte_stream_exception : public etl::exception + { + public: + + byte_stream_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + ///\ingroup string + /// String empty exception. + //*************************************************************************** + class byte_stream_overflow : public etl::byte_stream_exception + { + public: + + byte_stream_overflow(string_type file_name_, numeric_type line_number_) + : byte_stream_exception(ETL_ERROR_TEXT("byte_stream:overflow", ETL_BYTE_STREAM_FILE_ID"A"), file_name_, line_number_) + { + } + }; + //*************************************************************************** /// Encodes a byte stream. //*************************************************************************** @@ -134,12 +163,15 @@ namespace etl //*************************************************************************** bool write(bool value) { - bool success = false; + bool success = (available() > 0U); - if (available() > 0U) + if (success) { write_unchecked(value); - success = true; + } + else + { + ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); } return success; @@ -162,12 +194,15 @@ namespace etl typename etl::enable_if::value || etl::is_floating_point::value, bool>::type write(T value) { - bool success = false; + bool success = (available() > 0U); - if (available() > 0U) + if (success) { - write_unchecked(value); - success = true; + write_unchecked(value); + } + else + { + ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); } return success; @@ -196,12 +231,15 @@ namespace etl typename etl::enable_if::value || etl::is_floating_point::value, bool>::type write(const etl::span& range) { - bool success = false; + bool success = (available() >= range.size()); - if (available() >= range.size()) + if (success) { write_unchecked(range); - success = true; + } + else + { + ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); } return success; @@ -228,37 +266,40 @@ namespace etl typename etl::enable_if::value || etl::is_floating_point::value, bool>::type write(const T* start, size_t length) { - bool success = false; + bool success = (available() >= length); - if (available() >= length) + if (success) { write_unchecked(start, length); - success = true; + } + else + { + ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); } return success; } //*************************************************************************** - /// Skip n items of T, up to the maximum space available. + /// Skip n items of T, if the total space is available. /// Returns true if the skip was possible. - /// Returns false if the full skip size was not possible. + /// Returns false if the skip size was not possible. //*************************************************************************** template bool skip(size_t n) { - size_t maximum = available(); + bool success = (available() >= n); - if (n < maximum) + if (success) { step(n * sizeof(T)); - return true; } else { - step(maximum * sizeof(T)); - return false; + ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); } + + return success; } //*************************************************************************** diff --git a/test/test_byte_stream.cpp b/test/test_byte_stream.cpp index 484f0a02..7f26f9f4 100644 --- a/test/test_byte_stream.cpp +++ b/test/test_byte_stream.cpp @@ -153,7 +153,7 @@ namespace CHECK_EQUAL(std::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(!writer.write(uint32_t(0x12345678U))); // Can't write 4 more. + CHECK_THROW(writer.write(uint32_t(0x12345678U)), etl::byte_stream_overflow); // Can't write 4 more. CHECK(!writer.empty()); CHECK(!writer.full()); @@ -186,7 +186,7 @@ namespace CHECK(byte_stream.write(false)); // One too many. - CHECK(!byte_stream.write(true)); + CHECK_THROW(byte_stream.write(true), etl::byte_stream_overflow); CHECK_ARRAY_EQUAL(result, storage, 8); } @@ -207,7 +207,7 @@ namespace } // One too many. - CHECK(!byte_stream.write(int8_t(0))); + CHECK_THROW(byte_stream.write(int8_t(0)), etl::byte_stream_overflow); for (size_t i = 0; i < storage.size(); ++i) { @@ -231,7 +231,7 @@ namespace } // One too many. - CHECK(!byte_stream.write(uint8_t(0U))); + CHECK_THROW(byte_stream.write(uint8_t(0U)), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) { @@ -256,7 +256,7 @@ namespace CHECK(byte_stream.write(int16_t(0xFFFF))); // One too many. - CHECK(!byte_stream.write(int16_t(0))); + CHECK_THROW(byte_stream.write(int16_t(0)), etl::byte_stream_overflow); for (size_t i = 0; i < storage.size(); ++i) { @@ -281,7 +281,7 @@ namespace CHECK(byte_stream.write(uint16_t(0xFFFFU))); // One too many. - CHECK(!byte_stream.write(uint16_t(0U))); + CHECK_THROW(byte_stream.write(uint16_t(0U)), etl::byte_stream_overflow); for (size_t i = 0; i < storage.size(); ++i) { @@ -309,7 +309,7 @@ namespace CHECK(byte_stream.write(int32_t(0xFFFFFFFF))); // One too many. - CHECK(!byte_stream.write(int32_t(0))); + CHECK_THROW(byte_stream.write(int32_t(0)), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) { @@ -337,7 +337,7 @@ namespace CHECK(byte_stream.write(uint32_t(0xFFFFFFFFU))); // One too many. - CHECK(!byte_stream.write(uint32_t(0))); + CHECK_THROW(byte_stream.write(uint32_t(0)), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) { @@ -365,7 +365,7 @@ namespace CHECK(byte_stream.write(int64_t(0xFFFFFFFFFFFFFFFF))); // One too many. - CHECK(!byte_stream.write(int64_t(0))); + CHECK_THROW(byte_stream.write(int64_t(0)), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) { @@ -393,7 +393,7 @@ namespace CHECK(byte_stream.write(uint64_t(0xFFFFFFFFFFFFFFFFU))); // One too many. - CHECK(!byte_stream.write(uint64_t(0))); + CHECK_THROW(byte_stream.write(uint64_t(0)), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) { @@ -420,7 +420,7 @@ namespace CHECK(byte_stream.write(int32_t(0x01020304))); CHECK(byte_stream.skip(2)); CHECK(byte_stream.write(int32_t(0x05060708))); - CHECK(!byte_stream.skip(1)); + CHECK_THROW(byte_stream.skip(1), etl::byte_stream_overflow); for (size_t i = 0U; i < storage.size(); ++i) {