read.hpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145
  1. //
  2. // impl/read.hpp
  3. // ~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_IMPL_READ_HPP
  11. #define BOOST_ASIO_IMPL_READ_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <algorithm>
  16. #include <boost/asio/associated_allocator.hpp>
  17. #include <boost/asio/associated_executor.hpp>
  18. #include <boost/asio/buffer.hpp>
  19. #include <boost/asio/completion_condition.hpp>
  20. #include <boost/asio/detail/array_fwd.hpp>
  21. #include <boost/asio/detail/base_from_completion_cond.hpp>
  22. #include <boost/asio/detail/bind_handler.hpp>
  23. #include <boost/asio/detail/consuming_buffers.hpp>
  24. #include <boost/asio/detail/dependent_type.hpp>
  25. #include <boost/asio/detail/handler_alloc_helpers.hpp>
  26. #include <boost/asio/detail/handler_cont_helpers.hpp>
  27. #include <boost/asio/detail/handler_invoke_helpers.hpp>
  28. #include <boost/asio/detail/handler_type_requirements.hpp>
  29. #include <boost/asio/detail/non_const_lvalue.hpp>
  30. #include <boost/asio/detail/throw_error.hpp>
  31. #include <boost/asio/error.hpp>
  32. #include <boost/asio/detail/push_options.hpp>
  33. namespace boost {
  34. namespace asio {
  35. namespace detail
  36. {
  37. template <typename SyncReadStream, typename MutableBufferSequence,
  38. typename MutableBufferIterator, typename CompletionCondition>
  39. std::size_t read_buffer_sequence(SyncReadStream& s,
  40. const MutableBufferSequence& buffers, const MutableBufferIterator&,
  41. CompletionCondition completion_condition, boost::system::error_code& ec)
  42. {
  43. ec = boost::system::error_code();
  44. boost::asio::detail::consuming_buffers<mutable_buffer,
  45. MutableBufferSequence, MutableBufferIterator> tmp(buffers);
  46. while (!tmp.empty())
  47. {
  48. if (std::size_t max_size = detail::adapt_completion_condition_result(
  49. completion_condition(ec, tmp.total_consumed())))
  50. tmp.consume(s.read_some(tmp.prepare(max_size), ec));
  51. else
  52. break;
  53. }
  54. return tmp.total_consumed();;
  55. }
  56. } // namespace detail
  57. template <typename SyncReadStream, typename MutableBufferSequence,
  58. typename CompletionCondition>
  59. std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
  60. CompletionCondition completion_condition, boost::system::error_code& ec,
  61. typename enable_if<
  62. is_mutable_buffer_sequence<MutableBufferSequence>::value
  63. >::type*)
  64. {
  65. return detail::read_buffer_sequence(s, buffers,
  66. boost::asio::buffer_sequence_begin(buffers),
  67. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
  68. }
  69. template <typename SyncReadStream, typename MutableBufferSequence>
  70. inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
  71. typename enable_if<
  72. is_mutable_buffer_sequence<MutableBufferSequence>::value
  73. >::type*)
  74. {
  75. boost::system::error_code ec;
  76. std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
  77. boost::asio::detail::throw_error(ec, "read");
  78. return bytes_transferred;
  79. }
  80. template <typename SyncReadStream, typename MutableBufferSequence>
  81. inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
  82. boost::system::error_code& ec,
  83. typename enable_if<
  84. is_mutable_buffer_sequence<MutableBufferSequence>::value
  85. >::type*)
  86. {
  87. return read(s, buffers, transfer_all(), ec);
  88. }
  89. template <typename SyncReadStream, typename MutableBufferSequence,
  90. typename CompletionCondition>
  91. inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
  92. CompletionCondition completion_condition,
  93. typename enable_if<
  94. is_mutable_buffer_sequence<MutableBufferSequence>::value
  95. >::type*)
  96. {
  97. boost::system::error_code ec;
  98. std::size_t bytes_transferred = read(s, buffers,
  99. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
  100. boost::asio::detail::throw_error(ec, "read");
  101. return bytes_transferred;
  102. }
  103. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  104. template <typename SyncReadStream, typename DynamicBuffer_v1,
  105. typename CompletionCondition>
  106. std::size_t read(SyncReadStream& s,
  107. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  108. CompletionCondition completion_condition, boost::system::error_code& ec,
  109. typename enable_if<
  110. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  111. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  112. >::type*)
  113. {
  114. typename decay<DynamicBuffer_v1>::type b(
  115. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
  116. ec = boost::system::error_code();
  117. std::size_t total_transferred = 0;
  118. std::size_t max_size = detail::adapt_completion_condition_result(
  119. completion_condition(ec, total_transferred));
  120. std::size_t bytes_available = std::min<std::size_t>(
  121. std::max<std::size_t>(512, b.capacity() - b.size()),
  122. std::min<std::size_t>(max_size, b.max_size() - b.size()));
  123. while (bytes_available > 0)
  124. {
  125. std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
  126. b.commit(bytes_transferred);
  127. total_transferred += bytes_transferred;
  128. max_size = detail::adapt_completion_condition_result(
  129. completion_condition(ec, total_transferred));
  130. bytes_available = std::min<std::size_t>(
  131. std::max<std::size_t>(512, b.capacity() - b.size()),
  132. std::min<std::size_t>(max_size, b.max_size() - b.size()));
  133. }
  134. return total_transferred;
  135. }
  136. template <typename SyncReadStream, typename DynamicBuffer_v1>
  137. inline std::size_t read(SyncReadStream& s,
  138. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  139. typename enable_if<
  140. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  141. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  142. >::type*)
  143. {
  144. boost::system::error_code ec;
  145. std::size_t bytes_transferred = read(s,
  146. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);
  147. boost::asio::detail::throw_error(ec, "read");
  148. return bytes_transferred;
  149. }
  150. template <typename SyncReadStream, typename DynamicBuffer_v1>
  151. inline std::size_t read(SyncReadStream& s,
  152. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  153. boost::system::error_code& ec,
  154. typename enable_if<
  155. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  156. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  157. >::type*)
  158. {
  159. return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  160. transfer_all(), ec);
  161. }
  162. template <typename SyncReadStream, typename DynamicBuffer_v1,
  163. typename CompletionCondition>
  164. inline std::size_t read(SyncReadStream& s,
  165. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  166. CompletionCondition completion_condition,
  167. typename enable_if<
  168. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  169. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  170. >::type*)
  171. {
  172. boost::system::error_code ec;
  173. std::size_t bytes_transferred = read(s,
  174. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  175. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
  176. boost::asio::detail::throw_error(ec, "read");
  177. return bytes_transferred;
  178. }
  179. #if !defined(BOOST_ASIO_NO_EXTENSIONS)
  180. #if !defined(BOOST_ASIO_NO_IOSTREAM)
  181. template <typename SyncReadStream, typename Allocator,
  182. typename CompletionCondition>
  183. inline std::size_t read(SyncReadStream& s,
  184. boost::asio::basic_streambuf<Allocator>& b,
  185. CompletionCondition completion_condition, boost::system::error_code& ec)
  186. {
  187. return read(s, basic_streambuf_ref<Allocator>(b),
  188. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
  189. }
  190. template <typename SyncReadStream, typename Allocator>
  191. inline std::size_t read(SyncReadStream& s,
  192. boost::asio::basic_streambuf<Allocator>& b)
  193. {
  194. return read(s, basic_streambuf_ref<Allocator>(b));
  195. }
  196. template <typename SyncReadStream, typename Allocator>
  197. inline std::size_t read(SyncReadStream& s,
  198. boost::asio::basic_streambuf<Allocator>& b,
  199. boost::system::error_code& ec)
  200. {
  201. return read(s, basic_streambuf_ref<Allocator>(b), ec);
  202. }
  203. template <typename SyncReadStream, typename Allocator,
  204. typename CompletionCondition>
  205. inline std::size_t read(SyncReadStream& s,
  206. boost::asio::basic_streambuf<Allocator>& b,
  207. CompletionCondition completion_condition)
  208. {
  209. return read(s, basic_streambuf_ref<Allocator>(b),
  210. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  211. }
  212. #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
  213. #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
  214. #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  215. template <typename SyncReadStream, typename DynamicBuffer_v2,
  216. typename CompletionCondition>
  217. std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
  218. CompletionCondition completion_condition, boost::system::error_code& ec,
  219. typename enable_if<
  220. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  221. >::type*)
  222. {
  223. DynamicBuffer_v2& b = buffers;
  224. ec = boost::system::error_code();
  225. std::size_t total_transferred = 0;
  226. std::size_t max_size = detail::adapt_completion_condition_result(
  227. completion_condition(ec, total_transferred));
  228. std::size_t bytes_available = std::min<std::size_t>(
  229. std::max<std::size_t>(512, b.capacity() - b.size()),
  230. std::min<std::size_t>(max_size, b.max_size() - b.size()));
  231. while (bytes_available > 0)
  232. {
  233. std::size_t pos = b.size();
  234. b.grow(bytes_available);
  235. std::size_t bytes_transferred = s.read_some(
  236. b.data(pos, bytes_available), ec);
  237. b.shrink(bytes_available - bytes_transferred);
  238. total_transferred += bytes_transferred;
  239. max_size = detail::adapt_completion_condition_result(
  240. completion_condition(ec, total_transferred));
  241. bytes_available = std::min<std::size_t>(
  242. std::max<std::size_t>(512, b.capacity() - b.size()),
  243. std::min<std::size_t>(max_size, b.max_size() - b.size()));
  244. }
  245. return total_transferred;
  246. }
  247. template <typename SyncReadStream, typename DynamicBuffer_v2>
  248. inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
  249. typename enable_if<
  250. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  251. >::type*)
  252. {
  253. boost::system::error_code ec;
  254. std::size_t bytes_transferred = read(s,
  255. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);
  256. boost::asio::detail::throw_error(ec, "read");
  257. return bytes_transferred;
  258. }
  259. template <typename SyncReadStream, typename DynamicBuffer_v2>
  260. inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
  261. boost::system::error_code& ec,
  262. typename enable_if<
  263. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  264. >::type*)
  265. {
  266. return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  267. transfer_all(), ec);
  268. }
  269. template <typename SyncReadStream, typename DynamicBuffer_v2,
  270. typename CompletionCondition>
  271. inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
  272. CompletionCondition completion_condition,
  273. typename enable_if<
  274. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  275. >::type*)
  276. {
  277. boost::system::error_code ec;
  278. std::size_t bytes_transferred = read(s,
  279. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  280. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
  281. boost::asio::detail::throw_error(ec, "read");
  282. return bytes_transferred;
  283. }
  284. namespace detail
  285. {
  286. template <typename AsyncReadStream, typename MutableBufferSequence,
  287. typename MutableBufferIterator, typename CompletionCondition,
  288. typename ReadHandler>
  289. class read_op
  290. : detail::base_from_completion_cond<CompletionCondition>
  291. {
  292. public:
  293. read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
  294. CompletionCondition& completion_condition, ReadHandler& handler)
  295. : detail::base_from_completion_cond<
  296. CompletionCondition>(completion_condition),
  297. stream_(stream),
  298. buffers_(buffers),
  299. start_(0),
  300. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
  301. {
  302. }
  303. #if defined(BOOST_ASIO_HAS_MOVE)
  304. read_op(const read_op& other)
  305. : detail::base_from_completion_cond<CompletionCondition>(other),
  306. stream_(other.stream_),
  307. buffers_(other.buffers_),
  308. start_(other.start_),
  309. handler_(other.handler_)
  310. {
  311. }
  312. read_op(read_op&& other)
  313. : detail::base_from_completion_cond<CompletionCondition>(
  314. BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
  315. CompletionCondition>)(other)),
  316. stream_(other.stream_),
  317. buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
  318. start_(other.start_),
  319. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  320. {
  321. }
  322. #endif // defined(BOOST_ASIO_HAS_MOVE)
  323. void operator()(const boost::system::error_code& ec,
  324. std::size_t bytes_transferred, int start = 0)
  325. {
  326. std::size_t max_size;
  327. switch (start_ = start)
  328. {
  329. case 1:
  330. max_size = this->check_for_completion(ec, buffers_.total_consumed());
  331. do
  332. {
  333. stream_.async_read_some(buffers_.prepare(max_size),
  334. BOOST_ASIO_MOVE_CAST(read_op)(*this));
  335. return; default:
  336. buffers_.consume(bytes_transferred);
  337. if ((!ec && bytes_transferred == 0) || buffers_.empty())
  338. break;
  339. max_size = this->check_for_completion(ec, buffers_.total_consumed());
  340. } while (max_size > 0);
  341. handler_(ec, buffers_.total_consumed());
  342. }
  343. }
  344. //private:
  345. typedef boost::asio::detail::consuming_buffers<mutable_buffer,
  346. MutableBufferSequence, MutableBufferIterator> buffers_type;
  347. AsyncReadStream& stream_;
  348. buffers_type buffers_;
  349. int start_;
  350. ReadHandler handler_;
  351. };
  352. template <typename AsyncReadStream, typename MutableBufferSequence,
  353. typename MutableBufferIterator, typename CompletionCondition,
  354. typename ReadHandler>
  355. inline void* asio_handler_allocate(std::size_t size,
  356. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  357. CompletionCondition, ReadHandler>* this_handler)
  358. {
  359. return boost_asio_handler_alloc_helpers::allocate(
  360. size, this_handler->handler_);
  361. }
  362. template <typename AsyncReadStream, typename MutableBufferSequence,
  363. typename MutableBufferIterator, typename CompletionCondition,
  364. typename ReadHandler>
  365. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  366. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  367. CompletionCondition, ReadHandler>* this_handler)
  368. {
  369. boost_asio_handler_alloc_helpers::deallocate(
  370. pointer, size, this_handler->handler_);
  371. }
  372. template <typename AsyncReadStream, typename MutableBufferSequence,
  373. typename MutableBufferIterator, typename CompletionCondition,
  374. typename ReadHandler>
  375. inline bool asio_handler_is_continuation(
  376. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  377. CompletionCondition, ReadHandler>* this_handler)
  378. {
  379. return this_handler->start_ == 0 ? true
  380. : boost_asio_handler_cont_helpers::is_continuation(
  381. this_handler->handler_);
  382. }
  383. template <typename Function, typename AsyncReadStream,
  384. typename MutableBufferSequence, typename MutableBufferIterator,
  385. typename CompletionCondition, typename ReadHandler>
  386. inline void asio_handler_invoke(Function& function,
  387. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  388. CompletionCondition, ReadHandler>* this_handler)
  389. {
  390. boost_asio_handler_invoke_helpers::invoke(
  391. function, this_handler->handler_);
  392. }
  393. template <typename Function, typename AsyncReadStream,
  394. typename MutableBufferSequence, typename MutableBufferIterator,
  395. typename CompletionCondition, typename ReadHandler>
  396. inline void asio_handler_invoke(const Function& function,
  397. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  398. CompletionCondition, ReadHandler>* this_handler)
  399. {
  400. boost_asio_handler_invoke_helpers::invoke(
  401. function, this_handler->handler_);
  402. }
  403. template <typename AsyncReadStream, typename MutableBufferSequence,
  404. typename MutableBufferIterator, typename CompletionCondition,
  405. typename ReadHandler>
  406. inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
  407. const MutableBufferSequence& buffers, const MutableBufferIterator&,
  408. CompletionCondition& completion_condition, ReadHandler& handler)
  409. {
  410. detail::read_op<AsyncReadStream, MutableBufferSequence,
  411. MutableBufferIterator, CompletionCondition, ReadHandler>(
  412. stream, buffers, completion_condition, handler)(
  413. boost::system::error_code(), 0, 1);
  414. }
  415. template <typename AsyncReadStream>
  416. class initiate_async_read_buffer_sequence
  417. {
  418. public:
  419. typedef typename AsyncReadStream::executor_type executor_type;
  420. explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream)
  421. : stream_(stream)
  422. {
  423. }
  424. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  425. {
  426. return stream_.get_executor();
  427. }
  428. template <typename ReadHandler, typename MutableBufferSequence,
  429. typename CompletionCondition>
  430. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  431. const MutableBufferSequence& buffers,
  432. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  433. {
  434. // If you get an error on the following line it means that your handler
  435. // does not meet the documented type requirements for a ReadHandler.
  436. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  437. non_const_lvalue<ReadHandler> handler2(handler);
  438. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  439. start_read_buffer_sequence_op(stream_, buffers,
  440. boost::asio::buffer_sequence_begin(buffers),
  441. completion_cond2.value, handler2.value);
  442. }
  443. private:
  444. AsyncReadStream& stream_;
  445. };
  446. } // namespace detail
  447. #if !defined(GENERATING_DOCUMENTATION)
  448. template <typename AsyncReadStream, typename MutableBufferSequence,
  449. typename MutableBufferIterator, typename CompletionCondition,
  450. typename ReadHandler, typename Allocator>
  451. struct associated_allocator<
  452. detail::read_op<AsyncReadStream, MutableBufferSequence,
  453. MutableBufferIterator, CompletionCondition, ReadHandler>,
  454. Allocator>
  455. {
  456. typedef typename associated_allocator<ReadHandler, Allocator>::type type;
  457. static type get(
  458. const detail::read_op<AsyncReadStream, MutableBufferSequence,
  459. MutableBufferIterator, CompletionCondition, ReadHandler>& h,
  460. const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
  461. {
  462. return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
  463. }
  464. };
  465. template <typename AsyncReadStream, typename MutableBufferSequence,
  466. typename MutableBufferIterator, typename CompletionCondition,
  467. typename ReadHandler, typename Executor>
  468. struct associated_executor<
  469. detail::read_op<AsyncReadStream, MutableBufferSequence,
  470. MutableBufferIterator, CompletionCondition, ReadHandler>,
  471. Executor>
  472. {
  473. typedef typename associated_executor<ReadHandler, Executor>::type type;
  474. static type get(
  475. const detail::read_op<AsyncReadStream, MutableBufferSequence,
  476. MutableBufferIterator, CompletionCondition, ReadHandler>& h,
  477. const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
  478. {
  479. return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
  480. }
  481. };
  482. #endif // !defined(GENERATING_DOCUMENTATION)
  483. template <typename AsyncReadStream,
  484. typename MutableBufferSequence, typename CompletionCondition,
  485. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  486. std::size_t)) ReadHandler>
  487. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  488. void (boost::system::error_code, std::size_t))
  489. async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
  490. CompletionCondition completion_condition,
  491. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  492. typename enable_if<
  493. is_mutable_buffer_sequence<MutableBufferSequence>::value
  494. >::type*)
  495. {
  496. return async_initiate<ReadHandler,
  497. void (boost::system::error_code, std::size_t)>(
  498. detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), handler,
  499. buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  500. }
  501. template <typename AsyncReadStream, typename MutableBufferSequence,
  502. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  503. std::size_t)) ReadHandler>
  504. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  505. void (boost::system::error_code, std::size_t))
  506. async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
  507. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  508. typename enable_if<
  509. is_mutable_buffer_sequence<MutableBufferSequence>::value
  510. >::type*)
  511. {
  512. return async_initiate<ReadHandler,
  513. void (boost::system::error_code, std::size_t)>(
  514. detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s),
  515. handler, buffers, transfer_all());
  516. }
  517. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  518. namespace detail
  519. {
  520. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  521. typename CompletionCondition, typename ReadHandler>
  522. class read_dynbuf_v1_op
  523. : detail::base_from_completion_cond<CompletionCondition>
  524. {
  525. public:
  526. template <typename BufferSequence>
  527. read_dynbuf_v1_op(AsyncReadStream& stream,
  528. BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
  529. CompletionCondition& completion_condition, ReadHandler& handler)
  530. : detail::base_from_completion_cond<
  531. CompletionCondition>(completion_condition),
  532. stream_(stream),
  533. buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
  534. start_(0),
  535. total_transferred_(0),
  536. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
  537. {
  538. }
  539. #if defined(BOOST_ASIO_HAS_MOVE)
  540. read_dynbuf_v1_op(const read_dynbuf_v1_op& other)
  541. : detail::base_from_completion_cond<CompletionCondition>(other),
  542. stream_(other.stream_),
  543. buffers_(other.buffers_),
  544. start_(other.start_),
  545. total_transferred_(other.total_transferred_),
  546. handler_(other.handler_)
  547. {
  548. }
  549. read_dynbuf_v1_op(read_dynbuf_v1_op&& other)
  550. : detail::base_from_completion_cond<CompletionCondition>(
  551. BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
  552. CompletionCondition>)(other)),
  553. stream_(other.stream_),
  554. buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
  555. start_(other.start_),
  556. total_transferred_(other.total_transferred_),
  557. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  558. {
  559. }
  560. #endif // defined(BOOST_ASIO_HAS_MOVE)
  561. void operator()(const boost::system::error_code& ec,
  562. std::size_t bytes_transferred, int start = 0)
  563. {
  564. std::size_t max_size, bytes_available;
  565. switch (start_ = start)
  566. {
  567. case 1:
  568. max_size = this->check_for_completion(ec, total_transferred_);
  569. bytes_available = std::min<std::size_t>(
  570. std::max<std::size_t>(512,
  571. buffers_.capacity() - buffers_.size()),
  572. std::min<std::size_t>(max_size,
  573. buffers_.max_size() - buffers_.size()));
  574. for (;;)
  575. {
  576. stream_.async_read_some(buffers_.prepare(bytes_available),
  577. BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));
  578. return; default:
  579. total_transferred_ += bytes_transferred;
  580. buffers_.commit(bytes_transferred);
  581. max_size = this->check_for_completion(ec, total_transferred_);
  582. bytes_available = std::min<std::size_t>(
  583. std::max<std::size_t>(512,
  584. buffers_.capacity() - buffers_.size()),
  585. std::min<std::size_t>(max_size,
  586. buffers_.max_size() - buffers_.size()));
  587. if ((!ec && bytes_transferred == 0) || bytes_available == 0)
  588. break;
  589. }
  590. handler_(ec, static_cast<const std::size_t&>(total_transferred_));
  591. }
  592. }
  593. //private:
  594. AsyncReadStream& stream_;
  595. DynamicBuffer_v1 buffers_;
  596. int start_;
  597. std::size_t total_transferred_;
  598. ReadHandler handler_;
  599. };
  600. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  601. typename CompletionCondition, typename ReadHandler>
  602. inline void* asio_handler_allocate(std::size_t size,
  603. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  604. CompletionCondition, ReadHandler>* this_handler)
  605. {
  606. return boost_asio_handler_alloc_helpers::allocate(
  607. size, this_handler->handler_);
  608. }
  609. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  610. typename CompletionCondition, typename ReadHandler>
  611. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  612. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  613. CompletionCondition, ReadHandler>* this_handler)
  614. {
  615. boost_asio_handler_alloc_helpers::deallocate(
  616. pointer, size, this_handler->handler_);
  617. }
  618. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  619. typename CompletionCondition, typename ReadHandler>
  620. inline bool asio_handler_is_continuation(
  621. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  622. CompletionCondition, ReadHandler>* this_handler)
  623. {
  624. return this_handler->start_ == 0 ? true
  625. : boost_asio_handler_cont_helpers::is_continuation(
  626. this_handler->handler_);
  627. }
  628. template <typename Function, typename AsyncReadStream,
  629. typename DynamicBuffer_v1, typename CompletionCondition,
  630. typename ReadHandler>
  631. inline void asio_handler_invoke(Function& function,
  632. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  633. CompletionCondition, ReadHandler>* this_handler)
  634. {
  635. boost_asio_handler_invoke_helpers::invoke(
  636. function, this_handler->handler_);
  637. }
  638. template <typename Function, typename AsyncReadStream,
  639. typename DynamicBuffer_v1, typename CompletionCondition,
  640. typename ReadHandler>
  641. inline void asio_handler_invoke(const Function& function,
  642. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  643. CompletionCondition, ReadHandler>* this_handler)
  644. {
  645. boost_asio_handler_invoke_helpers::invoke(
  646. function, this_handler->handler_);
  647. }
  648. template <typename AsyncReadStream>
  649. class initiate_async_read_dynbuf_v1
  650. {
  651. public:
  652. typedef typename AsyncReadStream::executor_type executor_type;
  653. explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream)
  654. : stream_(stream)
  655. {
  656. }
  657. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  658. {
  659. return stream_.get_executor();
  660. }
  661. template <typename ReadHandler, typename DynamicBuffer_v1,
  662. typename CompletionCondition>
  663. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  664. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  665. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  666. {
  667. // If you get an error on the following line it means that your handler
  668. // does not meet the documented type requirements for a ReadHandler.
  669. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  670. non_const_lvalue<ReadHandler> handler2(handler);
  671. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  672. read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
  673. CompletionCondition, typename decay<ReadHandler>::type>(
  674. stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  675. completion_cond2.value, handler2.value)(
  676. boost::system::error_code(), 0, 1);
  677. }
  678. private:
  679. AsyncReadStream& stream_;
  680. };
  681. } // namespace detail
  682. #if !defined(GENERATING_DOCUMENTATION)
  683. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  684. typename CompletionCondition, typename ReadHandler, typename Allocator>
  685. struct associated_allocator<
  686. detail::read_dynbuf_v1_op<AsyncReadStream,
  687. DynamicBuffer_v1, CompletionCondition, ReadHandler>,
  688. Allocator>
  689. {
  690. typedef typename associated_allocator<ReadHandler, Allocator>::type type;
  691. static type get(
  692. const detail::read_dynbuf_v1_op<AsyncReadStream,
  693. DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
  694. const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
  695. {
  696. return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
  697. }
  698. };
  699. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  700. typename CompletionCondition, typename ReadHandler, typename Executor>
  701. struct associated_executor<
  702. detail::read_dynbuf_v1_op<AsyncReadStream,
  703. DynamicBuffer_v1, CompletionCondition, ReadHandler>,
  704. Executor>
  705. {
  706. typedef typename associated_executor<ReadHandler, Executor>::type type;
  707. static type get(
  708. const detail::read_dynbuf_v1_op<AsyncReadStream,
  709. DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
  710. const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
  711. {
  712. return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
  713. }
  714. };
  715. #endif // !defined(GENERATING_DOCUMENTATION)
  716. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  717. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  718. std::size_t)) ReadHandler>
  719. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  720. void (boost::system::error_code, std::size_t))
  721. async_read(AsyncReadStream& s,
  722. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  723. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  724. typename enable_if<
  725. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  726. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  727. >::type*)
  728. {
  729. return async_read(s,
  730. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  731. transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  732. }
  733. template <typename AsyncReadStream,
  734. typename DynamicBuffer_v1, typename CompletionCondition,
  735. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  736. std::size_t)) ReadHandler>
  737. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  738. void (boost::system::error_code, std::size_t))
  739. async_read(AsyncReadStream& s,
  740. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  741. CompletionCondition completion_condition,
  742. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  743. typename enable_if<
  744. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  745. && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  746. >::type*)
  747. {
  748. // If you get an error on the following line it means that your handler does
  749. // not meet the documented type requirements for a ReadHandler.
  750. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  751. return async_initiate<ReadHandler,
  752. void (boost::system::error_code, std::size_t)>(
  753. detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),
  754. handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  755. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  756. }
  757. #if !defined(BOOST_ASIO_NO_EXTENSIONS)
  758. #if !defined(BOOST_ASIO_NO_IOSTREAM)
  759. template <typename AsyncReadStream, typename Allocator,
  760. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  761. std::size_t)) ReadHandler>
  762. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  763. void (boost::system::error_code, std::size_t))
  764. async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
  765. BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
  766. {
  767. return async_read(s, basic_streambuf_ref<Allocator>(b),
  768. BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  769. }
  770. template <typename AsyncReadStream,
  771. typename Allocator, typename CompletionCondition,
  772. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  773. std::size_t)) ReadHandler>
  774. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  775. void (boost::system::error_code, std::size_t))
  776. async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
  777. CompletionCondition completion_condition,
  778. BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
  779. {
  780. return async_read(s, basic_streambuf_ref<Allocator>(b),
  781. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
  782. BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  783. }
  784. #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
  785. #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
  786. #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  787. namespace detail
  788. {
  789. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  790. typename CompletionCondition, typename ReadHandler>
  791. class read_dynbuf_v2_op
  792. : detail::base_from_completion_cond<CompletionCondition>
  793. {
  794. public:
  795. template <typename BufferSequence>
  796. read_dynbuf_v2_op(AsyncReadStream& stream,
  797. BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
  798. CompletionCondition& completion_condition, ReadHandler& handler)
  799. : detail::base_from_completion_cond<
  800. CompletionCondition>(completion_condition),
  801. stream_(stream),
  802. buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
  803. start_(0),
  804. total_transferred_(0),
  805. bytes_available_(0),
  806. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
  807. {
  808. }
  809. #if defined(BOOST_ASIO_HAS_MOVE)
  810. read_dynbuf_v2_op(const read_dynbuf_v2_op& other)
  811. : detail::base_from_completion_cond<CompletionCondition>(other),
  812. stream_(other.stream_),
  813. buffers_(other.buffers_),
  814. start_(other.start_),
  815. total_transferred_(other.total_transferred_),
  816. bytes_available_(other.bytes_available_),
  817. handler_(other.handler_)
  818. {
  819. }
  820. read_dynbuf_v2_op(read_dynbuf_v2_op&& other)
  821. : detail::base_from_completion_cond<CompletionCondition>(
  822. BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
  823. CompletionCondition>)(other)),
  824. stream_(other.stream_),
  825. buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
  826. start_(other.start_),
  827. total_transferred_(other.total_transferred_),
  828. bytes_available_(other.bytes_available_),
  829. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  830. {
  831. }
  832. #endif // defined(BOOST_ASIO_HAS_MOVE)
  833. void operator()(const boost::system::error_code& ec,
  834. std::size_t bytes_transferred, int start = 0)
  835. {
  836. std::size_t max_size, pos;
  837. switch (start_ = start)
  838. {
  839. case 1:
  840. max_size = this->check_for_completion(ec, total_transferred_);
  841. bytes_available_ = std::min<std::size_t>(
  842. std::max<std::size_t>(512,
  843. buffers_.capacity() - buffers_.size()),
  844. std::min<std::size_t>(max_size,
  845. buffers_.max_size() - buffers_.size()));
  846. for (;;)
  847. {
  848. pos = buffers_.size();
  849. buffers_.grow(bytes_available_);
  850. stream_.async_read_some(buffers_.data(pos, bytes_available_),
  851. BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));
  852. return; default:
  853. total_transferred_ += bytes_transferred;
  854. buffers_.shrink(bytes_available_ - bytes_transferred);
  855. max_size = this->check_for_completion(ec, total_transferred_);
  856. bytes_available_ = std::min<std::size_t>(
  857. std::max<std::size_t>(512,
  858. buffers_.capacity() - buffers_.size()),
  859. std::min<std::size_t>(max_size,
  860. buffers_.max_size() - buffers_.size()));
  861. if ((!ec && bytes_transferred == 0) || bytes_available_ == 0)
  862. break;
  863. }
  864. handler_(ec, static_cast<const std::size_t&>(total_transferred_));
  865. }
  866. }
  867. //private:
  868. AsyncReadStream& stream_;
  869. DynamicBuffer_v2 buffers_;
  870. int start_;
  871. std::size_t total_transferred_;
  872. std::size_t bytes_available_;
  873. ReadHandler handler_;
  874. };
  875. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  876. typename CompletionCondition, typename ReadHandler>
  877. inline void* asio_handler_allocate(std::size_t size,
  878. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  879. CompletionCondition, ReadHandler>* this_handler)
  880. {
  881. return boost_asio_handler_alloc_helpers::allocate(
  882. size, this_handler->handler_);
  883. }
  884. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  885. typename CompletionCondition, typename ReadHandler>
  886. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  887. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  888. CompletionCondition, ReadHandler>* this_handler)
  889. {
  890. boost_asio_handler_alloc_helpers::deallocate(
  891. pointer, size, this_handler->handler_);
  892. }
  893. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  894. typename CompletionCondition, typename ReadHandler>
  895. inline bool asio_handler_is_continuation(
  896. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  897. CompletionCondition, ReadHandler>* this_handler)
  898. {
  899. return this_handler->start_ == 0 ? true
  900. : boost_asio_handler_cont_helpers::is_continuation(
  901. this_handler->handler_);
  902. }
  903. template <typename Function, typename AsyncReadStream,
  904. typename DynamicBuffer_v2, typename CompletionCondition,
  905. typename ReadHandler>
  906. inline void asio_handler_invoke(Function& function,
  907. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  908. CompletionCondition, ReadHandler>* this_handler)
  909. {
  910. boost_asio_handler_invoke_helpers::invoke(
  911. function, this_handler->handler_);
  912. }
  913. template <typename Function, typename AsyncReadStream,
  914. typename DynamicBuffer_v2, typename CompletionCondition,
  915. typename ReadHandler>
  916. inline void asio_handler_invoke(const Function& function,
  917. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  918. CompletionCondition, ReadHandler>* this_handler)
  919. {
  920. boost_asio_handler_invoke_helpers::invoke(
  921. function, this_handler->handler_);
  922. }
  923. template <typename AsyncReadStream>
  924. class initiate_async_read_dynbuf_v2
  925. {
  926. public:
  927. typedef typename AsyncReadStream::executor_type executor_type;
  928. explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream)
  929. : stream_(stream)
  930. {
  931. }
  932. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  933. {
  934. return stream_.get_executor();
  935. }
  936. template <typename ReadHandler, typename DynamicBuffer_v2,
  937. typename CompletionCondition>
  938. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  939. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
  940. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  941. {
  942. // If you get an error on the following line it means that your handler
  943. // does not meet the documented type requirements for a ReadHandler.
  944. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  945. non_const_lvalue<ReadHandler> handler2(handler);
  946. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  947. read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
  948. CompletionCondition, typename decay<ReadHandler>::type>(
  949. stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  950. completion_cond2.value, handler2.value)(
  951. boost::system::error_code(), 0, 1);
  952. }
  953. private:
  954. AsyncReadStream& stream_;
  955. };
  956. } // namespace detail
  957. #if !defined(GENERATING_DOCUMENTATION)
  958. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  959. typename CompletionCondition, typename ReadHandler, typename Allocator>
  960. struct associated_allocator<
  961. detail::read_dynbuf_v2_op<AsyncReadStream,
  962. DynamicBuffer_v2, CompletionCondition, ReadHandler>,
  963. Allocator>
  964. {
  965. typedef typename associated_allocator<ReadHandler, Allocator>::type type;
  966. static type get(
  967. const detail::read_dynbuf_v2_op<AsyncReadStream,
  968. DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
  969. const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
  970. {
  971. return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
  972. }
  973. };
  974. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  975. typename CompletionCondition, typename ReadHandler, typename Executor>
  976. struct associated_executor<
  977. detail::read_dynbuf_v2_op<AsyncReadStream,
  978. DynamicBuffer_v2, CompletionCondition, ReadHandler>,
  979. Executor>
  980. {
  981. typedef typename associated_executor<ReadHandler, Executor>::type type;
  982. static type get(
  983. const detail::read_dynbuf_v2_op<AsyncReadStream,
  984. DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
  985. const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
  986. {
  987. return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
  988. }
  989. };
  990. #endif // !defined(GENERATING_DOCUMENTATION)
  991. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  992. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  993. std::size_t)) ReadHandler>
  994. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  995. void (boost::system::error_code, std::size_t))
  996. async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
  997. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  998. typename enable_if<
  999. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  1000. >::type*)
  1001. {
  1002. return async_read(s,
  1003. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  1004. transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  1005. }
  1006. template <typename AsyncReadStream,
  1007. typename DynamicBuffer_v2, typename CompletionCondition,
  1008. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  1009. std::size_t)) ReadHandler>
  1010. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  1011. void (boost::system::error_code, std::size_t))
  1012. async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
  1013. CompletionCondition completion_condition,
  1014. BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  1015. typename enable_if<
  1016. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  1017. >::type*)
  1018. {
  1019. // If you get an error on the following line it means that your handler does
  1020. // not meet the documented type requirements for a ReadHandler.
  1021. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1022. return async_initiate<ReadHandler,
  1023. void (boost::system::error_code, std::size_t)>(
  1024. detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),
  1025. handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  1026. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  1027. }
  1028. } // namespace asio
  1029. } // namespace boost
  1030. #include <boost/asio/detail/pop_options.hpp>
  1031. #endif // BOOST_ASIO_IMPL_READ_HPP