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