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/const_buffer_span.hpp>
15 : #include <boost/buffers/type_traits.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 algorithm 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 : struct BOOST_HTTP_PROTO_DECL
35 : sink
36 : {
37 : /** The results of consuming data.
38 : */
39 : struct results
40 : {
41 : /** The error, if any occurred.
42 : */
43 : system::error_code ec;
44 :
45 : /** The number of bytes consumed in the input.
46 : */
47 : std::size_t bytes = 0;
48 :
49 : /** Accumulate results.
50 : */
51 : results&
52 : operator+=(
53 : results const& rv) noexcept;
54 : };
55 :
56 : /** Consume data.
57 :
58 : This function attempts to write to the
59 : sink, by transferring data from the given
60 : constant buffer sequence.
61 : The return value indicates the number of
62 : bytes consumed from the buffers and the
63 : error if any occurred.
64 :
65 : @par Preconditions
66 : @li @ref init was called, and
67 : @li This is the first call to @ref write,
68 : or the last value of `more` was `true`.
69 :
70 : @par Postconditions
71 : @code
72 : rv.ec.failed() == true || rv.bytes == buffer_size(bs)
73 : @endcode
74 :
75 : @return The result of the operation.
76 :
77 : @param bs The buffers to use.
78 : Each buffer in the sequence will be
79 : consumed completely before the next
80 : buffer is accessed.
81 :
82 : @param more `true` if there will be one
83 : or more subsequent calls to @ref write.
84 : */
85 : template<class ConstBufferSequence>
86 : results
87 20397 : write(
88 : ConstBufferSequence const& bs,
89 : bool more)
90 : {
91 : static_assert(
92 : buffers::is_const_buffer_sequence<
93 : ConstBufferSequence>::value,
94 : "Type requirements not met");
95 :
96 20397 : return write_impl(bs, more);
97 : }
98 :
99 : #ifdef BOOST_HTTP_PROTO_DOCS
100 : protected:
101 : #else
102 : private:
103 : #endif
104 : /** Derived class override.
105 :
106 : This pure virtual function is called by
107 : the implementation and must be overriden.
108 : The callee should attempt to consume data
109 : from the given constant buffer.
110 : The return value must be set to indicate
111 : the number of bytes consumed from the
112 : buffers, and the error if any occurred.
113 :
114 : @par Preconditions
115 : @li @ref init was called, and
116 : @li This is the first call to @ref on_write,
117 : or the last value of `more` was `true`.
118 :
119 : @return The result of the operation.
120 :
121 : @param b The buffer to use.
122 : If `more` is true then the results
123 : must indicate that the buffer was
124 : consumed completely, or that an error
125 : occurred.
126 :
127 : @param more `true` if there will be one
128 : or more subsequent calls to @ref write.
129 : */
130 : virtual
131 : results
132 : on_write(
133 : buffers::const_buffer b,
134 : bool more) = 0;
135 :
136 : /** Derived class override.
137 :
138 : This pure virtual function is called by
139 : the implementation and must be overriden.
140 : The callee should attempt to consume data
141 : from the given constant buffer sequence.
142 : The return value must be set to indicate
143 : the number of bytes consumed from the
144 : buffers, and the error if any occurred.
145 :
146 : @par Preconditions
147 : @li @ref init was called, and
148 : @li This is the first call to @ref on_write,
149 : or the last value of `more` was `true`.
150 :
151 : @return The result of the operation.
152 :
153 : @param bs The buffer sequence to use.
154 : Each buffer in the sequence must
155 : be completely consumed before data
156 : is consumed from the next buffer.
157 : If `more` is true then the results
158 : must indicate that the buffer was
159 : consumed completely, or that an error
160 : occurred.
161 :
162 : @param more `true` if there will be one
163 : or more subsequent calls to @ref write.
164 : */
165 : virtual
166 : results
167 : on_write(
168 : buffers::const_buffer_span bs,
169 : bool more);
170 :
171 : private:
172 : results
173 2 : write_impl(
174 : buffers::const_buffer const& b,
175 : bool more)
176 : {
177 2 : return on_write(b, more);
178 : }
179 :
180 : results
181 2 : write_impl(
182 : buffers::mutable_buffer const& b,
183 : bool more)
184 : {
185 2 : return on_write(b, more);
186 : }
187 :
188 : results
189 5 : write_impl(
190 : buffers::const_buffer_span const& bs,
191 : bool more)
192 : {
193 5 : return on_write(bs, more);
194 : }
195 :
196 : template<class T>
197 : results
198 : write_impl(T const&, bool);
199 : };
200 :
201 : //------------------------------------------------
202 :
203 : /** Metafunction which determines if T is a sink
204 :
205 : @see
206 : @ref sink.
207 : */
208 : #ifdef BOOST_HTTP_PROTO_DOCS
209 : template<class T>
210 : using is_sink = __see_below__;
211 : #else
212 : template<class T>
213 : using is_sink =
214 : std::is_convertible<
215 : typename std::decay<T>::type*,
216 : sink*>;
217 : #endif
218 :
219 : } // http_proto
220 : } // boost
221 :
222 : #include <boost/http_proto/impl/sink.hpp>
223 :
224 : #endif
|