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 errors::make_reject(state, errors::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 { static_cast<T>(byte_value << bits_to_shift) }; total |= shifted_value; } auto const next_state { state.advance_by_bytes(sizeof(T)) }; return errors::make_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 errors::make_reject(state, errors::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 { static_cast<T>(byte_value << bits_to_shift) }; total |= shifted_value; } auto const next_state { state.advance_by_bytes(sizeof(T)) }; return errors::make_accept(next_state, total); } } #endif // CRUCIBLE_PARSING_BITS_INL