Back to home page

EIC code displayed by LXR

 
 

    


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