Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:43:54

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_DETAIL_IMPL_READ_HPP
0011 #define BOOST_BEAST_DETAIL_IMPL_READ_HPP
0012 
0013 #include <boost/beast/core/async_base.hpp>
0014 #include <boost/beast/core/flat_static_buffer.hpp>
0015 #include <boost/beast/core/read_size.hpp>
0016 #include <boost/asio/basic_stream_socket.hpp>
0017 #include <boost/asio/coroutine.hpp>
0018 #include <boost/throw_exception.hpp>
0019 
0020 namespace boost {
0021 namespace beast {
0022 namespace detail {
0023 
0024 // The number of bytes in the stack buffer when using non-blocking.
0025 static std::size_t constexpr default_max_stack_buffer = 16384;
0026 
0027 //------------------------------------------------------------------------------
0028 
0029 struct dynamic_read_ops
0030 {
0031 
0032 // read into a dynamic buffer until the
0033 // condition is met or an error occurs
0034 template<
0035     class Stream,
0036     class DynamicBuffer,
0037     class Condition,
0038     class Handler>
0039 class read_op
0040     : public asio::coroutine
0041     , public async_base<
0042         Handler, beast::executor_type<Stream>>
0043 {
0044     Stream& s_;
0045     DynamicBuffer& b_;
0046     Condition cond_;
0047     error_code ec_;
0048     std::size_t total_ = 0;
0049 
0050 public:
0051     read_op(read_op&&) = default;
0052 
0053     template<class Handler_, class Condition_>
0054     read_op(
0055         Handler_&& h,
0056         Stream& s,
0057         DynamicBuffer& b,
0058         Condition_&& cond)
0059         : async_base<Handler,
0060             beast::executor_type<Stream>>(
0061                 std::forward<Handler_>(h),
0062                     s.get_executor())
0063         , s_(s)
0064         , b_(b)
0065         , cond_(std::forward<Condition_>(cond))
0066     {
0067         (*this)({}, 0, false);
0068     }
0069 
0070     void
0071     operator()(
0072         error_code ec,
0073         std::size_t bytes_transferred,
0074         bool cont = true)
0075     {
0076         std::size_t max_prepare;
0077         BOOST_ASIO_CORO_REENTER(*this)
0078         {
0079             for(;;)
0080             {
0081                 max_prepare = beast::read_size(b_, cond_(ec, total_, b_));
0082                 if(max_prepare == 0)
0083                     break;
0084                 BOOST_ASIO_CORO_YIELD
0085                 s_.async_read_some(
0086                     b_.prepare(max_prepare), std::move(*this));
0087                 b_.commit(bytes_transferred);
0088                 total_ += bytes_transferred;
0089             }
0090             if(! cont)
0091             {
0092                 // run this handler "as-if" using net::post
0093                 // to reduce template instantiations
0094                 ec_ = ec;
0095                 BOOST_ASIO_CORO_YIELD
0096                 s_.async_read_some(
0097                     b_.prepare(0), std::move(*this));
0098                 BOOST_BEAST_ASSIGN_EC(ec, ec_);
0099             }
0100             this->complete_now(ec, total_);
0101         }
0102     }
0103 };
0104 
0105 //------------------------------------------------------------------------------
0106 
0107 template <typename AsyncReadStream>
0108 struct run_read_op
0109 {
0110     AsyncReadStream* stream;
0111 
0112     using executor_type = typename AsyncReadStream::executor_type;
0113 
0114     executor_type
0115     get_executor() const noexcept
0116     {
0117         return stream->get_executor();
0118     }
0119 
0120     template<
0121         class DynamicBuffer,
0122         class Condition,
0123         class ReadHandler>
0124     void
0125     operator()(
0126         ReadHandler&& h,
0127         DynamicBuffer* b,
0128         Condition&& c)
0129     {
0130         // If you get an error on the following line it means
0131         // that your handler does not meet the documented type
0132         // requirements for the handler.
0133 
0134         static_assert(
0135             beast::detail::is_invocable<ReadHandler,
0136             void(error_code, std::size_t)>::value,
0137             "ReadHandler type requirements not met");
0138 
0139         read_op<
0140             AsyncReadStream,
0141             DynamicBuffer,
0142             typename std::decay<Condition>::type,
0143             typename std::decay<ReadHandler>::type>(
0144                 std::forward<ReadHandler>(h),
0145                 *stream,
0146                 *b,
0147                 std::forward<Condition>(c));
0148     }
0149 
0150 };
0151 
0152 };
0153 
0154 //------------------------------------------------------------------------------
0155 
0156 template<
0157     class SyncReadStream,
0158     class DynamicBuffer,
0159     class CompletionCondition,
0160     class>
0161 std::size_t
0162 read(
0163     SyncReadStream& stream,
0164     DynamicBuffer& buffer,
0165     CompletionCondition cond)
0166 {
0167     static_assert(is_sync_read_stream<SyncReadStream>::value,
0168         "SyncReadStream type requirements not met");
0169     static_assert(
0170         net::is_dynamic_buffer<DynamicBuffer>::value,
0171         "DynamicBuffer type requirements not met");
0172     static_assert(
0173         detail::is_invocable<CompletionCondition,
0174             void(error_code&, std::size_t, DynamicBuffer&)>::value,
0175         "CompletionCondition type requirements not met");
0176     error_code ec;
0177     auto const bytes_transferred = detail::read(
0178         stream, buffer, std::move(cond), ec);
0179     if(ec)
0180         BOOST_THROW_EXCEPTION(system_error{ec});
0181     return bytes_transferred;
0182 }
0183 
0184 template<
0185     class SyncReadStream,
0186     class DynamicBuffer,
0187     class CompletionCondition,
0188     class>
0189 std::size_t
0190 read(
0191     SyncReadStream& stream,
0192     DynamicBuffer& buffer,
0193     CompletionCondition cond,
0194     error_code& ec)
0195 {
0196     static_assert(is_sync_read_stream<SyncReadStream>::value,
0197         "SyncReadStream type requirements not met");
0198     static_assert(
0199         net::is_dynamic_buffer<DynamicBuffer>::value,
0200         "DynamicBuffer type requirements not met");
0201     static_assert(
0202         detail::is_invocable<CompletionCondition,
0203             void(error_code&, std::size_t, DynamicBuffer&)>::value,
0204         "CompletionCondition type requirements not met");
0205     ec = {};
0206     std::size_t total = 0;
0207     std::size_t max_prepare;
0208     for(;;)
0209     {
0210         max_prepare =  beast::read_size(buffer, cond(ec, total, buffer));
0211         if(max_prepare == 0)
0212             break;
0213         std::size_t const bytes_transferred =
0214             stream.read_some(buffer.prepare(max_prepare), ec);
0215         buffer.commit(bytes_transferred);
0216         total += bytes_transferred;
0217     }
0218     return total;
0219 }
0220 
0221 template<
0222     class AsyncReadStream,
0223     class DynamicBuffer,
0224     class CompletionCondition,
0225     BOOST_BEAST_ASYNC_TPARAM2 ReadHandler,
0226     class>
0227 BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
0228 async_read(
0229     AsyncReadStream& stream,
0230     DynamicBuffer& buffer,
0231     CompletionCondition&& cond,
0232     ReadHandler&& handler)
0233 {
0234     static_assert(is_async_read_stream<AsyncReadStream>::value,
0235         "AsyncReadStream type requirements not met");
0236     static_assert(
0237         net::is_dynamic_buffer<DynamicBuffer>::value,
0238         "DynamicBuffer type requirements not met");
0239     static_assert(
0240         detail::is_invocable<CompletionCondition,
0241             void(error_code&, std::size_t, DynamicBuffer&)>::value,
0242         "CompletionCondition type requirements not met");
0243     return net::async_initiate<
0244         ReadHandler,
0245         void(error_code, std::size_t)>(
0246             typename dynamic_read_ops::run_read_op<AsyncReadStream>{&stream},
0247             handler,
0248             &buffer,
0249             std::forward<CompletionCondition>(cond));
0250 }
0251 
0252 } // detail
0253 } // beast
0254 } // boost
0255 
0256 #endif