GCC Code Coverage Report


Directory: ./
File: libs/beast2/include/boost/beast2/impl/read.hpp
Date: 2025-12-25 12:42:57
Exec Total Coverage
Lines: 52 55 94.5%
Functions: 27 31 87.1%
Branches: 42 66 63.6%

Line Branch Exec Source
1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/beast2
9 //
10
11 #ifndef BOOST_BEAST2_IMPL_READ_HPP
12 #define BOOST_BEAST2_IMPL_READ_HPP
13
14 #include <boost/beast2/detail/except.hpp>
15 #include <boost/http_proto/error.hpp>
16 #include <boost/http_proto/parser.hpp>
17 #include <boost/asio/append.hpp>
18 #include <boost/asio/compose.hpp>
19 #include <boost/asio/coroutine.hpp>
20 #include <boost/asio/immediate.hpp>
21 #include <boost/assert.hpp>
22
23 namespace boost {
24 namespace beast2 {
25
26 namespace detail {
27
28 template<class AsyncStream>
29 class read_until_op
30 : public asio::coroutine
31 {
32 AsyncStream& stream_;
33 http::parser& pr_;
34 std::size_t total_bytes_ = 0;
35 bool (&condition_)(http::parser&);
36
37 public:
38 35315 read_until_op(
39 AsyncStream& s,
40 http::parser& pr,
41 bool (&condition)(http::parser&)) noexcept
42 35315 : stream_(s)
43 35315 , pr_(pr)
44 35315 , condition_(condition)
45 {
46 35315 }
47
48 template<class Self>
49 void
50 156666 operator()(
51 Self& self,
52 system::error_code ec = {},
53 std::size_t bytes_transferred = 0)
54 {
55
4/9
✓ Branch 1 taken 78333 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 35315 times.
✓ Branch 7 taken 29319 times.
✓ Branch 8 taken 13699 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
313332 BOOST_ASIO_CORO_REENTER(*this)
56 {
57
1/1
✓ Branch 1 taken 35315 times.
70630 self.reset_cancellation_state(
58 70630 asio::enable_total_cancellation());
59
60 27392 for(;;)
61 {
62 4 for(;;)
63 {
64
1/1
✓ Branch 1 taken 49013 times.
98026 pr_.parse(ec);
65
2/2
✓ Branch 2 taken 15148 times.
✓ Branch 3 taken 33865 times.
98026 if(ec == http::condition::need_more_input)
66 {
67
2/2
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 15109 times.
30296 if(!!self.cancelled())
68 {
69 78 ec = asio::error::operation_aborted;
70 78 goto upcall;
71 }
72 // specific to http_io::async_read_some
73
7/7
✓ Branch 0 taken 9113 times.
✓ Branch 1 taken 5996 times.
✓ Branch 3 taken 9113 times.
✓ Branch 5 taken 1410 times.
✓ Branch 6 taken 7703 times.
✓ Branch 7 taken 1410 times.
✓ Branch 8 taken 13699 times.
30218 if(total_bytes_ != 0 && condition_(pr_))
74 {
75 2820 ec = {};
76 2820 goto upcall;
77 }
78 27398 break;
79 }
80
7/7
✓ Branch 1 taken 33863 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 33863 times.
✓ Branch 6 taken 33861 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 33863 times.
✓ Branch 9 taken 2 times.
67730 if(ec.failed() || condition_(pr_))
81 {
82
2/2
✓ Branch 0 taken 29319 times.
✓ Branch 1 taken 4544 times.
67726 if(total_bytes_ == 0)
83 {
84
3/10
✗ Branch 3 not taken.
✓ Branch 4 taken 29319 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 29319 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 14 taken 29319 times.
✗ Branch 15 not taken.
175914 BOOST_ASIO_CORO_YIELD
85 {
86 BOOST_ASIO_HANDLER_LOCATION((
87 __FILE__, __LINE__,
88 "immediate"));
89 58638 auto io_ex = self.get_io_executor();
90
2/2
✓ Branch 1 taken 29319 times.
✓ Branch 4 taken 29319 times.
58638 asio::async_immediate(
91 io_ex,
92 58638 asio::append(std::move(self), ec));
93 58638 }
94 }
95 67726 goto upcall;
96 }
97 }
98
3/10
✗ Branch 3 not taken.
✓ Branch 4 taken 13699 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 13699 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 14 taken 13699 times.
✗ Branch 15 not taken.
82194 BOOST_ASIO_CORO_YIELD
99 {
100 BOOST_ASIO_HANDLER_LOCATION((
101 __FILE__, __LINE__,
102 "async_read_some"));
103
1/1
✓ Branch 1 taken 13699 times.
27398 stream_.async_read_some(
104
1/1
✓ Branch 1 taken 13699 times.
54796 pr_.prepare(),
105 27398 std::move(self));
106 }
107
1/1
✓ Branch 1 taken 13699 times.
27398 pr_.commit(bytes_transferred);
108 27398 total_bytes_ += bytes_transferred;
109
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 13699 times.
27398 if(ec == asio::error::eof)
110 {
111 BOOST_ASSERT(
112 bytes_transferred == 0);
113 pr_.commit_eof();
114 ec = {};
115 }
116
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 13696 times.
27398 else if(ec.failed())
117 {
118 6 goto upcall;
119 }
120 }
121
122 70630 upcall:
123
1/1
✓ Branch 1 taken 35315 times.
70630 self.complete(ec, total_bytes_);
124 }
125 156666 }
126 };
127
128 inline
129 bool
130 42932 got_header_condition(http::parser& pr)
131 {
132 42932 return pr.got_header();
133 }
134
135 inline
136 bool
137 44 is_complete_condition(http::parser& pr)
138 {
139 44 return pr.is_complete();
140 }
141
142 } // detail
143
144 //------------------------------------------------
145
146 /** Asynchronously reads some data into the parser.
147
148 This function is used to asynchronously read data from a
149 stream into the parser's input sequence. This function will always
150 keep reading until a complete header is obtained.
151 The function call will invoke the completion token
152 with the following signature:
153 @code
154 void(system::error_code ec
155 std::size_t bytes_transferred);
156 @endcode
157 @note The parser's input sequence may contain additional data
158 beyond what was required to complete the header.
159 @param s The stream to read from.
160 @param pr The parser to read data into.
161 @param token The completion token.
162 */
163 template<
164 class AsyncReadStream,
165 BOOST_ASIO_COMPLETION_TOKEN_FOR(
166 void(system::error_code, std::size_t)) CompletionToken>
167 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
168 void (system::error_code, std::size_t))
169 70626 async_read_some(
170 AsyncReadStream& s,
171 http::parser& pr,
172 CompletionToken&& token)
173 {
174 return asio::async_compose<
175 CompletionToken,
176
1/1
✓ Branch 2 taken 35313 times.
70626 void(system::error_code, std::size_t)>(
177 detail::read_until_op<AsyncReadStream>
178 {s, pr, detail::got_header_condition},
179 token,
180 70626 s);
181 }
182
183 /** Asynchronously reads data into the parser until the header is complete.
184 This function is used to asynchronously read data from a
185 stream into the parser's input sequence until the parser's
186 header is complete.
187 The function call will invoke the completion token
188 with the following signature:
189 @code
190 void(system::error_code ec
191 std::size_t bytes_transferred);
192 @endcode
193 @note The parser's input sequence may contain additional data
194 beyond what was required to complete the header.
195 @param s The stream to read from.
196 @param pr The parser to read data into.
197 @param token The completion token.
198 */
199 template<
200 class AsyncReadStream,
201 BOOST_ASIO_COMPLETION_TOKEN_FOR(
202 void(system::error_code, std::size_t)) CompletionToken>
203 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
204 void (system::error_code, std::size_t))
205 2796 async_read_header(
206 AsyncReadStream& s,
207 http::parser& pr,
208 CompletionToken&& token)
209 {
210 // TODO: async_read_header should not perform a read
211 // operation if `parser::got_header() == true`.
212 2796 return async_read_some(s, pr, std::move(token));
213 }
214
215 /** Asynchronously reads data into the parser until the message is complete.
216 This function is used to asynchronously read data from a
217 stream into the parser's input sequence until the parser's
218 message is complete.
219 The function call will invoke the completion token
220 with the following signature:
221 @code
222 void(system::error_code ec
223 std::size_t bytes_transferred);
224 @endcode
225 @note The parser's input sequence may contain additional data
226 beyond what was required to complete the message.
227 @param s The stream to read from.
228 @param pr The parser to read data into.
229 @param token The completion token.
230 */
231 template<
232 class AsyncReadStream,
233 BOOST_ASIO_COMPLETION_TOKEN_FOR(
234 void(system::error_code, std::size_t)) CompletionToken>
235 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
236 void (system::error_code, std::size_t))
237 2 async_read(
238 AsyncReadStream& s,
239 http::parser& pr,
240 CompletionToken&& token)
241 {
242 return asio::async_compose<
243 CompletionToken,
244
0/1
✗ Branch 2 not taken.
2 void(system::error_code, std::size_t)>(
245 detail::read_until_op<AsyncReadStream>
246 {s, pr, detail::is_complete_condition},
247 token,
248 2 s);
249 }
250
251 } // beast2
252 } // boost
253
254 #endif
255