read.hpp 44 KB

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