GCC Code Coverage Report


Directory: ./
File: libs/http/include/boost/http/sink.hpp
Date: 2026-01-15 20:43:58
Exec Total Coverage
Lines: 8 8 100.0%
Functions: 7 7 100.0%
Branches: 1 1 100.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
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/http
8 //
9
10 #ifndef BOOST_HTTP_SINK_HPP
11 #define BOOST_HTTP_SINK_HPP
12
13 #include <boost/http/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15 #include <boost/core/span.hpp>
16 #include <boost/system/error_code.hpp>
17 #include <cstddef>
18 #include <type_traits>
19
20 namespace boost {
21 namespace http {
22
23 /** An interface for consuming buffers of data.
24
25 This interface abstracts the consumption of
26 a finite stream of data, passed by reading
27 from caller-provided buffers until there
28 is no more input data.
29
30 @par Thread Safety
31 Non-const member functions may not be
32 called concurrently on the same instance.
33
34 @see
35 @ref file_sink,
36 @ref source,
37 @ref parser.
38 */
39 struct BOOST_HTTP_SYMBOL_VISIBLE
40 sink
41 {
42 /** The results of consuming data.
43 */
44 struct results
45 {
46 /** The error, if any occurred.
47 */
48 system::error_code ec;
49
50 /** The number of bytes consumed in the input.
51 */
52 std::size_t bytes = 0;
53
54 /** Accumulate results.
55 */
56 results&
57 operator+=(
58 results const& rv) noexcept;
59
60 #ifdef BOOST_HTTP_AGGREGATE_WORKAROUND
61 constexpr
62 results() = default;
63
64 constexpr
65 results(
66 system::error_code ec_,
67 std::size_t bytes_) noexcept
68 : ec(ec_)
69 , bytes(bytes_)
70 {
71 }
72 #endif
73 };
74
75 /** Consume data.
76
77 This function attempts to write to the
78 sink, by transferring data from the given
79 constant buffer sequence.
80 The return value indicates the number of
81 bytes consumed from the buffers and the
82 error if any occurred.
83
84 @par Preconditions
85 @li This is the first call to `write`, or
86 the last value of `more` was `true`.
87 @li buffer_size(bs) != 0
88
89 @par Postconditions
90 @code
91 rv.ec.failed() == true || rv.bytes == buffer_size(bs)
92 @endcode
93
94 @return The result of the operation.
95
96 @param bs The buffers to use.
97 Each buffer in the sequence will be
98 consumed completely before the next
99 buffer is accessed.
100
101 @param more `true` if there will be one
102 or more subsequent calls to @ref write.
103 */
104 template<class ConstBufferSequence>
105 results
106 18459 write(
107 ConstBufferSequence const& bs,
108 bool more)
109 {
110 static_assert(
111 capy::const_buffer_sequence<ConstBufferSequence>,
112 "Type requirements not met");
113
114 18459 return write_impl(bs, more);
115 }
116
117 protected:
118 /** Derived class override.
119
120 This pure virtual function is called by
121 the implementation and must be overriden.
122 The callee should attempt to consume data
123 from the given constant buffer.
124 The return value must be set to indicate
125 the number of bytes consumed from the
126 buffers, and the error if any occurred.
127
128 @par Preconditions
129 @li This is the first call to `write`, or
130 the last value of `more` was `true`.
131 @li buffer_size(bs) != 0
132
133 @par Postconditions
134 @code
135 rv.ec.failed() == true || rv.bytes == buffer_size(bs)
136 @endcode
137
138 @return The result of the operation.
139
140 @param b The buffer to consume.
141 The result must indicate that the buffer
142 was consumed completely, or that an
143 error occurred.
144
145 @param more `true` if there will be one
146 or more subsequent calls.
147 */
148 virtual
149 results
150 on_write(
151 capy::const_buffer b,
152 bool more) = 0;
153
154 /** Derived class override.
155
156 This pure virtual function is called by
157 the implementation and must be overriden.
158 The callee should attempt to consume data
159 from the given constant buffer sequence.
160 The return value must be set to indicate
161 the number of bytes consumed from the
162 buffers, and the error if any occurred.
163
164 @par Preconditions
165 @li This is the first call to `write`, or
166 the last value of `more` was `true`.
167 @li
168 @code
169 buffer_size(bs) != 0
170 @endcode
171
172 @par Postconditions
173 @code
174 rv.ec.failed() == true || rv.bytes == buffer_size(bs)
175 @endcode
176
177 @return The result of the operation.
178
179 @param bs The buffer sequence to use.
180 Each buffer in the sequence must
181 be completely consumed before data
182 is consumed from the next buffer.
183 The result must indicate that the buffer
184 was consumed completely, or that an
185 error occurred.
186
187 @param more `true` if there will be one
188 or more subsequent calls.
189 */
190 BOOST_HTTP_DECL
191 virtual
192 results
193 on_write(
194 boost::span<const capy::const_buffer> bs,
195 bool more);
196
197 private:
198 results
199 7 write_impl(
200 capy::const_buffer const& b,
201 bool more)
202 {
203 7 return on_write(b, more);
204 }
205
206 results
207 2 write_impl(
208 capy::mutable_buffer const& b,
209 bool more)
210 {
211
1/1
✓ Branch 2 taken 2 times.
2 return on_write(b, more);
212 }
213
214 results
215 5 write_impl(
216 boost::span<const capy::const_buffer> const& bs,
217 bool more)
218 {
219 5 return on_write(bs, more);
220 }
221
222 template<class T>
223 results
224 write_impl(T const&, bool);
225 };
226
227 //------------------------------------------------
228
229 /** A type trait that determines if T is a sink.
230
231 @tparam T The type to check.
232
233 @see
234 @ref sink.
235 */
236 template<class T>
237 using is_sink =
238 std::is_convertible<
239 typename std::decay<T>::type*,
240 sink*>;
241
242 } // http
243 } // boost
244
245 #include <boost/http/impl/sink.hpp>
246
247 #endif
248