Line data Source code
1 : //
2 : // Copyright (c) 2019 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_SOURCE_HPP
11 : #define BOOST_HTTP_PROTO_SOURCE_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 producing buffers of data.
24 :
25 : This interface abstracts the production of
26 : a finite stream of data, returned by writing
27 : into caller-provided buffers until there
28 : is no more output 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_source,
36 : @ref sink,
37 : @ref serializer.
38 : */
39 : struct BOOST_SYMBOL_VISIBLE
40 : source
41 : {
42 : /** The results of producing data.
43 : */
44 : struct results
45 : {
46 : /** The error, if any occurred.
47 : */
48 : system::error_code ec;
49 :
50 : /** The number of bytes produced in the output.
51 : */
52 : std::size_t bytes = 0;
53 :
54 : /** True if there will be no more output.
55 : */
56 : bool finished = false;
57 :
58 : /** Accumulate results.
59 : */
60 : results&
61 : operator+=(
62 : results const& rv) noexcept;
63 :
64 : #ifdef BOOST_HTTP_PROTO_AGGREGATE_WORKAROUND
65 : constexpr
66 : results() = default;
67 :
68 : constexpr
69 : results(
70 : system::error_code ec_,
71 : std::size_t bytes_,
72 : bool finished_) noexcept
73 : : ec(ec_)
74 : , bytes(bytes_)
75 : , finished(finished_)
76 : {
77 : }
78 : #endif
79 : };
80 :
81 : /** Produce data.
82 :
83 : This function attempts to read from the
84 : source, placing the data into the given
85 : mutable buffer sequence.
86 : The return value indicates the number of
87 : bytes placed into the buffers, the error
88 : if any occurred, and a `bool` indicating
89 : whether or not there is more data
90 : remaining in the source.
91 :
92 : @par Preconditions
93 : @code
94 : buffer_size(bs) != 0
95 : @endcode
96 :
97 : @par Postconditions
98 : @code
99 : rv.ec.failed() == true || rv.finished == true || rv.bytes == buffer_size(bs)
100 : @endcode
101 :
102 : @return The result of the operation.
103 :
104 : @param bs The buffers to use.
105 : Each buffer in the sequence will
106 : be filled completely before data
107 : is placed in the next buffer.
108 : */
109 : template<class MutableBufferSequence>
110 : results
111 1005 : read(MutableBufferSequence const& bs)
112 : {
113 : static_assert(
114 : buffers::is_mutable_buffer_sequence<
115 : MutableBufferSequence>::value,
116 : "Type requirements not met");
117 :
118 1005 : return read_impl(bs);
119 : }
120 :
121 : protected:
122 : /** Derived class override.
123 :
124 : This pure virtual function is called by
125 : the implementation and must be overriden.
126 : The callee should attempt to place data
127 : into the given mutable buffer.
128 : The return value must be set to indicate
129 : the number of bytes placed into the
130 : buffers, the error if any occurred,
131 : and a `bool` indicating whether or
132 : not there is more data remaining
133 : in the source.
134 : The implementation must fill the
135 : provided buffer completely, report
136 : an error or set `rv.finished` to true.
137 :
138 : @par Preconditions
139 : @code
140 : buffer_size(bs) != 0
141 : @endcode
142 :
143 : @par Postconditions
144 : @code
145 : rv.ec.failed() == true || rv.finished == true || rv.bytes == buffer_size(bs)
146 : @endcode
147 :
148 : @return The result of the operation.
149 :
150 : @param b The buffer to use.
151 : If this is not filled completely,
152 : then the result must indicate failure
153 : or that no more data remains (or both).
154 : */
155 : virtual
156 : results
157 : on_read(
158 : buffers::mutable_buffer b) = 0;
159 :
160 : /** Derived class override.
161 :
162 : This pure virtual function is called by
163 : the implementation and must be overriden.
164 : The callee should attempt to place data
165 : into the given mutable buffer sequence.
166 : The return value must be set to indicate
167 : the number of bytes placed into the
168 : buffers, the error if any occurred,
169 : and a `bool` indicating whether or
170 : not there is more data remaining
171 : in the source.
172 :
173 : @par Preconditions
174 : @code
175 : buffer_size(bs) != 0
176 : @endcode
177 :
178 : @par Postconditions
179 : @code
180 : rv.ec.failed() == true || rv.finished == true || rv.bytes == buffer_size(bs)
181 : @endcode
182 :
183 : @return The result of the operation.
184 :
185 : @param bs The buffer sequence to use.
186 : Each buffer in the sequence must
187 : be filled completely before data
188 : is placed in the next buffer.
189 : If the buffers are not filled
190 : completely, then the result must
191 : indicate failure or that no more
192 : data remains (or both).
193 : */
194 : BOOST_HTTP_PROTO_DECL
195 : virtual
196 : results
197 : on_read(
198 : bool boost_span_issue_202_workaround,
199 : boost::span<buffers::mutable_buffer const> bs);
200 :
201 : private:
202 : results
203 9 : read_impl(
204 : buffers::mutable_buffer const& b)
205 : {
206 9 : return on_read(b);
207 : }
208 :
209 : // results
210 : // read_impl(
211 : // boost::span<buffers::mutable_buffer const> const& bs)
212 : // {
213 : // return on_read(bs);
214 : // }
215 :
216 : template<class T>
217 : results
218 : read_impl(T const&);
219 : };
220 :
221 : //------------------------------------------------
222 :
223 : /** A type trait that determines if T is a source.
224 :
225 : @tparam T The type to check.
226 :
227 : @see
228 : @ref source.
229 : */
230 : template<class T>
231 : using is_source =
232 : std::is_convertible<
233 : typename std::decay<T>::type*,
234 : source*>;
235 :
236 : } // http_proto
237 : } // boost
238 :
239 : #include <boost/http_proto/impl/source.hpp>
240 :
241 : #endif
|