File indexing completed on 2025-01-18 09:29:25
0001
0002
0003
0004
0005
0006
0007
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
0063 switch(step_)
0064 {
0065 case 0:
0066 if(s_.buffer_.size() == 0)
0067 {
0068 if(s_.capacity_ == 0)
0069 {
0070
0071 step_ = 1;
0072 return s_.next_layer_.async_read_some(
0073 b_, std::move(*this));
0074 }
0075
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
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
0118
0119
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 }
0242 }
0243
0244 #endif