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_SYMBOL_VISIBLE
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 : BOOST_HTTP_PROTO_DECL
166 : virtual
167 : results
168 : on_write(
169 : buffers::const_buffer_span bs,
170 : bool more);
171 :
172 : private:
173 : results
174 2 : write_impl(
175 : buffers::const_buffer const& b,
176 : bool more)
177 : {
178 2 : return on_write(b, more);
179 : }
180 :
181 : results
182 2 : write_impl(
183 : buffers::mutable_buffer const& b,
184 : bool more)
185 : {
186 2 : return on_write(b, more);
187 : }
188 :
189 : results
190 5 : write_impl(
191 : buffers::const_buffer_span const& bs,
192 : bool more)
193 : {
194 5 : return on_write(bs, more);
195 : }
196 :
197 : template<class T>
198 : results
199 : write_impl(T const&, bool);
200 : };
201 :
202 : //------------------------------------------------
203 :
204 : /** Metafunction which determines if T is a sink
205 :
206 : @see
207 : @ref sink.
208 : */
209 : #ifdef BOOST_HTTP_PROTO_DOCS
210 : template<class T>
211 : using is_sink = __see_below__;
212 : #else
213 : template<class T>
214 : using is_sink =
215 : std::is_convertible<
216 : typename std::decay<T>::type*,
217 : sink*>;
218 : #endif
219 :
220 : } // http_proto
221 : } // boost
222 :
223 : #include <boost/http_proto/impl/sink.hpp>
224 :
225 : #endif
|