bits.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef CRUCIBLE_PARSING_BITS_INL #define CRUCIBLE_PARSING_BITS_INL #include "crucible/parsing/bits.hpp" #include <climits> namespace crucible::parsing::bits { template<FixedWidthUnsignedIntegerType T> auto LittleEndianUnsignedInteger<T>::operator()(StateType const &state) const -> ResultType { auto const remaining_bytes = state.get_remaining_bytes_in_input(); if (remaining_bytes.size() < sizeof(T)) { return result::reject(state, BitsError { UnexpectedEndOfInput {} }); } T total = 0; for (std::size_t i = 0; i < sizeof(T); ++i) { std::size_t const bits_to_shift = i * CHAR_BIT; auto const byte_value = std::to_integer<T>(remaining_bytes[i]); T const shifted_value = byte_value << bits_to_shift; total |= shifted_value; } auto const next_state = state.advance_by_bytes(sizeof(T)); return result::accept(next_state, total); } template<FixedWidthUnsignedIntegerType T> auto BigEndianUnsignedInteger<T>::operator()(StateType const &state) const -> ResultType { auto const remaining_bytes = state.get_remaining_bytes_in_input(); if (remaining_bytes.size() < sizeof(T)) { return result::reject(state, BitsError { UnexpectedEndOfInput {} }); } T total = 0; for (std::size_t i = 0; i < sizeof(T); ++i) { std::size_t const bits_to_shift = (sizeof(T) - (i + 1)) * CHAR_BIT; auto const byte_value = std::to_integer<T>(remaining_bytes[i]); T const shifted_value = byte_value << bits_to_shift; total |= shifted_value; } auto const next_state = state.advance_by_bytes(sizeof(T)); return result::accept(next_state, total); } } #endif // CRUCIBLE_PARSING_BITS_INL