read.hpp 40 KB

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