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