read.hpp 42 KB

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