bytes.cpp
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "crucible/parsing/bytes.inl" #include <algorithm> #include <climits> #include <sstream> namespace crucible::parsing::bytes { State::State(std::span<std::byte const> const input) : my_input { input } { } State::State(std::span<std::byte const> const input, std::size_t const offset) : my_input { input }, my_offset { offset } { } auto State::has_remaining_input() const -> bool { return my_offset < my_input.size(); } auto State::get_remaining_input() const -> std::span<std::byte const> { return my_input.subspan(my_offset); } auto State::advance(std::size_t const count) const -> State { return State { my_input, my_offset + count }; } Exact::Exact(std::vector<std::byte> const &bytes) : my_bytes { bytes } { } auto Exact::operator()(StateType const &initial_state) const -> ResultType { auto const &remaining_bytes { initial_state.get_remaining_input() }; if (remaining_bytes.size() < my_bytes.size()) { return errors::make_reject(initial_state, errors::InsufficientInput { my_bytes.size() }); } auto const sequence_begin { my_bytes.begin() }; auto const sequence_end { my_bytes.end() }; auto const input_begin { remaining_bytes.begin() }; bool const is_equal { std::equal(sequence_begin, sequence_end, input_begin) }; if (is_equal) { auto const next_state { initial_state.advance(my_bytes.size()) }; return errors::make_accept(next_state, my_bytes); } else { return errors::make_reject(initial_state, errors::ExpectedExactBytes { my_bytes }); } } Take::Take(std::size_t const count) : my_count { count } { } auto Take::operator()(StateType const &initial_state) const -> ResultType { auto const &remaining_bytes { initial_state.get_remaining_input() }; if (remaining_bytes.size() < my_count) { return errors::make_reject(initial_state, errors::InsufficientInput { my_count }); } auto const result { remaining_bytes.first(my_count) }; auto const next_state { initial_state.advance(my_count) }; return errors::make_accept(next_state, std::vector<std::byte>(result.begin(), result.end())); } auto make_exact(std::vector<std::byte> const &sequence) -> Exact { return { sequence }; } auto make_take(std::size_t const count) -> Take { return { count }; } auto make_u8_le() -> UnsignedInteger<std::uint8_t, Endianness::Le> { return {}; } auto make_u16_le() -> UnsignedInteger<std::uint16_t, Endianness::Le> { return {}; } auto make_u32_le() -> UnsignedInteger<std::uint32_t, Endianness::Le> { return {}; } auto make_u64_le() -> UnsignedInteger<std::uint64_t, Endianness::Le> { return {}; } auto make_u8_be() -> UnsignedInteger<std::uint8_t, Endianness::Be> { return {}; } auto make_u16_be() -> UnsignedInteger<std::uint16_t, Endianness::Be> { return {}; } auto make_u32_be() -> UnsignedInteger<std::uint32_t, Endianness::Be> { return {}; } auto make_u64_be() -> UnsignedInteger<std::uint64_t, Endianness::Be> { return {}; } }