read.hpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. //
  2. // impl/read.hpp
  3. // ~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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/associator.hpp>
  17. #include <boost/asio/buffer.hpp>
  18. #include <boost/asio/completion_condition.hpp>
  19. #include <boost/asio/detail/array_fwd.hpp>
  20. #include <boost/asio/detail/base_from_cancellation_state.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. : public base_from_cancellation_state<ReadHandler>,
  300. base_from_completion_cond<CompletionCondition>
  301. {
  302. public:
  303. read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
  304. CompletionCondition& completion_condition, ReadHandler& handler)
  305. : base_from_cancellation_state<ReadHandler>(
  306. handler, enable_partial_cancellation()),
  307. base_from_completion_cond<CompletionCondition>(completion_condition),
  308. stream_(stream),
  309. buffers_(buffers),
  310. start_(0),
  311. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
  312. {
  313. }
  314. #if defined(BOOST_ASIO_HAS_MOVE)
  315. read_op(const read_op& other)
  316. : base_from_cancellation_state<ReadHandler>(other),
  317. base_from_completion_cond<CompletionCondition>(other),
  318. stream_(other.stream_),
  319. buffers_(other.buffers_),
  320. start_(other.start_),
  321. handler_(other.handler_)
  322. {
  323. }
  324. read_op(read_op&& other)
  325. : base_from_cancellation_state<ReadHandler>(
  326. BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
  327. ReadHandler>)(other)),
  328. base_from_completion_cond<CompletionCondition>(
  329. BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
  330. CompletionCondition>)(other)),
  331. stream_(other.stream_),
  332. buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
  333. start_(other.start_),
  334. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  335. {
  336. }
  337. #endif // defined(BOOST_ASIO_HAS_MOVE)
  338. void operator()(boost::system::error_code ec,
  339. std::size_t bytes_transferred, int start = 0)
  340. {
  341. std::size_t max_size;
  342. switch (start_ = start)
  343. {
  344. case 1:
  345. max_size = this->check_for_completion(ec, buffers_.total_consumed());
  346. for (;;)
  347. {
  348. {
  349. BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
  350. stream_.async_read_some(buffers_.prepare(max_size),
  351. BOOST_ASIO_MOVE_CAST(read_op)(*this));
  352. }
  353. return; default:
  354. buffers_.consume(bytes_transferred);
  355. if ((!ec && bytes_transferred == 0) || buffers_.empty())
  356. break;
  357. max_size = this->check_for_completion(ec, buffers_.total_consumed());
  358. if (max_size == 0)
  359. break;
  360. if (this->cancelled() != cancellation_type::none)
  361. {
  362. ec = error::operation_aborted;
  363. break;
  364. }
  365. }
  366. BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(
  367. static_cast<const boost::system::error_code&>(ec),
  368. static_cast<const std::size_t&>(buffers_.total_consumed()));
  369. }
  370. }
  371. //private:
  372. typedef boost::asio::detail::consuming_buffers<mutable_buffer,
  373. MutableBufferSequence, MutableBufferIterator> buffers_type;
  374. AsyncReadStream& stream_;
  375. buffers_type buffers_;
  376. int start_;
  377. ReadHandler handler_;
  378. };
  379. template <typename AsyncReadStream, typename MutableBufferSequence,
  380. typename MutableBufferIterator, typename CompletionCondition,
  381. typename ReadHandler>
  382. inline asio_handler_allocate_is_deprecated
  383. asio_handler_allocate(std::size_t size,
  384. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  385. CompletionCondition, ReadHandler>* this_handler)
  386. {
  387. #if defined(BOOST_ASIO_NO_DEPRECATED)
  388. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  389. return asio_handler_allocate_is_no_longer_used();
  390. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  391. return boost_asio_handler_alloc_helpers::allocate(
  392. size, this_handler->handler_);
  393. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  394. }
  395. template <typename AsyncReadStream, typename MutableBufferSequence,
  396. typename MutableBufferIterator, typename CompletionCondition,
  397. typename ReadHandler>
  398. inline asio_handler_deallocate_is_deprecated
  399. asio_handler_deallocate(void* pointer, std::size_t size,
  400. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  401. CompletionCondition, ReadHandler>* this_handler)
  402. {
  403. boost_asio_handler_alloc_helpers::deallocate(
  404. pointer, size, this_handler->handler_);
  405. #if defined(BOOST_ASIO_NO_DEPRECATED)
  406. return asio_handler_deallocate_is_no_longer_used();
  407. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  408. }
  409. template <typename AsyncReadStream, typename MutableBufferSequence,
  410. typename MutableBufferIterator, typename CompletionCondition,
  411. typename ReadHandler>
  412. inline bool asio_handler_is_continuation(
  413. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  414. CompletionCondition, ReadHandler>* this_handler)
  415. {
  416. return this_handler->start_ == 0 ? true
  417. : boost_asio_handler_cont_helpers::is_continuation(
  418. this_handler->handler_);
  419. }
  420. template <typename Function, typename AsyncReadStream,
  421. typename MutableBufferSequence, typename MutableBufferIterator,
  422. typename CompletionCondition, typename ReadHandler>
  423. inline asio_handler_invoke_is_deprecated
  424. asio_handler_invoke(Function& function,
  425. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  426. CompletionCondition, ReadHandler>* this_handler)
  427. {
  428. boost_asio_handler_invoke_helpers::invoke(
  429. function, this_handler->handler_);
  430. #if defined(BOOST_ASIO_NO_DEPRECATED)
  431. return asio_handler_invoke_is_no_longer_used();
  432. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  433. }
  434. template <typename Function, typename AsyncReadStream,
  435. typename MutableBufferSequence, typename MutableBufferIterator,
  436. typename CompletionCondition, typename ReadHandler>
  437. inline asio_handler_invoke_is_deprecated
  438. asio_handler_invoke(const Function& function,
  439. read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
  440. CompletionCondition, ReadHandler>* this_handler)
  441. {
  442. boost_asio_handler_invoke_helpers::invoke(
  443. function, this_handler->handler_);
  444. #if defined(BOOST_ASIO_NO_DEPRECATED)
  445. return asio_handler_invoke_is_no_longer_used();
  446. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  447. }
  448. template <typename AsyncReadStream, typename MutableBufferSequence,
  449. typename MutableBufferIterator, typename CompletionCondition,
  450. typename ReadHandler>
  451. inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
  452. const MutableBufferSequence& buffers, const MutableBufferIterator&,
  453. CompletionCondition& completion_condition, ReadHandler& handler)
  454. {
  455. detail::read_op<AsyncReadStream, MutableBufferSequence,
  456. MutableBufferIterator, CompletionCondition, ReadHandler>(
  457. stream, buffers, completion_condition, handler)(
  458. boost::system::error_code(), 0, 1);
  459. }
  460. template <typename AsyncReadStream>
  461. class initiate_async_read_buffer_sequence
  462. {
  463. public:
  464. typedef typename AsyncReadStream::executor_type executor_type;
  465. explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream)
  466. : stream_(stream)
  467. {
  468. }
  469. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  470. {
  471. return stream_.get_executor();
  472. }
  473. template <typename ReadHandler, typename MutableBufferSequence,
  474. typename CompletionCondition>
  475. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  476. const MutableBufferSequence& buffers,
  477. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  478. {
  479. // If you get an error on the following line it means that your handler
  480. // does not meet the documented type requirements for a ReadHandler.
  481. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  482. non_const_lvalue<ReadHandler> handler2(handler);
  483. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  484. start_read_buffer_sequence_op(stream_, buffers,
  485. boost::asio::buffer_sequence_begin(buffers),
  486. completion_cond2.value, handler2.value);
  487. }
  488. private:
  489. AsyncReadStream& stream_;
  490. };
  491. } // namespace detail
  492. #if !defined(GENERATING_DOCUMENTATION)
  493. template <template <typename, typename> class Associator,
  494. typename AsyncReadStream, typename MutableBufferSequence,
  495. typename MutableBufferIterator, typename CompletionCondition,
  496. typename ReadHandler, typename DefaultCandidate>
  497. struct associator<Associator,
  498. detail::read_op<AsyncReadStream, MutableBufferSequence,
  499. MutableBufferIterator, CompletionCondition, ReadHandler>,
  500. DefaultCandidate>
  501. : Associator<ReadHandler, DefaultCandidate>
  502. {
  503. static typename Associator<ReadHandler, DefaultCandidate>::type get(
  504. const detail::read_op<AsyncReadStream, MutableBufferSequence,
  505. MutableBufferIterator, CompletionCondition, ReadHandler>& h,
  506. const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
  507. {
  508. return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
  509. }
  510. };
  511. #endif // !defined(GENERATING_DOCUMENTATION)
  512. template <typename AsyncReadStream,
  513. typename MutableBufferSequence, typename CompletionCondition,
  514. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  515. std::size_t)) ReadToken>
  516. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  517. void (boost::system::error_code, std::size_t))
  518. async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
  519. CompletionCondition completion_condition,
  520. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  521. typename constraint<
  522. is_mutable_buffer_sequence<MutableBufferSequence>::value
  523. >::type)
  524. {
  525. return async_initiate<ReadToken,
  526. void (boost::system::error_code, std::size_t)>(
  527. detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), token,
  528. buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  529. }
  530. template <typename AsyncReadStream, typename MutableBufferSequence,
  531. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  532. std::size_t)) ReadToken>
  533. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  534. void (boost::system::error_code, std::size_t))
  535. async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
  536. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  537. typename constraint<
  538. is_mutable_buffer_sequence<MutableBufferSequence>::value
  539. >::type)
  540. {
  541. return async_initiate<ReadToken,
  542. void (boost::system::error_code, std::size_t)>(
  543. detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s),
  544. token, buffers, transfer_all());
  545. }
  546. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  547. namespace detail
  548. {
  549. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  550. typename CompletionCondition, typename ReadHandler>
  551. class read_dynbuf_v1_op
  552. : public base_from_cancellation_state<ReadHandler>,
  553. base_from_completion_cond<CompletionCondition>
  554. {
  555. public:
  556. template <typename BufferSequence>
  557. read_dynbuf_v1_op(AsyncReadStream& stream,
  558. BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
  559. CompletionCondition& completion_condition, ReadHandler& handler)
  560. : base_from_cancellation_state<ReadHandler>(
  561. handler, enable_partial_cancellation()),
  562. base_from_completion_cond<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. : base_from_cancellation_state<ReadHandler>(other),
  573. base_from_completion_cond<CompletionCondition>(other),
  574. stream_(other.stream_),
  575. buffers_(other.buffers_),
  576. start_(other.start_),
  577. total_transferred_(other.total_transferred_),
  578. handler_(other.handler_)
  579. {
  580. }
  581. read_dynbuf_v1_op(read_dynbuf_v1_op&& other)
  582. : base_from_cancellation_state<ReadHandler>(
  583. BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
  584. ReadHandler>)(other)),
  585. base_from_completion_cond<CompletionCondition>(
  586. BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
  587. CompletionCondition>)(other)),
  588. stream_(other.stream_),
  589. buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
  590. start_(other.start_),
  591. total_transferred_(other.total_transferred_),
  592. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  593. {
  594. }
  595. #endif // defined(BOOST_ASIO_HAS_MOVE)
  596. void operator()(boost::system::error_code ec,
  597. std::size_t bytes_transferred, int start = 0)
  598. {
  599. std::size_t max_size, bytes_available;
  600. switch (start_ = start)
  601. {
  602. case 1:
  603. max_size = this->check_for_completion(ec, total_transferred_);
  604. bytes_available = std::min<std::size_t>(
  605. std::max<std::size_t>(512,
  606. buffers_.capacity() - buffers_.size()),
  607. std::min<std::size_t>(max_size,
  608. buffers_.max_size() - buffers_.size()));
  609. for (;;)
  610. {
  611. {
  612. BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
  613. stream_.async_read_some(buffers_.prepare(bytes_available),
  614. BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));
  615. }
  616. return; default:
  617. total_transferred_ += bytes_transferred;
  618. buffers_.commit(bytes_transferred);
  619. max_size = this->check_for_completion(ec, total_transferred_);
  620. bytes_available = std::min<std::size_t>(
  621. std::max<std::size_t>(512,
  622. buffers_.capacity() - buffers_.size()),
  623. std::min<std::size_t>(max_size,
  624. buffers_.max_size() - buffers_.size()));
  625. if ((!ec && bytes_transferred == 0) || bytes_available == 0)
  626. break;
  627. if (this->cancelled() != cancellation_type::none)
  628. {
  629. ec = error::operation_aborted;
  630. break;
  631. }
  632. }
  633. BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(
  634. static_cast<const boost::system::error_code&>(ec),
  635. static_cast<const std::size_t&>(total_transferred_));
  636. }
  637. }
  638. //private:
  639. AsyncReadStream& stream_;
  640. DynamicBuffer_v1 buffers_;
  641. int start_;
  642. std::size_t total_transferred_;
  643. ReadHandler handler_;
  644. };
  645. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  646. typename CompletionCondition, typename ReadHandler>
  647. inline asio_handler_allocate_is_deprecated
  648. asio_handler_allocate(std::size_t size,
  649. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  650. CompletionCondition, ReadHandler>* this_handler)
  651. {
  652. #if defined(BOOST_ASIO_NO_DEPRECATED)
  653. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  654. return asio_handler_allocate_is_no_longer_used();
  655. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  656. return boost_asio_handler_alloc_helpers::allocate(
  657. size, this_handler->handler_);
  658. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  659. }
  660. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  661. typename CompletionCondition, typename ReadHandler>
  662. inline asio_handler_deallocate_is_deprecated
  663. asio_handler_deallocate(void* pointer, std::size_t size,
  664. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  665. CompletionCondition, ReadHandler>* this_handler)
  666. {
  667. boost_asio_handler_alloc_helpers::deallocate(
  668. pointer, size, this_handler->handler_);
  669. #if defined(BOOST_ASIO_NO_DEPRECATED)
  670. return asio_handler_deallocate_is_no_longer_used();
  671. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  672. }
  673. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  674. typename CompletionCondition, typename ReadHandler>
  675. inline bool asio_handler_is_continuation(
  676. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  677. CompletionCondition, ReadHandler>* this_handler)
  678. {
  679. return this_handler->start_ == 0 ? true
  680. : boost_asio_handler_cont_helpers::is_continuation(
  681. this_handler->handler_);
  682. }
  683. template <typename Function, typename AsyncReadStream,
  684. typename DynamicBuffer_v1, typename CompletionCondition,
  685. typename ReadHandler>
  686. inline asio_handler_invoke_is_deprecated
  687. asio_handler_invoke(Function& function,
  688. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  689. CompletionCondition, ReadHandler>* this_handler)
  690. {
  691. boost_asio_handler_invoke_helpers::invoke(
  692. function, this_handler->handler_);
  693. #if defined(BOOST_ASIO_NO_DEPRECATED)
  694. return asio_handler_invoke_is_no_longer_used();
  695. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  696. }
  697. template <typename Function, typename AsyncReadStream,
  698. typename DynamicBuffer_v1, typename CompletionCondition,
  699. typename ReadHandler>
  700. inline asio_handler_invoke_is_deprecated
  701. asio_handler_invoke(const Function& function,
  702. read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
  703. CompletionCondition, ReadHandler>* this_handler)
  704. {
  705. boost_asio_handler_invoke_helpers::invoke(
  706. function, this_handler->handler_);
  707. #if defined(BOOST_ASIO_NO_DEPRECATED)
  708. return asio_handler_invoke_is_no_longer_used();
  709. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  710. }
  711. template <typename AsyncReadStream>
  712. class initiate_async_read_dynbuf_v1
  713. {
  714. public:
  715. typedef typename AsyncReadStream::executor_type executor_type;
  716. explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream)
  717. : stream_(stream)
  718. {
  719. }
  720. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  721. {
  722. return stream_.get_executor();
  723. }
  724. template <typename ReadHandler, typename DynamicBuffer_v1,
  725. typename CompletionCondition>
  726. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  727. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  728. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  729. {
  730. // If you get an error on the following line it means that your handler
  731. // does not meet the documented type requirements for a ReadHandler.
  732. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  733. non_const_lvalue<ReadHandler> handler2(handler);
  734. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  735. read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
  736. CompletionCondition, typename decay<ReadHandler>::type>(
  737. stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  738. completion_cond2.value, handler2.value)(
  739. boost::system::error_code(), 0, 1);
  740. }
  741. private:
  742. AsyncReadStream& stream_;
  743. };
  744. } // namespace detail
  745. #if !defined(GENERATING_DOCUMENTATION)
  746. template <template <typename, typename> class Associator,
  747. typename AsyncReadStream, typename DynamicBuffer_v1,
  748. typename CompletionCondition, typename ReadHandler,
  749. typename DefaultCandidate>
  750. struct associator<Associator,
  751. detail::read_dynbuf_v1_op<AsyncReadStream,
  752. DynamicBuffer_v1, CompletionCondition, ReadHandler>,
  753. DefaultCandidate>
  754. : Associator<ReadHandler, DefaultCandidate>
  755. {
  756. static typename Associator<ReadHandler, DefaultCandidate>::type get(
  757. const detail::read_dynbuf_v1_op<AsyncReadStream,
  758. DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
  759. const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
  760. {
  761. return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
  762. }
  763. };
  764. #endif // !defined(GENERATING_DOCUMENTATION)
  765. template <typename AsyncReadStream, typename DynamicBuffer_v1,
  766. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  767. std::size_t)) ReadToken>
  768. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  769. void (boost::system::error_code, std::size_t))
  770. async_read(AsyncReadStream& s,
  771. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  772. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  773. typename constraint<
  774. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  775. >::type,
  776. typename constraint<
  777. !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  778. >::type)
  779. {
  780. return async_read(s,
  781. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  782. transfer_all(), BOOST_ASIO_MOVE_CAST(ReadToken)(token));
  783. }
  784. template <typename AsyncReadStream,
  785. typename DynamicBuffer_v1, typename CompletionCondition,
  786. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  787. std::size_t)) ReadToken>
  788. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  789. void (boost::system::error_code, std::size_t))
  790. async_read(AsyncReadStream& s,
  791. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
  792. CompletionCondition completion_condition,
  793. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  794. typename constraint<
  795. is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
  796. >::type,
  797. typename constraint<
  798. !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
  799. >::type)
  800. {
  801. return async_initiate<ReadToken,
  802. void (boost::system::error_code, std::size_t)>(
  803. detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),
  804. token, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
  805. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  806. }
  807. #if !defined(BOOST_ASIO_NO_EXTENSIONS)
  808. #if !defined(BOOST_ASIO_NO_IOSTREAM)
  809. template <typename AsyncReadStream, typename Allocator,
  810. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  811. std::size_t)) ReadToken>
  812. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  813. void (boost::system::error_code, std::size_t))
  814. async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
  815. BOOST_ASIO_MOVE_ARG(ReadToken) token)
  816. {
  817. return async_read(s, basic_streambuf_ref<Allocator>(b),
  818. BOOST_ASIO_MOVE_CAST(ReadToken)(token));
  819. }
  820. template <typename AsyncReadStream,
  821. typename Allocator, typename CompletionCondition,
  822. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  823. std::size_t)) ReadToken>
  824. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  825. void (boost::system::error_code, std::size_t))
  826. async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
  827. CompletionCondition completion_condition,
  828. BOOST_ASIO_MOVE_ARG(ReadToken) token)
  829. {
  830. return async_read(s, basic_streambuf_ref<Allocator>(b),
  831. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
  832. BOOST_ASIO_MOVE_CAST(ReadToken)(token));
  833. }
  834. #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
  835. #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
  836. #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
  837. namespace detail
  838. {
  839. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  840. typename CompletionCondition, typename ReadHandler>
  841. class read_dynbuf_v2_op
  842. : public base_from_cancellation_state<ReadHandler>,
  843. base_from_completion_cond<CompletionCondition>
  844. {
  845. public:
  846. template <typename BufferSequence>
  847. read_dynbuf_v2_op(AsyncReadStream& stream,
  848. BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
  849. CompletionCondition& completion_condition, ReadHandler& handler)
  850. : base_from_cancellation_state<ReadHandler>(
  851. handler, enable_partial_cancellation()),
  852. base_from_completion_cond<CompletionCondition>(completion_condition),
  853. stream_(stream),
  854. buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
  855. start_(0),
  856. total_transferred_(0),
  857. bytes_available_(0),
  858. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
  859. {
  860. }
  861. #if defined(BOOST_ASIO_HAS_MOVE)
  862. read_dynbuf_v2_op(const read_dynbuf_v2_op& other)
  863. : base_from_cancellation_state<ReadHandler>(other),
  864. base_from_completion_cond<CompletionCondition>(other),
  865. stream_(other.stream_),
  866. buffers_(other.buffers_),
  867. start_(other.start_),
  868. total_transferred_(other.total_transferred_),
  869. bytes_available_(other.bytes_available_),
  870. handler_(other.handler_)
  871. {
  872. }
  873. read_dynbuf_v2_op(read_dynbuf_v2_op&& other)
  874. : base_from_cancellation_state<ReadHandler>(
  875. BOOST_ASIO_MOVE_CAST(base_from_cancellation_state<
  876. ReadHandler>)(other)),
  877. base_from_completion_cond<CompletionCondition>(
  878. BOOST_ASIO_MOVE_CAST(base_from_completion_cond<
  879. CompletionCondition>)(other)),
  880. stream_(other.stream_),
  881. buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
  882. start_(other.start_),
  883. total_transferred_(other.total_transferred_),
  884. bytes_available_(other.bytes_available_),
  885. handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
  886. {
  887. }
  888. #endif // defined(BOOST_ASIO_HAS_MOVE)
  889. void operator()(boost::system::error_code ec,
  890. std::size_t bytes_transferred, int start = 0)
  891. {
  892. std::size_t max_size, pos;
  893. switch (start_ = start)
  894. {
  895. case 1:
  896. max_size = this->check_for_completion(ec, total_transferred_);
  897. bytes_available_ = std::min<std::size_t>(
  898. std::max<std::size_t>(512,
  899. buffers_.capacity() - buffers_.size()),
  900. std::min<std::size_t>(max_size,
  901. buffers_.max_size() - buffers_.size()));
  902. for (;;)
  903. {
  904. pos = buffers_.size();
  905. buffers_.grow(bytes_available_);
  906. {
  907. BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));
  908. stream_.async_read_some(buffers_.data(pos, bytes_available_),
  909. BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));
  910. }
  911. return; default:
  912. total_transferred_ += bytes_transferred;
  913. buffers_.shrink(bytes_available_ - bytes_transferred);
  914. max_size = this->check_for_completion(ec, total_transferred_);
  915. bytes_available_ = std::min<std::size_t>(
  916. std::max<std::size_t>(512,
  917. buffers_.capacity() - buffers_.size()),
  918. std::min<std::size_t>(max_size,
  919. buffers_.max_size() - buffers_.size()));
  920. if ((!ec && bytes_transferred == 0) || bytes_available_ == 0)
  921. break;
  922. if (this->cancelled() != cancellation_type::none)
  923. {
  924. ec = error::operation_aborted;
  925. break;
  926. }
  927. }
  928. BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(
  929. static_cast<const boost::system::error_code&>(ec),
  930. static_cast<const std::size_t&>(total_transferred_));
  931. }
  932. }
  933. //private:
  934. AsyncReadStream& stream_;
  935. DynamicBuffer_v2 buffers_;
  936. int start_;
  937. std::size_t total_transferred_;
  938. std::size_t bytes_available_;
  939. ReadHandler handler_;
  940. };
  941. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  942. typename CompletionCondition, typename ReadHandler>
  943. inline asio_handler_allocate_is_deprecated
  944. asio_handler_allocate(std::size_t size,
  945. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  946. CompletionCondition, ReadHandler>* this_handler)
  947. {
  948. #if defined(BOOST_ASIO_NO_DEPRECATED)
  949. boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
  950. return asio_handler_allocate_is_no_longer_used();
  951. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  952. return boost_asio_handler_alloc_helpers::allocate(
  953. size, this_handler->handler_);
  954. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  955. }
  956. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  957. typename CompletionCondition, typename ReadHandler>
  958. inline asio_handler_deallocate_is_deprecated
  959. asio_handler_deallocate(void* pointer, std::size_t size,
  960. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  961. CompletionCondition, ReadHandler>* this_handler)
  962. {
  963. boost_asio_handler_alloc_helpers::deallocate(
  964. pointer, size, this_handler->handler_);
  965. #if defined(BOOST_ASIO_NO_DEPRECATED)
  966. return asio_handler_deallocate_is_no_longer_used();
  967. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  968. }
  969. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  970. typename CompletionCondition, typename ReadHandler>
  971. inline bool asio_handler_is_continuation(
  972. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  973. CompletionCondition, ReadHandler>* this_handler)
  974. {
  975. return this_handler->start_ == 0 ? true
  976. : boost_asio_handler_cont_helpers::is_continuation(
  977. this_handler->handler_);
  978. }
  979. template <typename Function, typename AsyncReadStream,
  980. typename DynamicBuffer_v2, typename CompletionCondition,
  981. typename ReadHandler>
  982. inline asio_handler_invoke_is_deprecated
  983. asio_handler_invoke(Function& function,
  984. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  985. CompletionCondition, ReadHandler>* this_handler)
  986. {
  987. boost_asio_handler_invoke_helpers::invoke(
  988. function, this_handler->handler_);
  989. #if defined(BOOST_ASIO_NO_DEPRECATED)
  990. return asio_handler_invoke_is_no_longer_used();
  991. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  992. }
  993. template <typename Function, typename AsyncReadStream,
  994. typename DynamicBuffer_v2, typename CompletionCondition,
  995. typename ReadHandler>
  996. inline asio_handler_invoke_is_deprecated
  997. asio_handler_invoke(const Function& function,
  998. read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
  999. CompletionCondition, ReadHandler>* this_handler)
  1000. {
  1001. boost_asio_handler_invoke_helpers::invoke(
  1002. function, this_handler->handler_);
  1003. #if defined(BOOST_ASIO_NO_DEPRECATED)
  1004. return asio_handler_invoke_is_no_longer_used();
  1005. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  1006. }
  1007. template <typename AsyncReadStream>
  1008. class initiate_async_read_dynbuf_v2
  1009. {
  1010. public:
  1011. typedef typename AsyncReadStream::executor_type executor_type;
  1012. explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream)
  1013. : stream_(stream)
  1014. {
  1015. }
  1016. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1017. {
  1018. return stream_.get_executor();
  1019. }
  1020. template <typename ReadHandler, typename DynamicBuffer_v2,
  1021. typename CompletionCondition>
  1022. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  1023. BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
  1024. BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
  1025. {
  1026. // If you get an error on the following line it means that your handler
  1027. // does not meet the documented type requirements for a ReadHandler.
  1028. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1029. non_const_lvalue<ReadHandler> handler2(handler);
  1030. non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
  1031. read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
  1032. CompletionCondition, typename decay<ReadHandler>::type>(
  1033. stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  1034. completion_cond2.value, handler2.value)(
  1035. boost::system::error_code(), 0, 1);
  1036. }
  1037. private:
  1038. AsyncReadStream& stream_;
  1039. };
  1040. } // namespace detail
  1041. #if !defined(GENERATING_DOCUMENTATION)
  1042. template <template <typename, typename> class Associator,
  1043. typename AsyncReadStream, typename DynamicBuffer_v2,
  1044. typename CompletionCondition, typename ReadHandler,
  1045. typename DefaultCandidate>
  1046. struct associator<Associator,
  1047. detail::read_dynbuf_v2_op<AsyncReadStream,
  1048. DynamicBuffer_v2, CompletionCondition, ReadHandler>,
  1049. DefaultCandidate>
  1050. : Associator<ReadHandler, DefaultCandidate>
  1051. {
  1052. static typename Associator<ReadHandler, DefaultCandidate>::type get(
  1053. const detail::read_dynbuf_v2_op<AsyncReadStream,
  1054. DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
  1055. const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT
  1056. {
  1057. return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
  1058. }
  1059. };
  1060. #endif // !defined(GENERATING_DOCUMENTATION)
  1061. template <typename AsyncReadStream, typename DynamicBuffer_v2,
  1062. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  1063. std::size_t)) ReadToken>
  1064. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  1065. void (boost::system::error_code, std::size_t))
  1066. async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
  1067. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  1068. typename constraint<
  1069. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  1070. >::type)
  1071. {
  1072. return async_read(s,
  1073. BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  1074. transfer_all(), BOOST_ASIO_MOVE_CAST(ReadToken)(token));
  1075. }
  1076. template <typename AsyncReadStream,
  1077. typename DynamicBuffer_v2, typename CompletionCondition,
  1078. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  1079. std::size_t)) ReadToken>
  1080. inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  1081. void (boost::system::error_code, std::size_t))
  1082. async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
  1083. CompletionCondition completion_condition,
  1084. BOOST_ASIO_MOVE_ARG(ReadToken) token,
  1085. typename constraint<
  1086. is_dynamic_buffer_v2<DynamicBuffer_v2>::value
  1087. >::type)
  1088. {
  1089. return async_initiate<ReadToken,
  1090. void (boost::system::error_code, std::size_t)>(
  1091. detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),
  1092. token, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
  1093. BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
  1094. }
  1095. } // namespace asio
  1096. } // namespace boost
  1097. #include <boost/asio/detail/pop_options.hpp>
  1098. #endif // BOOST_ASIO_IMPL_READ_HPP