#pragma once #include "binary-reader.hpp" #include "compat/exception.hpp" namespace floormat::Serialize { template template constexpr binary_reader::binary_reader(const Seq& seq) noexcept : it{std::cbegin(seq)}, end{std::cend(seq)} {} template constexpr binary_reader::binary_reader(It begin, It end) noexcept : it{std::move(begin)}, end{std::move(end)} {} template template constexpr T binary_reader::read() noexcept(false) { constexpr size_t N = sizeof(T); fm_soft_assert((ptrdiff_t)N <= std::distance(it, end)); num_bytes_read += N; char buf[N]; for (auto i = 0uz; i < N; i++) buf[i] = *it++; return maybe_byteswap(std::bit_cast(buf)); } template template constexpr std::array binary_reader::read() noexcept(false) { std::array array; if (std::is_constant_evaluated()) array = {}; fm_soft_assert(N <= (size_t)std::distance(it, end)); num_bytes_read += N; for (auto i = 0uz; i < N; i++) array[i] = *it++; return array; } template constexpr void binary_reader::assert_end() noexcept(false) { fm_soft_assert(it == end); } template constexpr void operator>>(binary_reader& reader, T& x) noexcept(false) { x = reader.template read(); } template constexpr void operator<<(T& x, binary_reader& reader) noexcept(false) { x = reader.template read(); } template template constexpr auto binary_reader::read_asciiz_string() noexcept(false) { static_assert(MAX > 0); struct fixed_string final { char buf[MAX]; size_t len; constexpr operator StringView() const noexcept { return { buf, len, StringViewFlag::NullTerminated }; } }; fixed_string ret; for (auto i = 0uz; i < MAX && it != end; i++) { const char c = *it++; ret.buf[i] = c; if (c == '\0') { ret.len = i; num_bytes_read += i+1; return ret; } } fm_throw("can't find string terminator"_cf); } template constexpr StringView binary_reader::read_asciiz_string_() noexcept(false) { It start = it; while (it != end) { num_bytes_read++; if (*it++ == '\0') return StringView{&*start, (size_t)std::distance(start, it) - 1, StringViewFlag::NullTerminated}; } fm_throw("can't find string terminator"_cf); } template constexpr char binary_reader::peek() const { fm_soft_assert(it != end); return *it; } } // namespace floormat::Serialize