Line data Source code
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_proto
8 : //
9 :
10 : #ifndef BOOST_HTTP_PROTO_SINK_HPP
11 : #define BOOST_HTTP_PROTO_SINK_HPP
12 :
13 : #include <boost/http_proto/detail/config.hpp>
14 : #include <boost/buffers/buffer.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_proto {
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_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_PROTO_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 18450 : write(
107 : ConstBufferSequence const& bs,
108 : bool more)
109 : {
110 : static_assert(
111 : buffers::is_const_buffer_sequence<
112 : ConstBufferSequence>::value,
113 : "Type requirements not met");
114 :
115 18450 : return write_impl(bs, more);
116 : }
117 :
118 : protected:
119 : /** Derived class override.
120 :
121 : This pure virtual function is called by
122 : the implementation and must be overriden.
123 : The callee should attempt to consume data
124 : from the given constant buffer.
125 : The return value must be set to indicate
126 : the number of bytes consumed from the
127 : buffers, and the error if any occurred.
128 :
129 : @par Preconditions
130 : @li This is the first call to `write`, or
131 : the last value of `more` was `true`.
132 : @li buffer_size(bs) != 0
133 :
134 : @par Postconditions
135 : @code
136 : rv.ec.failed() == true || rv.bytes == buffer_size(bs)
137 : @endcode
138 :
139 : @return The result of the operation.
140 :
141 : @param b The buffer to consume.
142 : The result must indicate that the buffer
143 : was consumed completely, or that an
144 : error occurred.
145 :
146 : @param more `true` if there will be one
147 : or more subsequent calls.
148 : */
149 : virtual
150 : results
151 : on_write(
152 : buffers::const_buffer b,
153 : bool more) = 0;
154 :
155 : /** Derived class override.
156 :
157 : This pure virtual function is called by
158 : the implementation and must be overriden.
159 : The callee should attempt to consume data
160 : from the given constant buffer sequence.
161 : The return value must be set to indicate
162 : the number of bytes consumed from the
163 : buffers, and the error if any occurred.
164 :
165 : @par Preconditions
166 : @li This is the first call to `write`, or
167 : the last value of `more` was `true`.
168 : @li
169 : @code
170 : buffer_size(bs) != 0
171 : @endcode
172 :
173 : @par Postconditions
174 : @code
175 : rv.ec.failed() == true || rv.bytes == buffer_size(bs)
176 : @endcode
177 :
178 : @return The result of the operation.
179 :
180 : @param bs The buffer sequence to use.
181 : Each buffer in the sequence must
182 : be completely consumed before data
183 : is consumed from the next buffer.
184 : The result must indicate that the buffer
185 : was consumed completely, or that an
186 : error occurred.
187 :
188 : @param more `true` if there will be one
189 : or more subsequent calls.
190 : */
191 : BOOST_HTTP_PROTO_DECL
192 : virtual
193 : results
194 : on_write(
195 : bool boost_span_issue_202_workaround,
196 : boost::span<const buffers::const_buffer> bs,
197 : bool more);
198 :
199 : private:
200 : results
201 7 : write_impl(
202 : buffers::const_buffer const& b,
203 : bool more)
204 : {
205 7 : return on_write(b, more);
206 : }
207 :
208 : results
209 2 : write_impl(
210 : buffers::mutable_buffer const& b,
211 : bool more)
212 : {
213 2 : return on_write(b, more);
214 : }
215 :
216 : // results
217 : // write_impl(
218 : // boost::span<const buffers::const_buffer> const& bs,
219 : // bool more)
220 : // {
221 : // return on_write(bs, more);
222 : // }
223 :
224 : template<class T>
225 : results
226 : write_impl(T const&, bool);
227 : };
228 :
229 : //------------------------------------------------
230 :
231 : /** A type trait that determines if T is a sink.
232 :
233 : @tparam T The type to check.
234 :
235 : @see
236 : @ref sink.
237 : */
238 : template<class T>
239 : using is_sink =
240 : std::is_convertible<
241 : typename std::decay<T>::type*,
242 : sink*>;
243 :
244 : } // http_proto
245 : } // boost
246 :
247 : #include <boost/http_proto/impl/sink.hpp>
248 :
249 : #endif
|