1#ifndef RPNX_COMPRESSION_IMPLEMENTATION_IO_HPP
2#define RPNX_COMPRESSION_IMPLEMENTATION_IO_HPP
26 template <
typename value_type >
27 [[nodiscard]]
constexpr std::byte
to_byte(value_type value)
noexcept
29 using plain_type = std::remove_cv_t< value_type >;
30 static_assert(std::is_same_v< plain_type, std::byte > || (std::is_integral_v< plain_type > &&
sizeof(plain_type) == 1U),
"compression iterators must contain byte-sized values");
31 if constexpr (std::is_same_v< plain_type, std::byte >)
37 return static_cast< std::byte
>(
static_cast< std::uint8_t
>(value));
47 template <
typename output_iterator >
48 void write_byte(output_iterator& output, std::byte value)
50 if constexpr (
requires { *output = value; })
56 *output = std::to_integer< std::uint8_t >(value);
69 template < std::input_iterator input_iterator, std::sentinel_for< input_iterator > sentinel >
78 byte_reader(input_iterator first, sentinel last) : m_current(std::move(first)), m_last(std::move(last))
86 [[nodiscard]]
bool empty()
const
88 return !m_lookahead.has_value() && m_current == m_last;
96 [[nodiscard]]
bool peek(std::byte& value)
98 if (!m_lookahead.has_value())
100 if (m_current == m_last)
104 m_lookahead =
to_byte(*m_current);
107 value = *m_lookahead;
116 [[nodiscard]]
bool read(std::byte& value)
118 if (m_lookahead.has_value())
120 value = *m_lookahead;
125 if (m_current == m_last)
140 [[nodiscard]]
bool read(std::uint8_t& value)
147 value = std::to_integer< std::uint8_t >(
byte);
155 [[nodiscard]] std::size_t
consumed() const noexcept
161 input_iterator m_current;
163 std::optional< std::byte > m_lookahead;
164 std::size_t m_consumed = 0U;
177 m_checksum ^= std::to_integer< std::uint8_t >(
value);
178 for (std::uint8_t bit = 0U; bit < 8U; ++bit)
180 std::uint32_t
const mask = 0U - (m_checksum & 1U);
181 m_checksum = (m_checksum >> 1U) ^ (0xedb88320U & mask);
189 [[nodiscard]] std::uint32_t
value() const noexcept
195 std::uint32_t m_checksum = 0xffffffffU;
208 constexpr std::uint32_t modulus = 65521U;
209 m_first = (m_first + std::to_integer< std::uint8_t >(
value)) % modulus;
210 m_second = (m_second + m_first) % modulus;
217 [[nodiscard]] std::uint32_t
value() const noexcept
219 return (m_second << 16U) | m_first;
223 std::uint32_t m_first = 1U;
224 std::uint32_t m_second = 0U;
Incremental Adler-32 accumulator.
std::uint32_t value() const noexcept
Returns the checksum for all bytes supplied so far.
void update(std::byte value) noexcept
Includes one byte in the checksum.
bool peek(std::byte &value)
Inspects the next byte without consuming it.
std::size_t consumed() const noexcept
Returns the number of bytes consumed from the source.
byte_reader(input_iterator first, sentinel last)
Constructs a reader over an iterator range.
bool read(std::uint8_t &value)
Reads one byte as an unsigned integer.
bool empty() const
Tests whether no unread byte remains.
bool read(std::byte &value)
Reads one byte.
Incremental reflected IEEE CRC-32 accumulator.
std::uint32_t value() const noexcept
Returns the checksum for all bytes supplied so far.
void update(std::byte value) noexcept
Includes one byte in the checksum.
Internal primitives shared by the format-specific codecs.
void write_byte(output_iterator &output, std::byte value)
Writes one byte through an output iterator and advances it.
constexpr std::byte to_byte(value_type value) noexcept
Converts one supported iterator value to std::byte.