51namespace orrery::sim {
53static_assert(std::numeric_limits<core::Real>::is_iec559,
54 "The binary formats store the bit pattern of a Real, which assumes IEEE 754");
63using RealBits = std::conditional_t<core::kSinglePrecision, std::uint32_t, std::uint64_t>;
65static_assert(
sizeof(
RealBits) ==
sizeof(core::Real));
68inline constexpr std::size_t
kRealBytes =
sizeof(core::Real);
75inline constexpr std::uint64_t kChecksumPrime = 0x00000100000001b3ULL;
78[[nodiscard]]
constexpr std::uint64_t
checksum_byte(std::uint64_t checksum,
79 std::byte value)
noexcept {
80 return (checksum ^
static_cast<std::uint64_t
>(value)) * kChecksumPrime;
92 explicit BinaryWriter(std::ostream& out) noexcept : out_(&out) {}
94 void write_u8(std::uint8_t value) { write_integer(value, 1); }
96 void write_u32(std::uint32_t value) { write_integer(value, 4); }
98 void write_u64(std::uint64_t value) { write_integer(value, 8); }
111 for (
const core::Real value : values) {
125 write_u32(
static_cast<std::uint32_t
>(text.size()));
130 [[nodiscard]] std::uint64_t
checksum() const noexcept {
return checksum_; }
139 [[nodiscard]]
bool ok() const noexcept {
return out_->good(); }
149 void write_integer(std::uint64_t value, std::size_t width) {
150 std::array<char, 8> bytes{};
151 for (std::size_t index = 0; index < width; ++index) {
152 const auto octet =
static_cast<unsigned char>((value >> (8 * index)) & 0xffU);
153 bytes[index] =
static_cast<char>(octet);
154 checksum_ = checksum_byte(checksum_,
static_cast<std::byte
>(octet));
156 out_->write(bytes.data(),
static_cast<std::streamsize
>(width));
172 explicit BinaryReader(std::istream& in) noexcept : in_(&in) {}
174 [[nodiscard]] std::uint8_t read_u8() {
return static_cast<std::uint8_t
>(read_integer(1)); }
176 [[nodiscard]] std::uint32_t read_u32() {
return static_cast<std::uint32_t
>(read_integer(4)); }
178 [[nodiscard]] std::uint64_t read_u64() {
return read_integer(8); }
180 [[nodiscard]] core::Real read_real() {
186 for (core::Real& value : values) {
205 [[nodiscard]] std::uint64_t
checksum() const noexcept {
return checksum_; }
208 [[nodiscard]]
bool ok() const noexcept {
return in_->good(); }
211 [[nodiscard]] std::uint64_t read_integer(std::size_t width);
std::conditional_t< core::kSinglePrecision, std::uint32_t, std::uint64_t > RealBits
An unsigned integer the same width as Real, which is what a bit pattern is carried in between this fi...
Definition binary_stream.hpp:63
constexpr std::uint64_t checksum_byte(std::uint64_t checksum, std::byte value) noexcept
Fold one byte into a running FNV-1a checksum.
Definition binary_stream.hpp:78
constexpr std::uint64_t kChecksumBasis
The offset basis and prime of 64-bit FNV-1a.
Definition binary_stream.hpp:74
constexpr std::size_t kRealBytes
How many bytes a Real occupies in both formats.
Definition binary_stream.hpp:68
std::uint64_t checksum() const noexcept
The checksum of everything read so far, comparable against the one the writer recorded.
Definition binary_stream.hpp:205
void read_reals(std::span< core::Real > values)
Fill values with that many consecutive Real.
Definition binary_stream.hpp:185
bool ok() const noexcept
Whether every read so far found the bytes it wanted.
Definition binary_stream.hpp:208
std::string read_string(std::size_t limit)
Read a 32-bit length followed by that many bytes.
std::string read_bytes(std::size_t length)
Read exactly length bytes.
bool ok() const noexcept
Whether every write so far reached the stream.
Definition binary_stream.hpp:139
void write_bytes(std::string_view text)
Write the exact bytes of text, with no length prefix and no terminator.
void write_real(core::Real value)
Write a Real as its IEEE 754 bit pattern, four bytes or eight according to the precision this build w...
Definition binary_stream.hpp:106
void write_reals(std::span< const core::Real > values)
Write a contiguous run of Real, which is how both formats carry particle components.
Definition binary_stream.hpp:110
void write_string(std::string_view text)
Write a 32-bit length followed by that many bytes.
Definition binary_stream.hpp:124
std::uint64_t checksum() const noexcept
The checksum of everything written so far.
Definition binary_stream.hpp:130
The scalar and index types that every layer of the project agrees on.