#include "vdm/util/bytes.hpp" #include #include #include #include #include #include "vtest.hpp" using vdm::as_bytes; using vdm::as_chars; using vdm::ByteReader; using vdm::ByteSpan; using vdm::ConstByteSpan; using vdm::load_le; using vdm::store_le; VT_TEST(le_roundtrip_u32) { std::array buf{}; store_le(buf, 0x01020304u); // little-endian: least significant byte first VT_CHECK_EQ(std::to_integer(buf[0]), 0x04); VT_CHECK_EQ(std::to_integer(buf[1]), 0x03); VT_CHECK_EQ(std::to_integer(buf[2]), 0x02); VT_CHECK_EQ(std::to_integer(buf[3]), 0x01); VT_CHECK_EQ(load_le(buf), 0x01020304u); } VT_TEST(le_roundtrip_u64) { std::array buf{}; const std::uint64_t v = 0xDEADBEEF0BADF00Dull; store_le(buf, v); VT_CHECK_EQ(load_le(buf), v); } VT_TEST(as_bytes_as_chars_roundtrip) { std::string_view s = "veloxpart"; ConstByteSpan b = as_bytes(s); VT_CHECK_EQ(b.size(), s.size()); VT_CHECK_EQ(std::string(as_chars(b)), std::string(s)); } VT_TEST(byte_reader_sequential_reads) { // magic "VDMP", u16 version=2, u16 flags=0, u64 total=5 std::array buf{}; ByteSpan w(buf); std::memcpy(buf.data(), "VDMP", 4); store_le(w.subspan(4), 2); store_le(w.subspan(6), 0); store_le(w.subspan(8), 5); ByteReader r{ConstByteSpan(buf)}; VT_CHECK_EQ(std::string(as_chars(r.raw(4))), std::string("VDMP")); VT_CHECK_EQ(r.u16(), 2); VT_CHECK_EQ(r.u16(), 0); VT_CHECK_EQ(r.u64(), 5u); VT_CHECK(!r.overran()); VT_CHECK_EQ(r.remaining(), 0u); } VT_TEST(byte_reader_latches_on_overrun) { std::array buf{}; ByteReader r{ConstByteSpan(buf)}; VT_CHECK_EQ(r.u16(), 0); // ok, 2 of 3 consumed VT_CHECK(!r.overran()); VT_CHECK_EQ(r.u32(), 0u); // wants 4, only 1 left -> latch VT_CHECK(r.overran()); VT_CHECK_EQ(r.remaining(), 0u); // further reads stay zero and latched VT_CHECK_EQ(r.u8(), 0); VT_CHECK(r.overran()); } VT_TEST(byte_reader_length_prefixed_string) { std::array buf{}; ByteSpan w(buf); store_le(w, 5); std::memcpy(buf.data() + 4, "hello", 5); ByteReader r{ConstByteSpan(buf)}; VT_CHECK_EQ(std::string(r.lp_string()), std::string("hello")); VT_CHECK(!r.overran()); } VT_TEST(byte_reader_length_prefixed_string_rejects_bogus_length) { std::array buf{}; ByteSpan w(buf); store_le(w, 0xFFFFFFFFu); // claims 4 GiB, only 2 bytes follow ByteReader r{ConstByteSpan(buf)}; std::string_view s = r.lp_string(); VT_CHECK(s.empty()); VT_CHECK(r.overran()); }