]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/buffered_read_stream.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / beast / core / buffered_read_stream.hpp
CommitLineData
7c673cae 1//
92f5a8d4 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
7c673cae
FG
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//
b32b8144
FG
7// Official repository: https://github.com/boostorg/beast
8//
7c673cae 9
b32b8144
FG
10#ifndef BOOST_BEAST_BUFFERED_READ_STREAM_HPP
11#define BOOST_BEAST_BUFFERED_READ_STREAM_HPP
7c673cae 12
b32b8144
FG
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/beast/core/error.hpp>
15#include <boost/beast/core/multi_buffer.hpp>
92f5a8d4 16#include <boost/beast/core/stream_traits.hpp>
b32b8144 17#include <boost/asio/async_result.hpp>
7c673cae 18#include <boost/asio/buffer.hpp>
b32b8144 19#include <boost/asio/io_context.hpp>
7c673cae
FG
20#include <cstdint>
21#include <utility>
22
b32b8144 23namespace boost {
7c673cae
FG
24namespace beast {
25
92f5a8d4 26/** A <em>Stream</em> with attached <em>DynamicBuffer</em> to buffer reads.
7c673cae 27
92f5a8d4 28 This wraps a <em>Stream</em> implementation so that calls to write are
7c673cae 29 passed through to the underlying stream, while calls to read will
92f5a8d4 30 first consume the input sequence stored in a <em>DynamicBuffer</em> which
7c673cae
FG
31 is part of the object.
32
33 The use-case for this class is different than that of the
92f5a8d4
TL
34 `net::buffered_read_stream`. It is designed to facilitate
35 the use of `net::read_until`, and to allow buffers
7c673cae
FG
36 acquired during detection of handshakes to be made transparently
37 available to callers. A hypothetical implementation of the
92f5a8d4 38 buffered version of `net::ssl::stream::async_handshake`
7c673cae
FG
39 could make use of this wrapper.
40
41 Uses:
42
43 @li Transparently leave untouched input acquired in calls
92f5a8d4 44 to `net::read_until` behind for subsequent callers.
7c673cae
FG
45
46 @li "Preload" a stream with handshake input data acquired
47 from other sources.
48
49 Example:
50 @code
51 // Process the next HTTP header on the stream,
52 // leaving excess bytes behind for the next call.
53 //
92f5a8d4 54 template<class Stream, class DynamicBuffer>
7c673cae 55 void process_http_message(
92f5a8d4 56 buffered_read_stream<Stream, DynamicBuffer>& stream)
7c673cae
FG
57 {
58 // Read up to and including the end of the HTTP
59 // header, leaving the sequence in the stream's
60 // buffer. read_until may read past the end of the
61 // headers; the return value will include only the
62 // part up to the end of the delimiter.
63 //
64 std::size_t bytes_transferred =
92f5a8d4 65 net::read_until(
7c673cae
FG
66 stream.next_layer(), stream.buffer(), "\r\n\r\n");
67
b32b8144 68 // Use buffers_prefix() to limit the input
7c673cae
FG
69 // sequence to only the data up to and including
70 // the trailing "\r\n\r\n".
71 //
b32b8144 72 auto header_buffers = buffers_prefix(
7c673cae
FG
73 bytes_transferred, stream.buffer().data());
74
75 ...
76
77 // Discard the portion of the input corresponding
78 // to the HTTP headers.
79 //
80 stream.buffer().consume(bytes_transferred);
81
82 // Everything we read from the stream
83 // is part of the content-body.
84 }
85 @endcode
86
87 @tparam Stream The type of stream to wrap.
88
89 @tparam DynamicBuffer The type of stream buffer to use.
90*/
91template<class Stream, class DynamicBuffer>
b32b8144 92class buffered_read_stream
7c673cae 93{
b32b8144 94 static_assert(
92f5a8d4
TL
95 net::is_dynamic_buffer<DynamicBuffer>::value,
96 "DynamicBuffer type requirements not met");
7c673cae 97
92f5a8d4 98 struct ops;
7c673cae 99
b32b8144 100 DynamicBuffer buffer_;
7c673cae
FG
101 std::size_t capacity_ = 0;
102 Stream next_layer_;
103
104public:
105 /// The type of the internal buffer
b32b8144 106 using buffer_type = DynamicBuffer;
7c673cae
FG
107
108 /// The type of the next layer.
109 using next_layer_type =
110 typename std::remove_reference<Stream>::type;
111
7c673cae
FG
112 /** Move constructor.
113
114 @note The behavior of move assignment on or from streams
115 with active or pending operations is undefined.
116 */
b32b8144 117 buffered_read_stream(buffered_read_stream&&) = default;
7c673cae
FG
118
119 /** Move assignment.
120
121 @note The behavior of move assignment on or from streams
122 with active or pending operations is undefined.
123 */
b32b8144 124 buffered_read_stream& operator=(buffered_read_stream&&) = default;
7c673cae
FG
125
126 /** Construct the wrapping stream.
127
128 @param args Parameters forwarded to the `Stream` constructor.
129 */
130 template<class... Args>
131 explicit
b32b8144 132 buffered_read_stream(Args&&... args);
7c673cae
FG
133
134 /// Get a reference to the next layer.
135 next_layer_type&
92f5a8d4 136 next_layer() noexcept
7c673cae
FG
137 {
138 return next_layer_;
139 }
140
141 /// Get a const reference to the next layer.
142 next_layer_type const&
92f5a8d4 143 next_layer() const noexcept
7c673cae
FG
144 {
145 return next_layer_;
146 }
147
92f5a8d4
TL
148 using executor_type =
149 beast::executor_type<next_layer_type>;
7c673cae 150
b32b8144
FG
151 /** Get the executor associated with the object.
152
153 This function may be used to obtain the executor object that the stream
154 uses to dispatch handlers for asynchronous operations.
155
156 @return A copy of the executor that stream will use to dispatch handlers.
b32b8144 157 */
92f5a8d4
TL
158 executor_type
159 get_executor() noexcept
7c673cae 160 {
b32b8144 161 return next_layer_.get_executor();
7c673cae
FG
162 }
163
164 /** Access the internal buffer.
165
166 The internal buffer is returned. It is possible for the
167 caller to break invariants with this function. For example,
168 by causing the internal buffer size to increase beyond
169 the caller defined maximum.
170 */
171 DynamicBuffer&
92f5a8d4 172 buffer() noexcept
7c673cae 173 {
b32b8144 174 return buffer_;
7c673cae
FG
175 }
176
177 /// Access the internal buffer
178 DynamicBuffer const&
92f5a8d4 179 buffer() const noexcept
7c673cae 180 {
b32b8144 181 return buffer_;
7c673cae
FG
182 }
183
184 /** Set the maximum buffer size.
185
186 This changes the maximum size of the internal buffer used
187 to hold read data. No bytes are discarded by this call. If
188 the buffer size is set to zero, no more data will be buffered.
189
190 Thread safety:
191 The caller is responsible for making sure the call is
192 made from the same implicit or explicit strand.
193
194 @param size The number of bytes in the read buffer.
195
196 @note This is a soft limit. If the new maximum size is smaller
197 than the amount of data in the buffer, no bytes are discarded.
198 */
199 void
92f5a8d4 200 capacity(std::size_t size) noexcept
7c673cae
FG
201 {
202 capacity_ = size;
203 }
204
205 /** Read some data from the stream.
206
207 This function is used to read data from the stream.
208 The function call will block until one or more bytes of
209 data has been read successfully, or until an error occurs.
210
211 @param buffers One or more buffers into which the data will be read.
212
213 @return The number of bytes read.
214
215 @throws system_error Thrown on failure.
216 */
217 template<class MutableBufferSequence>
218 std::size_t
219 read_some(MutableBufferSequence const& buffers);
220
221 /** Read some data from the stream.
222
223 This function is used to read data from the stream.
224 The function call will block until one or more bytes of
225 data has been read successfully, or until an error occurs.
226
227 @param buffers One or more buffers into which the data will be read.
228
229 @param ec Set to the error, if any occurred.
230
231 @return The number of bytes read, or 0 on error.
232 */
233 template<class MutableBufferSequence>
234 std::size_t
235 read_some(MutableBufferSequence const& buffers,
236 error_code& ec);
237
238 /** Start an asynchronous read.
239
240 This function is used to asynchronously read data from
241 the stream. The function call always returns immediately.
242
243 @param buffers One or more buffers into which the data
244 will be read. Although the buffers object may be copied
245 as necessary, ownership of the underlying memory blocks
246 is retained by the caller, which must guarantee that they
247 remain valid until the handler is called.
248
92f5a8d4
TL
249 @param handler The completion handler to invoke when the operation
250 completes. The implementation takes ownership of the handler by
251 performing a decay-copy. The equivalent function signature of
252 the handler must be:
253 @code
254 void handler(
7c673cae
FG
255 error_code const& error, // result of operation
256 std::size_t bytes_transferred // number of bytes transferred
92f5a8d4
TL
257 );
258 @endcode
7c673cae
FG
259 Regardless of whether the asynchronous operation completes
260 immediately or not, the handler will not be invoked from within
261 this function. Invocation of the handler will be performed in a
92f5a8d4 262 manner equivalent to using `net::post`.
7c673cae 263 */
92f5a8d4
TL
264 template<
265 class MutableBufferSequence,
266 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler =
267 net::default_completion_token_t<executor_type>>
268 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
269 async_read_some(
270 MutableBufferSequence const& buffers,
271 ReadHandler&& handler =
272 net::default_completion_token_t<executor_type>{});
7c673cae
FG
273
274 /** Write some data to the stream.
275
276 This function is used to write data to the stream.
277 The function call will block until one or more bytes of the
278 data has been written successfully, or until an error occurs.
279
280 @param buffers One or more data buffers to be written to the stream.
281
282 @return The number of bytes written.
283
284 @throws system_error Thrown on failure.
285 */
286 template<class ConstBufferSequence>
287 std::size_t
288 write_some(ConstBufferSequence const& buffers)
289 {
b32b8144 290 static_assert(is_sync_write_stream<next_layer_type>::value,
92f5a8d4 291 "SyncWriteStream type requirements not met");
7c673cae
FG
292 return next_layer_.write_some(buffers);
293 }
294
295 /** Write some data to the stream.
296
297 This function is used to write data to the stream.
298 The function call will block until one or more bytes of the
299 data has been written successfully, or until an error occurs.
300
301 @param buffers One or more data buffers to be written to the stream.
302
303 @param ec Set to the error, if any occurred.
304
305 @return The number of bytes written.
306 */
307 template<class ConstBufferSequence>
308 std::size_t
309 write_some(ConstBufferSequence const& buffers,
310 error_code& ec)
311 {
b32b8144 312 static_assert(is_sync_write_stream<next_layer_type>::value,
92f5a8d4 313 "SyncWriteStream type requirements not met");
7c673cae
FG
314 return next_layer_.write_some(buffers, ec);
315 }
316
317 /** Start an asynchronous write.
318
319 This function is used to asynchronously write data from
320 the stream. The function call always returns immediately.
321
322 @param buffers One or more data buffers to be written to
323 the stream. Although the buffers object may be copied as
324 necessary, ownership of the underlying memory blocks is
325 retained by the caller, which must guarantee that they
326 remain valid until the handler is called.
327
92f5a8d4
TL
328 @param handler The completion handler to invoke when the operation
329 completes. The implementation takes ownership of the handler by
330 performing a decay-copy. The equivalent function signature of
331 the handler must be:
332 @code
333 void handler(
7c673cae
FG
334 error_code const& error, // result of operation
335 std::size_t bytes_transferred // number of bytes transferred
92f5a8d4
TL
336 );
337 @endcode
7c673cae
FG
338 Regardless of whether the asynchronous operation completes
339 immediately or not, the handler will not be invoked from within
340 this function. Invocation of the handler will be performed in a
92f5a8d4 341 manner equivalent to using `net::post`.
7c673cae 342 */
92f5a8d4
TL
343 template<
344 class ConstBufferSequence,
345 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler =
346 net::default_completion_token_t<executor_type>>
347 BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
348 async_write_some(
349 ConstBufferSequence const& buffers,
350 WriteHandler&& handler =
351 net::default_completion_token_t<executor_type>{});
7c673cae
FG
352};
353
354} // beast
b32b8144 355} // boost
7c673cae 356
92f5a8d4 357#include <boost/beast/core/impl/buffered_read_stream.hpp>
7c673cae
FG
358
359#endif