buffered_read_stream.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_IMPL_BUFFERED_READ_STREAM_HPP
  10. #define BOOST_BEAST_IMPL_BUFFERED_READ_STREAM_HPP
  11. #include <boost/beast/core/async_base.hpp>
  12. #include <boost/beast/core/bind_handler.hpp>
  13. #include <boost/beast/core/error.hpp>
  14. #include <boost/beast/core/read_size.hpp>
  15. #include <boost/beast/core/stream_traits.hpp>
  16. #include <boost/beast/core/detail/is_invocable.hpp>
  17. #include <boost/asio/post.hpp>
  18. #include <boost/throw_exception.hpp>
  19. namespace boost {
  20. namespace beast {
  21. template<class Stream, class DynamicBuffer>
  22. struct buffered_read_stream<Stream, DynamicBuffer>::ops
  23. {
  24. template<class MutableBufferSequence, class Handler>
  25. class read_op
  26. : public async_base<Handler,
  27. beast::executor_type<buffered_read_stream>>
  28. {
  29. buffered_read_stream& s_;
  30. MutableBufferSequence b_;
  31. int step_ = 0;
  32. public:
  33. read_op(read_op&&) = default;
  34. read_op(read_op const&) = delete;
  35. template<class Handler_>
  36. read_op(
  37. Handler_&& h,
  38. buffered_read_stream& s,
  39. MutableBufferSequence const& b)
  40. : async_base<
  41. Handler, beast::executor_type<buffered_read_stream>>(
  42. std::forward<Handler_>(h), s.get_executor())
  43. , s_(s)
  44. , b_(b)
  45. {
  46. (*this)({}, 0);
  47. }
  48. void
  49. operator()(
  50. error_code ec,
  51. std::size_t bytes_transferred)
  52. {
  53. // VFALCO TODO Rewrite this using reenter/yield
  54. switch(step_)
  55. {
  56. case 0:
  57. if(s_.buffer_.size() == 0)
  58. {
  59. if(s_.capacity_ == 0)
  60. {
  61. // read (unbuffered)
  62. step_ = 1;
  63. return s_.next_layer_.async_read_some(
  64. b_, std::move(*this));
  65. }
  66. // read
  67. step_ = 2;
  68. return s_.next_layer_.async_read_some(
  69. s_.buffer_.prepare(read_size(
  70. s_.buffer_, s_.capacity_)),
  71. std::move(*this));
  72. }
  73. step_ = 3;
  74. return net::post(
  75. s_.get_executor(),
  76. beast::bind_front_handler(
  77. std::move(*this), ec, 0));
  78. case 1:
  79. // upcall
  80. break;
  81. case 2:
  82. s_.buffer_.commit(bytes_transferred);
  83. BOOST_FALLTHROUGH;
  84. case 3:
  85. bytes_transferred =
  86. net::buffer_copy(b_, s_.buffer_.data());
  87. s_.buffer_.consume(bytes_transferred);
  88. break;
  89. }
  90. this->complete_now(ec, bytes_transferred);
  91. }
  92. };
  93. struct run_read_op
  94. {
  95. template<class ReadHandler, class Buffers>
  96. void
  97. operator()(
  98. ReadHandler&& h,
  99. buffered_read_stream* s,
  100. Buffers const& b)
  101. {
  102. // If you get an error on the following line it means
  103. // that your handler does not meet the documented type
  104. // requirements for the handler.
  105. static_assert(
  106. beast::detail::is_invocable<ReadHandler,
  107. void(error_code, std::size_t)>::value,
  108. "ReadHandler type requirements not met");
  109. read_op<
  110. Buffers,
  111. typename std::decay<ReadHandler>::type>(
  112. std::forward<ReadHandler>(h), *s, b);
  113. }
  114. };
  115. };
  116. //------------------------------------------------------------------------------
  117. template<class Stream, class DynamicBuffer>
  118. template<class... Args>
  119. buffered_read_stream<Stream, DynamicBuffer>::
  120. buffered_read_stream(Args&&... args)
  121. : next_layer_(std::forward<Args>(args)...)
  122. {
  123. }
  124. template<class Stream, class DynamicBuffer>
  125. template<class ConstBufferSequence, class WriteHandler>
  126. BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
  127. buffered_read_stream<Stream, DynamicBuffer>::
  128. async_write_some(
  129. ConstBufferSequence const& buffers,
  130. WriteHandler&& handler)
  131. {
  132. static_assert(is_async_write_stream<next_layer_type>::value,
  133. "AsyncWriteStream type requirements not met");
  134. static_assert(net::is_const_buffer_sequence<
  135. ConstBufferSequence>::value,
  136. "ConstBufferSequence type requirements not met");
  137. static_assert(detail::is_invocable<WriteHandler,
  138. void(error_code, std::size_t)>::value,
  139. "WriteHandler type requirements not met");
  140. return next_layer_.async_write_some(buffers,
  141. std::forward<WriteHandler>(handler));
  142. }
  143. template<class Stream, class DynamicBuffer>
  144. template<class MutableBufferSequence>
  145. std::size_t
  146. buffered_read_stream<Stream, DynamicBuffer>::
  147. read_some(
  148. MutableBufferSequence const& buffers)
  149. {
  150. static_assert(is_sync_read_stream<next_layer_type>::value,
  151. "SyncReadStream type requirements not met");
  152. static_assert(net::is_mutable_buffer_sequence<
  153. MutableBufferSequence>::value,
  154. "MutableBufferSequence type requirements not met");
  155. error_code ec;
  156. auto n = read_some(buffers, ec);
  157. if(ec)
  158. BOOST_THROW_EXCEPTION(system_error{ec});
  159. return n;
  160. }
  161. template<class Stream, class DynamicBuffer>
  162. template<class MutableBufferSequence>
  163. std::size_t
  164. buffered_read_stream<Stream, DynamicBuffer>::
  165. read_some(MutableBufferSequence const& buffers,
  166. error_code& ec)
  167. {
  168. static_assert(is_sync_read_stream<next_layer_type>::value,
  169. "SyncReadStream type requirements not met");
  170. static_assert(net::is_mutable_buffer_sequence<
  171. MutableBufferSequence>::value,
  172. "MutableBufferSequence type requirements not met");
  173. if(buffer_.size() == 0)
  174. {
  175. if(capacity_ == 0)
  176. return next_layer_.read_some(buffers, ec);
  177. buffer_.commit(next_layer_.read_some(
  178. buffer_.prepare(read_size(buffer_,
  179. capacity_)), ec));
  180. if(ec)
  181. return 0;
  182. }
  183. else
  184. {
  185. ec = {};
  186. }
  187. auto bytes_transferred =
  188. net::buffer_copy(buffers, buffer_.data());
  189. buffer_.consume(bytes_transferred);
  190. return bytes_transferred;
  191. }
  192. template<class Stream, class DynamicBuffer>
  193. template<class MutableBufferSequence, class ReadHandler>
  194. BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
  195. buffered_read_stream<Stream, DynamicBuffer>::
  196. async_read_some(
  197. MutableBufferSequence const& buffers,
  198. ReadHandler&& handler)
  199. {
  200. static_assert(is_async_read_stream<next_layer_type>::value,
  201. "AsyncReadStream type requirements not met");
  202. static_assert(net::is_mutable_buffer_sequence<
  203. MutableBufferSequence>::value,
  204. "MutableBufferSequence type requirements not met");
  205. if(buffer_.size() == 0 && capacity_ == 0)
  206. return next_layer_.async_read_some(buffers,
  207. std::forward<ReadHandler>(handler));
  208. return net::async_initiate<
  209. ReadHandler,
  210. void(error_code, std::size_t)>(
  211. typename ops::run_read_op{},
  212. handler,
  213. this,
  214. buffers);
  215. }
  216. } // beast
  217. } // boost
  218. #endif