GCC Code Coverage Report


Directory: ./
File: libs/beast2/include/boost/beast2/impl/read.hpp
Date: 2025-11-20 15:35:53
Exec Total Coverage
Lines: 52 55 94.5%
Functions: 27 30 90.0%
Branches: 41 64 64.1%

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_proto::parser& pr_;
34 std::size_t total_bytes_ = 0;
35 bool (&condition_)(http_proto::parser&);
36
37 public:
38 35315 read_until_op(
39 AsyncStream& s,
40 http_proto::parser& pr,
41 bool (&condition)(http_proto::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
3/7
✗ Branch 2 not taken.
✓ Branch 3 taken 35315 times.
✓ Branch 4 taken 29319 times.
✓ Branch 5 taken 13699 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 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_proto::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 2 not taken.
✓ Branch 3 taken 29319 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 29319 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 29319 times.
✗ Branch 14 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 2 not taken.
✓ Branch 3 taken 13699 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 13699 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 13699 times.
✗ Branch 14 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_proto::parser& pr)
131 {
132 42932 return pr.got_header();
133 }
134
135 inline
136 bool
137 44 is_complete_condition(http_proto::parser& pr)
138 {
139 44 return pr.is_complete();
140 }
141
142 } // detail
143
144 //------------------------------------------------
145
146 template<
147 class AsyncReadStream,
148 BOOST_ASIO_COMPLETION_TOKEN_FOR(
149 void(system::error_code, std::size_t)) CompletionToken>
150 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
151 void (system::error_code, std::size_t))
152 70626 async_read_some(
153 AsyncReadStream& s,
154 http_proto::parser& pr,
155 CompletionToken&& token)
156 {
157 return asio::async_compose<
158 CompletionToken,
159
1/1
✓ Branch 2 taken 35313 times.
70626 void(system::error_code, std::size_t)>(
160 detail::read_until_op<AsyncReadStream>
161 {s, pr, detail::got_header_condition},
162 token,
163 70626 s);
164 }
165
166 template<
167 class AsyncReadStream,
168 BOOST_ASIO_COMPLETION_TOKEN_FOR(
169 void(system::error_code, std::size_t)) CompletionToken>
170 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
171 void (system::error_code, std::size_t))
172 2796 async_read_header(
173 AsyncReadStream& s,
174 http_proto::parser& pr,
175 CompletionToken&& token)
176 {
177 // TODO: async_read_header should not perform a read
178 // operation if `parser::got_header() == true`.
179 2796 return async_read_some(s, pr, std::move(token));
180 }
181
182 template<
183 class AsyncReadStream,
184 BOOST_ASIO_COMPLETION_TOKEN_FOR(
185 void(system::error_code, std::size_t)) CompletionToken>
186 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
187 void (system::error_code, std::size_t))
188 2 async_read(
189 AsyncReadStream& s,
190 http_proto::parser& pr,
191 CompletionToken&& token)
192 {
193 return asio::async_compose<
194 CompletionToken,
195
0/1
✗ Branch 2 not taken.
2 void(system::error_code, std::size_t)>(
196 detail::read_until_op<AsyncReadStream>
197 {s, pr, detail::is_complete_condition},
198 token,
199 2 s);
200 }
201
202 } // beast2
203 } // boost
204
205 #endif
206