Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:25

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_IMPL_BUFFERED_READ_STREAM_HPP
0011 #define BOOST_BEAST_IMPL_BUFFERED_READ_STREAM_HPP
0012 
0013 #include <boost/beast/core/async_base.hpp>
0014 #include <boost/beast/core/bind_handler.hpp>
0015 #include <boost/beast/core/error.hpp>
0016 #include <boost/beast/core/read_size.hpp>
0017 #include <boost/beast/core/stream_traits.hpp>
0018 #include <boost/beast/core/detail/is_invocable.hpp>
0019 #include <boost/asio/dispatch.hpp>
0020 #include <boost/throw_exception.hpp>
0021 
0022 namespace boost {
0023 namespace beast {
0024 
0025 
0026 template<class Stream, class DynamicBuffer>
0027 struct buffered_read_stream<Stream, DynamicBuffer>::ops
0028 {
0029 
0030 template<class MutableBufferSequence, class Handler>
0031 class read_op
0032     : public async_base<Handler,
0033     beast::executor_type<buffered_read_stream>>
0034 {
0035     buffered_read_stream& s_;
0036     MutableBufferSequence b_;
0037     int step_ = 0;
0038 
0039 public:
0040     read_op(read_op&&) = default;
0041     read_op(read_op const&) = delete;
0042 
0043     template<class Handler_>
0044     read_op(
0045         Handler_&& h,
0046         buffered_read_stream& s,
0047         MutableBufferSequence const& b)
0048         : async_base<
0049             Handler, beast::executor_type<buffered_read_stream>>(
0050                 std::forward<Handler_>(h), s.get_executor())
0051         , s_(s)
0052         , b_(b)
0053     {
0054         (*this)({}, 0);
0055     }
0056 
0057     void
0058     operator()(
0059         error_code ec,
0060         std::size_t bytes_transferred)
0061     {
0062         // VFALCO TODO Rewrite this using reenter/yield
0063         switch(step_)
0064         {
0065         case 0:
0066             if(s_.buffer_.size() == 0)
0067             {
0068                 if(s_.capacity_ == 0)
0069                 {
0070                     // read (unbuffered)
0071                     step_ = 1;
0072                     return s_.next_layer_.async_read_some(
0073                         b_, std::move(*this));
0074                 }
0075                 // read
0076                 step_ = 2;
0077                 return s_.next_layer_.async_read_some(
0078                     s_.buffer_.prepare(read_size(
0079                         s_.buffer_, s_.capacity_)),
0080                             std::move(*this));
0081             }
0082             step_ = 3;
0083             {
0084                 const auto ex = this->get_immediate_executor();
0085                 return net::dispatch(
0086                     ex,
0087                     beast::bind_front_handler(
0088                         std::move(*this), ec, 0));
0089             }
0090         case 1:
0091             // upcall
0092             break;
0093 
0094         case 2:
0095             s_.buffer_.commit(bytes_transferred);
0096             BOOST_FALLTHROUGH;
0097 
0098         case 3:
0099             bytes_transferred =
0100                 net::buffer_copy(b_, s_.buffer_.data());
0101             s_.buffer_.consume(bytes_transferred);
0102             break;
0103         }
0104         this->complete_now(ec, bytes_transferred);
0105     }
0106 };
0107 
0108 struct run_read_op
0109 {
0110     template<class ReadHandler, class Buffers>
0111     void
0112     operator()(
0113         ReadHandler&& h,
0114         buffered_read_stream* s,
0115         Buffers const* b)
0116     {
0117         // If you get an error on the following line it means
0118         // that your handler does not meet the documented type
0119         // requirements for the handler.
0120 
0121         static_assert(
0122             beast::detail::is_invocable<ReadHandler,
0123             void(error_code, std::size_t)>::value,
0124             "ReadHandler type requirements not met");
0125 
0126         read_op<
0127             Buffers,
0128             typename std::decay<ReadHandler>::type>(
0129                 std::forward<ReadHandler>(h), *s, *b);
0130     }
0131 };
0132 
0133 };
0134 
0135 //------------------------------------------------------------------------------
0136 
0137 template<class Stream, class DynamicBuffer>
0138 template<class... Args>
0139 buffered_read_stream<Stream, DynamicBuffer>::
0140 buffered_read_stream(Args&&... args)
0141     : next_layer_(std::forward<Args>(args)...)
0142 {
0143 }
0144 
0145 template<class Stream, class DynamicBuffer>
0146 template<class ConstBufferSequence, BOOST_BEAST_ASYNC_TPARAM2 WriteHandler>
0147 BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
0148 buffered_read_stream<Stream, DynamicBuffer>::
0149 async_write_some(
0150     ConstBufferSequence const& buffers,
0151     WriteHandler&& handler)
0152 {
0153     static_assert(is_async_write_stream<next_layer_type>::value,
0154         "AsyncWriteStream type requirements not met");
0155     static_assert(net::is_const_buffer_sequence<
0156         ConstBufferSequence>::value,
0157             "ConstBufferSequence type requirements not met");
0158     static_assert(detail::is_completion_token_for<WriteHandler,
0159         void(error_code, std::size_t)>::value,
0160             "WriteHandler type requirements not met");
0161     return next_layer_.async_write_some(buffers,
0162         std::forward<WriteHandler>(handler));
0163 }
0164 
0165 template<class Stream, class DynamicBuffer>
0166 template<class MutableBufferSequence>
0167 std::size_t
0168 buffered_read_stream<Stream, DynamicBuffer>::
0169 read_some(
0170     MutableBufferSequence const& buffers)
0171 {
0172     static_assert(is_sync_read_stream<next_layer_type>::value,
0173         "SyncReadStream type requirements not met");
0174     static_assert(net::is_mutable_buffer_sequence<
0175         MutableBufferSequence>::value,
0176             "MutableBufferSequence type requirements not met");
0177     error_code ec;
0178     auto n = read_some(buffers, ec);
0179     if(ec)
0180         BOOST_THROW_EXCEPTION(system_error{ec});
0181     return n;
0182 }
0183 
0184 template<class Stream, class DynamicBuffer>
0185 template<class MutableBufferSequence>
0186 std::size_t
0187 buffered_read_stream<Stream, DynamicBuffer>::
0188 read_some(MutableBufferSequence const& buffers,
0189     error_code& ec)
0190 {
0191     static_assert(is_sync_read_stream<next_layer_type>::value,
0192         "SyncReadStream type requirements not met");
0193     static_assert(net::is_mutable_buffer_sequence<
0194         MutableBufferSequence>::value,
0195             "MutableBufferSequence type requirements not met");
0196     if(buffer_.size() == 0)
0197     {
0198         if(capacity_ == 0)
0199             return next_layer_.read_some(buffers, ec);
0200         buffer_.commit(next_layer_.read_some(
0201             buffer_.prepare(read_size(buffer_,
0202                 capacity_)), ec));
0203         if(ec)
0204             return 0;
0205     }
0206     else
0207     {
0208         ec = {};
0209     }
0210     auto bytes_transferred =
0211         net::buffer_copy(buffers, buffer_.data());
0212     buffer_.consume(bytes_transferred);
0213     return bytes_transferred;
0214 }
0215 
0216 template<class Stream, class DynamicBuffer>
0217 template<class MutableBufferSequence, BOOST_BEAST_ASYNC_TPARAM2 ReadHandler>
0218 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
0219 buffered_read_stream<Stream, DynamicBuffer>::
0220 async_read_some(
0221     MutableBufferSequence const& buffers,
0222     ReadHandler&& handler)
0223 {
0224     static_assert(is_async_read_stream<next_layer_type>::value,
0225         "AsyncReadStream type requirements not met");
0226     static_assert(net::is_mutable_buffer_sequence<
0227         MutableBufferSequence>::value,
0228             "MutableBufferSequence type requirements not met");
0229     if(buffer_.size() == 0 && capacity_ == 0)
0230         return next_layer_.async_read_some(buffers,
0231             std::forward<ReadHandler>(handler));
0232     return net::async_initiate<
0233         ReadHandler,
0234         void(error_code, std::size_t)>(
0235             typename ops::run_read_op{},
0236             handler,
0237             this,
0238             &buffers);
0239 }
0240 
0241 } // beast
0242 } // boost
0243 
0244 #endif