GCC Code Coverage Report


Directory: libs/beast2/
File: include/boost/beast2/impl/read.hpp
Date: 2025-11-13 15:50:44
Exec Total Coverage
Lines: 52 55 94.5%
Functions: 29 32 90.6%
Branches: 41 77 53.2%

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 834 read_until_op(
39 AsyncStream& s,
40 http_proto::parser& pr,
41 bool (&condition)(http_proto::parser&)) noexcept
42 834 : stream_(s)
43 834 , pr_(pr)
44 834 , condition_(condition)
45 {
46 834 }
47
48 template<class Self>
49 void
50 3836 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 834 times.
✓ Branch 4 taken 605 times.
✓ Branch 5 taken 479 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
7672 BOOST_ASIO_CORO_REENTER(*this)
56 {
57
1/2
✓ Branch 1 taken 834 times.
✗ Branch 2 not taken.
1668 self.reset_cancellation_state(
58 1668 asio::enable_total_cancellation());
59
60 952 for(;;)
61 {
62 4 for(;;)
63 {
64
1/2
✓ Branch 1 taken 1312 times.
✗ Branch 2 not taken.
2624 pr_.parse(ec);
65
2/2
✓ Branch 2 taken 549 times.
✓ Branch 3 taken 763 times.
2624 if(ec == http_proto::condition::need_more_input)
66 {
67
2/2
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 510 times.
1098 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/8
✓ Branch 0 taken 281 times.
✓ Branch 1 taken 229 times.
✓ Branch 3 taken 281 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 31 times.
✓ Branch 6 taken 250 times.
✓ Branch 7 taken 31 times.
✓ Branch 8 taken 479 times.
1020 if(total_bytes_ != 0 && condition_(pr_))
74 {
75 62 ec = {};
76 62 goto upcall;
77 }
78 958 break;
79 }
80
7/8
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 2 times.
✓ Branch 4 taken 761 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 759 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 761 times.
✓ Branch 9 taken 2 times.
1526 if(ec.failed() || condition_(pr_))
81 {
82
2/2
✓ Branch 0 taken 605 times.
✓ Branch 1 taken 156 times.
1522 if(total_bytes_ == 0)
83 {
84
3/10
✗ Branch 2 not taken.
✓ Branch 3 taken 605 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 605 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 605 times.
✗ Branch 14 not taken.
3630 BOOST_ASIO_CORO_YIELD
85 {
86 BOOST_ASIO_HANDLER_LOCATION((
87 __FILE__, __LINE__,
88 "immediate"));
89 1210 auto io_ex = self.get_io_executor();
90
2/4
✓ Branch 1 taken 605 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 605 times.
✗ Branch 5 not taken.
1210 asio::async_immediate(
91 io_ex,
92 1210 asio::append(std::move(self), ec));
93 1210 }
94 }
95 1522 goto upcall;
96 }
97 }
98
3/10
✗ Branch 2 not taken.
✓ Branch 3 taken 479 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 479 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 13 taken 479 times.
✗ Branch 14 not taken.
2874 BOOST_ASIO_CORO_YIELD
99 {
100 BOOST_ASIO_HANDLER_LOCATION((
101 __FILE__, __LINE__,
102 "async_read_some"));
103
1/2
✓ Branch 1 taken 479 times.
✗ Branch 2 not taken.
958 stream_.async_read_some(
104
1/2
✓ Branch 1 taken 479 times.
✗ Branch 2 not taken.
1916 pr_.prepare(),
105 958 std::move(self));
106 }
107
1/2
✓ Branch 1 taken 479 times.
✗ Branch 2 not taken.
958 pr_.commit(bytes_transferred);
108 958 total_bytes_ += bytes_transferred;
109
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 479 times.
958 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 476 times.
958 else if(ec.failed())
117 {
118 6 goto upcall;
119 }
120 }
121
122 1668 upcall:
123
1/2
✓ Branch 1 taken 834 times.
✗ Branch 2 not taken.
1668 self.complete(ec, total_bytes_);
124 }
125 3836 }
126 };
127
128 inline
129 bool
130 998 got_header_condition(http_proto::parser& pr)
131 {
132 998 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 1664 async_read_some(
153 AsyncReadStream& s,
154 http_proto::parser& pr,
155 CompletionToken&& token)
156 {
157 return asio::async_compose<
158 CompletionToken,
159
1/2
✓ Branch 2 taken 832 times.
✗ Branch 3 not taken.
1664 void(system::error_code, std::size_t)>(
160 detail::read_until_op<AsyncReadStream>
161 {s, pr, detail::got_header_condition},
162 token,
163 1664 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 143 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 143 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/2
✗ Branch 2 not taken.
✗ Branch 3 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