#include "foundation/binary_stream.h" #include "test_harness.h" #include #include #include #include using pp::foundation::ByteReader; using pp::foundation::ByteWriter; namespace { void round_trips_little_endian_values(pp::tests::Harness& h) { std::vector bytes; ByteWriter writer(bytes); PP_EXPECT(h, writer.write_u8(0x12U).ok()); PP_EXPECT(h, writer.write_u16_le(0x3456U).ok()); PP_EXPECT(h, writer.write_u32_le(0x789abcdeU).ok()); PP_EXPECT(h, writer.size() == 7U); ByteReader reader(bytes); const auto u8 = reader.read_u8(); const auto u16 = reader.read_u16_le(); const auto u32 = reader.read_u32_le(); PP_EXPECT(h, u8.ok()); PP_EXPECT(h, u8.value() == 0x12U); PP_EXPECT(h, u16.ok()); PP_EXPECT(h, u16.value() == 0x3456U); PP_EXPECT(h, u32.ok()); PP_EXPECT(h, u32.value() == 0x789abcdeU); PP_EXPECT(h, reader.empty()); } void rejects_overread_without_moving_cursor(pp::tests::Harness& h) { const std::array bytes { std::byte { 0x01 }, std::byte { 0x02 }, std::byte { 0x03 }, }; ByteReader reader(bytes); PP_EXPECT(h, reader.seek(2).ok()); const auto before = reader.position(); const auto value = reader.read_u32_le(); PP_EXPECT(h, !value.ok()); PP_EXPECT(h, reader.position() == before); PP_EXPECT(h, reader.remaining() == 1U); } void rejects_out_of_range_seek(pp::tests::Harness& h) { const std::array bytes { std::byte { 0x01 }, std::byte { 0x02 }, }; ByteReader reader(bytes); PP_EXPECT(h, !reader.seek(3).ok()); PP_EXPECT(h, reader.position() == 0U); PP_EXPECT(h, reader.seek(2).ok()); PP_EXPECT(h, reader.empty()); } void boundary_reads_are_consistent(pp::tests::Harness& h) { std::array bytes {}; for (std::size_t i = 0; i < bytes.size(); ++i) { bytes[i] = static_cast(i); } for (std::size_t length = 0; length <= bytes.size(); ++length) { ByteReader reader(std::span(bytes.data(), length)); const auto exact = reader.read_bytes(length); PP_EXPECT(h, exact.ok()); PP_EXPECT(h, exact.value().size() == length); PP_EXPECT(h, reader.empty()); const auto too_much = reader.read_u8(); PP_EXPECT(h, !too_much.ok()); PP_EXPECT(h, reader.position() == length); } } } int main() { pp::tests::Harness harness; harness.run("round_trips_little_endian_values", round_trips_little_endian_values); harness.run("rejects_overread_without_moving_cursor", rejects_overread_without_moving_cursor); harness.run("rejects_out_of_range_seek", rejects_out_of_range_seek); harness.run("boundary_reads_are_consistent", boundary_reads_are_consistent); return harness.finish(); }