|
||||
File indexing completed on 2025-01-18 09:29:27
0001 // 0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // Official repository: https://github.com/boostorg/beast 0008 // 0009 0010 #ifndef BOOST_BEAST_BUFFERED_READ_STREAM_HPP 0011 #define BOOST_BEAST_BUFFERED_READ_STREAM_HPP 0012 0013 #include <boost/beast/core/detail/config.hpp> 0014 #include <boost/beast/core/error.hpp> 0015 #include <boost/beast/core/multi_buffer.hpp> 0016 #include <boost/beast/core/stream_traits.hpp> 0017 #include <boost/asio/async_result.hpp> 0018 #include <boost/asio/buffer.hpp> 0019 #include <boost/asio/io_context.hpp> 0020 #include <cstdint> 0021 #include <utility> 0022 0023 namespace boost { 0024 namespace beast { 0025 0026 /** A <em>Stream</em> with attached <em>DynamicBuffer</em> to buffer reads. 0027 0028 This wraps a <em>Stream</em> implementation so that calls to write are 0029 passed through to the underlying stream, while calls to read will 0030 first consume the input sequence stored in a <em>DynamicBuffer</em> which 0031 is part of the object. 0032 0033 The use-case for this class is different than that of the 0034 `net::buffered_read_stream`. It is designed to facilitate 0035 the use of `net::read_until`, and to allow buffers 0036 acquired during detection of handshakes to be made transparently 0037 available to callers. A hypothetical implementation of the 0038 buffered version of `net::ssl::stream::async_handshake` 0039 could make use of this wrapper. 0040 0041 Uses: 0042 0043 @li Transparently leave untouched input acquired in calls 0044 to `net::read_until` behind for subsequent callers. 0045 0046 @li "Preload" a stream with handshake input data acquired 0047 from other sources. 0048 0049 Example: 0050 @code 0051 // Process the next HTTP header on the stream, 0052 // leaving excess bytes behind for the next call. 0053 // 0054 template<class Stream, class DynamicBuffer> 0055 void process_http_message( 0056 buffered_read_stream<Stream, DynamicBuffer>& stream) 0057 { 0058 // Read up to and including the end of the HTTP 0059 // header, leaving the sequence in the stream's 0060 // buffer. read_until may read past the end of the 0061 // headers; the return value will include only the 0062 // part up to the end of the delimiter. 0063 // 0064 std::size_t bytes_transferred = 0065 net::read_until( 0066 stream.next_layer(), stream.buffer(), "\r\n\r\n"); 0067 0068 // Use buffers_prefix() to limit the input 0069 // sequence to only the data up to and including 0070 // the trailing "\r\n\r\n". 0071 // 0072 auto header_buffers = buffers_prefix( 0073 bytes_transferred, stream.buffer().data()); 0074 0075 ... 0076 0077 // Discard the portion of the input corresponding 0078 // to the HTTP headers. 0079 // 0080 stream.buffer().consume(bytes_transferred); 0081 0082 // Everything we read from the stream 0083 // is part of the content-body. 0084 } 0085 @endcode 0086 0087 @tparam Stream The type of stream to wrap. 0088 0089 @tparam DynamicBuffer The type of stream buffer to use. 0090 */ 0091 template<class Stream, class DynamicBuffer> 0092 class buffered_read_stream 0093 { 0094 static_assert( 0095 net::is_dynamic_buffer<DynamicBuffer>::value, 0096 "DynamicBuffer type requirements not met"); 0097 0098 struct ops; 0099 0100 DynamicBuffer buffer_; 0101 std::size_t capacity_ = 0; 0102 Stream next_layer_; 0103 0104 public: 0105 /// The type of the internal buffer 0106 using buffer_type = DynamicBuffer; 0107 0108 /// The type of the next layer. 0109 using next_layer_type = 0110 typename std::remove_reference<Stream>::type; 0111 0112 /** Move constructor. 0113 0114 @note The behavior of move assignment on or from streams 0115 with active or pending operations is undefined. 0116 */ 0117 buffered_read_stream(buffered_read_stream&&) = default; 0118 0119 /** Move assignment. 0120 0121 @note The behavior of move assignment on or from streams 0122 with active or pending operations is undefined. 0123 */ 0124 buffered_read_stream& operator=(buffered_read_stream&&) = default; 0125 0126 /** Construct the wrapping stream. 0127 0128 @param args Parameters forwarded to the `Stream` constructor. 0129 */ 0130 template<class... Args> 0131 explicit 0132 buffered_read_stream(Args&&... args); 0133 0134 /// Get a reference to the next layer. 0135 next_layer_type& 0136 next_layer() noexcept 0137 { 0138 return next_layer_; 0139 } 0140 0141 /// Get a const reference to the next layer. 0142 next_layer_type const& 0143 next_layer() const noexcept 0144 { 0145 return next_layer_; 0146 } 0147 0148 using executor_type = 0149 beast::executor_type<next_layer_type>; 0150 0151 /** Get the executor associated with the object. 0152 0153 This function may be used to obtain the executor object that the stream 0154 uses to dispatch handlers for asynchronous operations. 0155 0156 @return A copy of the executor that stream will use to dispatch handlers. 0157 */ 0158 executor_type 0159 get_executor() noexcept 0160 { 0161 return next_layer_.get_executor(); 0162 } 0163 0164 /** Access the internal buffer. 0165 0166 The internal buffer is returned. It is possible for the 0167 caller to break invariants with this function. For example, 0168 by causing the internal buffer size to increase beyond 0169 the caller defined maximum. 0170 */ 0171 DynamicBuffer& 0172 buffer() noexcept 0173 { 0174 return buffer_; 0175 } 0176 0177 /// Access the internal buffer 0178 DynamicBuffer const& 0179 buffer() const noexcept 0180 { 0181 return buffer_; 0182 } 0183 0184 /** Set the maximum buffer size. 0185 0186 This changes the maximum size of the internal buffer used 0187 to hold read data. No bytes are discarded by this call. If 0188 the buffer size is set to zero, no more data will be buffered. 0189 0190 Thread safety: 0191 The caller is responsible for making sure the call is 0192 made from the same implicit or explicit strand. 0193 0194 @param size The number of bytes in the read buffer. 0195 0196 @note This is a soft limit. If the new maximum size is smaller 0197 than the amount of data in the buffer, no bytes are discarded. 0198 */ 0199 void 0200 capacity(std::size_t size) noexcept 0201 { 0202 capacity_ = size; 0203 } 0204 0205 /** Read some data from the stream. 0206 0207 This function is used to read data from the stream. 0208 The function call will block until one or more bytes of 0209 data has been read successfully, or until an error occurs. 0210 0211 @param buffers One or more buffers into which the data will be read. 0212 0213 @return The number of bytes read. 0214 0215 @throws system_error Thrown on failure. 0216 */ 0217 template<class MutableBufferSequence> 0218 std::size_t 0219 read_some(MutableBufferSequence const& buffers); 0220 0221 /** Read some data from the stream. 0222 0223 This function is used to read data from the stream. 0224 The function call will block until one or more bytes of 0225 data has been read successfully, or until an error occurs. 0226 0227 @param buffers One or more buffers into which the data will be read. 0228 0229 @param ec Set to the error, if any occurred. 0230 0231 @return The number of bytes read, or 0 on error. 0232 */ 0233 template<class MutableBufferSequence> 0234 std::size_t 0235 read_some(MutableBufferSequence const& buffers, 0236 error_code& ec); 0237 0238 /** Start an asynchronous read. 0239 0240 This function is used to asynchronously read data from 0241 the stream. The function call always returns immediately. 0242 0243 @param buffers One or more buffers into which the data 0244 will be read. Although the buffers object may be copied 0245 as necessary, ownership of the underlying memory blocks 0246 is retained by the caller, which must guarantee that they 0247 remain valid until the handler is called. 0248 0249 @param handler The completion handler to invoke when the operation 0250 completes. The implementation takes ownership of the handler by 0251 performing a decay-copy. The equivalent function signature of 0252 the handler must be: 0253 @code 0254 void handler( 0255 error_code const& error, // result of operation 0256 std::size_t bytes_transferred // number of bytes transferred 0257 ); 0258 @endcode 0259 If the handler has an associated immediate executor, 0260 an immediate completion will be dispatched to it. 0261 Otherwise, the handler will not be invoked from within 0262 this function. Invocation of the handler will be performed 0263 by dispatching to the immediate executor. If no 0264 immediate executor is specified, this is equivalent 0265 to using `net::post`. */ 0266 template< 0267 class MutableBufferSequence, 0268 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler = 0269 net::default_completion_token_t<executor_type>> 0270 BOOST_BEAST_ASYNC_RESULT2(ReadHandler) 0271 async_read_some( 0272 MutableBufferSequence const& buffers, 0273 ReadHandler&& handler = 0274 net::default_completion_token_t<executor_type>{}); 0275 0276 /** Write some data to the stream. 0277 0278 This function is used to write data to the stream. 0279 The function call will block until one or more bytes of the 0280 data has been written successfully, or until an error occurs. 0281 0282 @param buffers One or more data buffers to be written to the stream. 0283 0284 @return The number of bytes written. 0285 0286 @throws system_error Thrown on failure. 0287 */ 0288 template<class ConstBufferSequence> 0289 std::size_t 0290 write_some(ConstBufferSequence const& buffers) 0291 { 0292 static_assert(is_sync_write_stream<next_layer_type>::value, 0293 "SyncWriteStream type requirements not met"); 0294 return next_layer_.write_some(buffers); 0295 } 0296 0297 /** Write some data to the stream. 0298 0299 This function is used to write data to the stream. 0300 The function call will block until one or more bytes of the 0301 data has been written successfully, or until an error occurs. 0302 0303 @param buffers One or more data buffers to be written to the stream. 0304 0305 @param ec Set to the error, if any occurred. 0306 0307 @return The number of bytes written. 0308 */ 0309 template<class ConstBufferSequence> 0310 std::size_t 0311 write_some(ConstBufferSequence const& buffers, 0312 error_code& ec) 0313 { 0314 static_assert(is_sync_write_stream<next_layer_type>::value, 0315 "SyncWriteStream type requirements not met"); 0316 return next_layer_.write_some(buffers, ec); 0317 } 0318 0319 /** Start an asynchronous write. 0320 0321 This function is used to asynchronously write data from 0322 the stream. The function call always returns immediately. 0323 0324 @param buffers One or more data buffers to be written to 0325 the stream. Although the buffers object may be copied as 0326 necessary, ownership of the underlying memory blocks is 0327 retained by the caller, which must guarantee that they 0328 remain valid until the handler is called. 0329 0330 @param handler The completion handler to invoke when the operation 0331 completes. The implementation takes ownership of the handler by 0332 performing a decay-copy. The equivalent function signature of 0333 the handler must be: 0334 @code 0335 void handler( 0336 error_code const& error, // result of operation 0337 std::size_t bytes_transferred // number of bytes transferred 0338 ); 0339 @endcode 0340 If the handler has an associated immediate executor, 0341 an immediate completion will be dispatched to it. 0342 Otherwise, the handler will not be invoked from within 0343 this function. Invocation of the handler will be performed 0344 by dispatching to the immediate executor. If no 0345 immediate executor is specified, this is equivalent 0346 to using `net::post`. */ 0347 template< 0348 class ConstBufferSequence, 0349 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler = 0350 net::default_completion_token_t<executor_type>> 0351 BOOST_BEAST_ASYNC_RESULT2(WriteHandler) 0352 async_write_some( 0353 ConstBufferSequence const& buffers, 0354 WriteHandler&& handler = 0355 net::default_completion_token_t<executor_type>{}); 0356 }; 0357 0358 } // beast 0359 } // boost 0360 0361 #include <boost/beast/core/impl/buffered_read_stream.hpp> 0362 0363 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |