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