include/boost/burl/detail/parser.hpp

100.0% Lines (12/12) 100.0% List of functions (12/12) 100.0% Branches (1/1)
parser.hpp
f(x) Functions (12)
Function Calls Lines Branches Blocks
boost::burl::detail::parser::decoder::~decoder() :48 40x 100.0% 100.0% boost::burl::detail::parser::parser() :105 3x 100.0% 100.0% boost::burl::detail::parser::parser(boost::burl::detail::parser&&) :112 335x 100.0% 100.0% boost::burl::detail::parser::operator=(boost::burl::detail::parser&&) :115 3x 100.0% 100.0% boost::burl::detail::parser::~parser() :122 530x 100.0% 100.0% boost::burl::detail::parser::header_deleter::operator()(boost::http::detail::header*) const :171 192x 100.0% 100.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read_some<boost::capy::detail::slice_of<boost::capy::mutable_buffer> >(boost::capy::detail::slice_of<boost::capy::mutable_buffer>) :204 9x 100.0% 100.0% 44.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read_some<boost::capy::detail::slice_of<std::span<boost::capy::mutable_buffer const, 18446744073709551615ul> > >(boost::capy::detail::slice_of<std::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >) :204 25x 100.0% 100.0% 44.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer) :204 102x 100.0% 100.0% 44.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read_some<std::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >(std::span<boost::capy::mutable_buffer const, 18446744073709551615ul>) :204 7x 100.0% 100.0% 44.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read<boost::capy::mutable_buffer>(boost::capy::mutable_buffer) :213 5x 100.0% 100.0% boost::capy::task<boost::capy::io_result<unsigned long> > boost::burl::detail::parser::read<std::span<boost::capy::mutable_buffer const, 18446744073709551615ul> >(std::span<boost::capy::mutable_buffer const, 18446744073709551615ul>) :213 14x 100.0% 100.0%
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Mohammad Nejati
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/burl
8 //
9
10 #ifndef BOOST_BURL_DETAIL_PARSER_HPP
11 #define BOOST_BURL_DETAIL_PARSER_HPP
12
13 #include <boost/burl/error.hpp>
14 #include <boost/burl/detail/circular_buffer.hpp>
15
16 #include <boost/capy/buffers/buffer_copy.hpp>
17 #include <boost/capy/buffers/buffer_param.hpp>
18 #include <boost/capy/concept/buffer_source.hpp>
19 #include <boost/capy/io/any_read_stream.hpp>
20 #include <boost/capy/io_task.hpp>
21 #include <boost/capy/read.hpp>
22 #include <boost/http/message_base.hpp>
23 #include <boost/http/header_limits.hpp>
24 #include <boost/http/static_response.hpp>
25 #include <boost/http/static_request.hpp>
26
27 #include <memory>
28
29 namespace boost
30 {
31 namespace burl
32 {
33 namespace detail
34 {
35
36 class parser
37 {
38 public:
39 struct decoder
40 {
41 struct result
42 {
43 std::size_t consumed;
44 std::size_t produced;
45 std::error_code ec;
46 };
47
48 40x virtual ~decoder() = default;
49
50 virtual result
51 process(
52 capy::mutable_buffer out,
53 capy::const_buffer in,
54 bool eof) = 0;
55 };
56
57 struct config
58 {
59 http::header_limits hdr_limits;
60
61 std::size_t in_buffer = 64 * 1024;
62 std::size_t dec_buffer = 8 * 1024;
63 std::uint64_t body_limit = std::uint64_t(-1);
64 };
65
66 bool
67 got_header() const noexcept;
68
69 bool
70 got_body() const noexcept;
71
72 bool
73 has_buffered_data() const noexcept;
74
75 capy::io_task<>
76 read_header();
77
78 void
79 reset(capy::any_read_stream stream) noexcept;
80
81 void
82 set_decoder(decoder* dec) noexcept;
83
84 void
85 set_body_limit(std::uint64_t n) noexcept;
86
87 capy::io_task<std::string_view>
88 read_body();
89
90 template<capy::MutableBufferSequence Buffers>
91 capy::io_task<std::size_t>
92 read_some(Buffers buffers);
93
94 template<capy::MutableBufferSequence Buffers>
95 capy::io_task<std::size_t>
96 read(Buffers buffers);
97
98 capy::io_task<std::span<capy::const_buffer>>
99 pull(std::span<capy::const_buffer> dest);
100
101 void
102 consume(std::size_t n) noexcept;
103
104 protected:
105 3x parser() = default;
106
107 parser(
108 config const& cfg,
109 http::detail::kind kind,
110 capy::any_read_stream stream = {});
111
112 335x parser(parser&& other) noexcept = default;
113
114 parser&
115 3x operator=(parser&& other) noexcept = default;
116
117 parser(const parser&) = delete;
118
119 parser&
120 operator=(const parser&) = delete;
121
122 530x ~parser() = default;
123
124 void
125 start(bool head);
126
127 http::static_response const&
128 get_response() const;
129
130 http::static_request const&
131 get_request() const;
132
133 private:
134 struct chunk_fn;
135
136 std::size_t
137 raw_limit_rem() const noexcept;
138
139 std::size_t
140 dec_limit_rem() const noexcept;
141
142 bool
143 payload_sized() const noexcept;
144
145 std::size_t
146 payload_rem() const noexcept;
147
148 std::size_t
149 table_reserve() const noexcept;
150
151 capy::io_task<>
152 refill();
153
154 std::error_code
155 walk_chunks(chunk_fn f, bool dry = false);
156
157 std::error_code
158 flatten_chunks();
159
160 capy::io_task<std::size_t>
161 decode_some(
162 std::span<capy::mutable_buffer const> buffers);
163
164 capy::io_task<std::size_t>
165 do_read_some(
166 std::span<capy::mutable_buffer const> buffers);
167
168 struct header_deleter
169 {
170 void
171 192x operator()(
172 http::detail::header* h) const noexcept
173 {
174 192x ::operator delete(h);
175 192x }
176 };
177
178 using header_ptr = std::unique_ptr<
179 http::detail::header, header_deleter>;
180
181 http::header_limits hdr_limits_;
182 capy::any_read_stream stream_;
183 header_ptr h_;
184 decoder * dec_ = nullptr;
185 circular_buffer in_;
186 circular_buffer out_;
187 std::uint64_t chunk_rem_ = 0;
188 std::uint64_t transferred_ = 0;
189 std::uint64_t decoded_ = 0;
190 std::uint64_t body_limit_ = 0;
191 std::error_code dec_err_;
192 http::payload payload_ = http::payload::none;
193 bool head_ = false;
194 bool started_ = false;
195 bool got_header_ = false;
196 bool got_body_ = false;
197 bool mid_chunk_ = false;
198 bool fin_chunk_ = false;
199 bool eof_ = false;
200 };
201
202 template<capy::MutableBufferSequence Buffers>
203 capy::io_task<std::size_t>
204
1/1
✓ Branch 1 taken 143 times.
143x parser::
205 read_some(Buffers buffers)
206 {
207 capy::buffer_param bp(buffers);
208 co_return co_await do_read_some(bp.data());
209 286x }
210
211 template<capy::MutableBufferSequence Buffers>
212 capy::io_task<std::size_t>
213 19x parser::
214 read(Buffers buffers)
215 {
216 19x return capy::read(*this, std::move(buffers));
217 }
218
219 } // namespace detail
220 } // namespace burl
221 } // namespace boost
222
223 #endif
224