5 // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_IMPL_READ_HPP
12 #define BOOST_ASIO_IMPL_READ_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/associated_allocator.hpp>
20 #include <boost/asio/associated_executor.hpp>
21 #include <boost/asio/buffer.hpp>
22 #include <boost/asio/completion_condition.hpp>
23 #include <boost/asio/detail/array_fwd.hpp>
24 #include <boost/asio/detail/base_from_completion_cond.hpp>
25 #include <boost/asio/detail/bind_handler.hpp>
26 #include <boost/asio/detail/consuming_buffers.hpp>
27 #include <boost/asio/detail/dependent_type.hpp>
28 #include <boost/asio/detail/handler_alloc_helpers.hpp>
29 #include <boost/asio/detail/handler_cont_helpers.hpp>
30 #include <boost/asio/detail/handler_invoke_helpers.hpp>
31 #include <boost/asio/detail/handler_type_requirements.hpp>
32 #include <boost/asio/detail/throw_error.hpp>
33 #include <boost/asio/error.hpp>
35 #include <boost/asio/detail/push_options.hpp>
42 template <typename SyncReadStream, typename MutableBufferSequence,
43 typename MutableBufferIterator, typename CompletionCondition>
44 std::size_t read_buffer_sequence(SyncReadStream& s,
45 const MutableBufferSequence& buffers, const MutableBufferIterator&,
46 CompletionCondition completion_condition, boost::system::error_code& ec)
48 ec = boost::system::error_code();
49 boost::asio::detail::consuming_buffers<mutable_buffer,
50 MutableBufferSequence, MutableBufferIterator> tmp(buffers);
53 if (std::size_t max_size = detail::adapt_completion_condition_result(
54 completion_condition(ec, tmp.total_consumed())))
55 tmp.consume(s.read_some(tmp.prepare(max_size), ec));
59 return tmp.total_consumed();;
63 template <typename SyncReadStream, typename MutableBufferSequence,
64 typename CompletionCondition>
65 std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
66 CompletionCondition completion_condition, boost::system::error_code& ec,
68 is_mutable_buffer_sequence<MutableBufferSequence>::value
71 return detail::read_buffer_sequence(s, buffers,
72 boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
75 template <typename SyncReadStream, typename MutableBufferSequence>
76 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
78 is_mutable_buffer_sequence<MutableBufferSequence>::value
81 boost::system::error_code ec;
82 std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
83 boost::asio::detail::throw_error(ec, "read");
84 return bytes_transferred;
87 template <typename SyncReadStream, typename MutableBufferSequence>
88 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
89 boost::system::error_code& ec,
91 is_mutable_buffer_sequence<MutableBufferSequence>::value
94 return read(s, buffers, transfer_all(), ec);
97 template <typename SyncReadStream, typename MutableBufferSequence,
98 typename CompletionCondition>
99 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
100 CompletionCondition completion_condition,
102 is_mutable_buffer_sequence<MutableBufferSequence>::value
105 boost::system::error_code ec;
106 std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
107 boost::asio::detail::throw_error(ec, "read");
108 return bytes_transferred;
111 template <typename SyncReadStream, typename DynamicBuffer,
112 typename CompletionCondition>
113 std::size_t read(SyncReadStream& s,
114 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
115 CompletionCondition completion_condition, boost::system::error_code& ec,
117 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
120 typename decay<DynamicBuffer>::type b(
121 BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
123 ec = boost::system::error_code();
124 std::size_t total_transferred = 0;
125 std::size_t max_size = detail::adapt_completion_condition_result(
126 completion_condition(ec, total_transferred));
127 std::size_t bytes_available = std::min<std::size_t>(
128 std::max<std::size_t>(512, b.capacity() - b.size()),
129 std::min<std::size_t>(max_size, b.max_size() - b.size()));
130 while (bytes_available > 0)
132 std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
133 b.commit(bytes_transferred);
134 total_transferred += bytes_transferred;
135 max_size = detail::adapt_completion_condition_result(
136 completion_condition(ec, total_transferred));
137 bytes_available = std::min<std::size_t>(
138 std::max<std::size_t>(512, b.capacity() - b.size()),
139 std::min<std::size_t>(max_size, b.max_size() - b.size()));
141 return total_transferred;
144 template <typename SyncReadStream, typename DynamicBuffer>
145 inline std::size_t read(SyncReadStream& s,
146 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
148 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
151 boost::system::error_code ec;
152 std::size_t bytes_transferred = read(s,
153 BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), transfer_all(), ec);
154 boost::asio::detail::throw_error(ec, "read");
155 return bytes_transferred;
158 template <typename SyncReadStream, typename DynamicBuffer>
159 inline std::size_t read(SyncReadStream& s,
160 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
161 boost::system::error_code& ec,
163 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
166 return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
170 template <typename SyncReadStream, typename DynamicBuffer,
171 typename CompletionCondition>
172 inline std::size_t read(SyncReadStream& s,
173 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
174 CompletionCondition completion_condition,
176 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
179 boost::system::error_code ec;
180 std::size_t bytes_transferred = read(s,
181 BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
182 completion_condition, ec);
183 boost::asio::detail::throw_error(ec, "read");
184 return bytes_transferred;
187 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
188 #if !defined(BOOST_ASIO_NO_IOSTREAM)
190 template <typename SyncReadStream, typename Allocator,
191 typename CompletionCondition>
192 inline std::size_t read(SyncReadStream& s,
193 boost::asio::basic_streambuf<Allocator>& b,
194 CompletionCondition completion_condition, boost::system::error_code& ec)
196 return read(s, basic_streambuf_ref<Allocator>(b), completion_condition, ec);
199 template <typename SyncReadStream, typename Allocator>
200 inline std::size_t read(SyncReadStream& s,
201 boost::asio::basic_streambuf<Allocator>& b)
203 return read(s, basic_streambuf_ref<Allocator>(b));
206 template <typename SyncReadStream, typename Allocator>
207 inline std::size_t read(SyncReadStream& s,
208 boost::asio::basic_streambuf<Allocator>& b,
209 boost::system::error_code& ec)
211 return read(s, basic_streambuf_ref<Allocator>(b), ec);
214 template <typename SyncReadStream, typename Allocator,
215 typename CompletionCondition>
216 inline std::size_t read(SyncReadStream& s,
217 boost::asio::basic_streambuf<Allocator>& b,
218 CompletionCondition completion_condition)
220 return read(s, basic_streambuf_ref<Allocator>(b), completion_condition);
223 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
224 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
228 template <typename AsyncReadStream, typename MutableBufferSequence,
229 typename MutableBufferIterator, typename CompletionCondition,
230 typename ReadHandler>
232 : detail::base_from_completion_cond<CompletionCondition>
235 read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
236 CompletionCondition completion_condition, ReadHandler& handler)
237 : detail::base_from_completion_cond<
238 CompletionCondition>(completion_condition),
242 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
246 #if defined(BOOST_ASIO_HAS_MOVE)
247 read_op(const read_op& other)
248 : detail::base_from_completion_cond<CompletionCondition>(other),
249 stream_(other.stream_),
250 buffers_(other.buffers_),
251 start_(other.start_),
252 handler_(other.handler_)
256 read_op(read_op&& other)
257 : detail::base_from_completion_cond<CompletionCondition>(other),
258 stream_(other.stream_),
259 buffers_(other.buffers_),
260 start_(other.start_),
261 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
264 #endif // defined(BOOST_ASIO_HAS_MOVE)
266 void operator()(const boost::system::error_code& ec,
267 std::size_t bytes_transferred, int start = 0)
269 std::size_t max_size;
270 switch (start_ = start)
273 max_size = this->check_for_completion(ec, buffers_.total_consumed());
276 stream_.async_read_some(buffers_.prepare(max_size),
277 BOOST_ASIO_MOVE_CAST(read_op)(*this));
279 buffers_.consume(bytes_transferred);
280 if ((!ec && bytes_transferred == 0) || buffers_.empty())
282 max_size = this->check_for_completion(ec, buffers_.total_consumed());
283 } while (max_size > 0);
285 handler_(ec, buffers_.total_consumed());
290 AsyncReadStream& stream_;
291 boost::asio::detail::consuming_buffers<mutable_buffer,
292 MutableBufferSequence, MutableBufferIterator> buffers_;
294 ReadHandler handler_;
297 template <typename AsyncReadStream, typename MutableBufferSequence,
298 typename MutableBufferIterator, typename CompletionCondition,
299 typename ReadHandler>
300 inline void* asio_handler_allocate(std::size_t size,
301 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
302 CompletionCondition, ReadHandler>* this_handler)
304 return boost_asio_handler_alloc_helpers::allocate(
305 size, this_handler->handler_);
308 template <typename AsyncReadStream, typename MutableBufferSequence,
309 typename MutableBufferIterator, typename CompletionCondition,
310 typename ReadHandler>
311 inline void asio_handler_deallocate(void* pointer, std::size_t size,
312 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
313 CompletionCondition, ReadHandler>* this_handler)
315 boost_asio_handler_alloc_helpers::deallocate(
316 pointer, size, this_handler->handler_);
319 template <typename AsyncReadStream, typename MutableBufferSequence,
320 typename MutableBufferIterator, typename CompletionCondition,
321 typename ReadHandler>
322 inline bool asio_handler_is_continuation(
323 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
324 CompletionCondition, ReadHandler>* this_handler)
326 return this_handler->start_ == 0 ? true
327 : boost_asio_handler_cont_helpers::is_continuation(
328 this_handler->handler_);
331 template <typename Function, typename AsyncReadStream,
332 typename MutableBufferSequence, typename MutableBufferIterator,
333 typename CompletionCondition, typename ReadHandler>
334 inline void asio_handler_invoke(Function& function,
335 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
336 CompletionCondition, ReadHandler>* this_handler)
338 boost_asio_handler_invoke_helpers::invoke(
339 function, this_handler->handler_);
342 template <typename Function, typename AsyncReadStream,
343 typename MutableBufferSequence, typename MutableBufferIterator,
344 typename CompletionCondition, typename ReadHandler>
345 inline void asio_handler_invoke(const Function& function,
346 read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,
347 CompletionCondition, ReadHandler>* this_handler)
349 boost_asio_handler_invoke_helpers::invoke(
350 function, this_handler->handler_);
353 template <typename AsyncReadStream, typename MutableBufferSequence,
354 typename MutableBufferIterator, typename CompletionCondition,
355 typename ReadHandler>
356 inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
357 const MutableBufferSequence& buffers, const MutableBufferIterator&,
358 CompletionCondition completion_condition, ReadHandler& handler)
360 detail::read_op<AsyncReadStream, MutableBufferSequence,
361 MutableBufferIterator, CompletionCondition, ReadHandler>(
362 stream, buffers, completion_condition, handler)(
363 boost::system::error_code(), 0, 1);
365 } // namespace detail
367 #if !defined(GENERATING_DOCUMENTATION)
369 template <typename AsyncReadStream, typename MutableBufferSequence,
370 typename MutableBufferIterator, typename CompletionCondition,
371 typename ReadHandler, typename Allocator>
372 struct associated_allocator<
373 detail::read_op<AsyncReadStream, MutableBufferSequence,
374 MutableBufferIterator, CompletionCondition, ReadHandler>,
377 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
380 const detail::read_op<AsyncReadStream, MutableBufferSequence,
381 MutableBufferIterator, CompletionCondition, ReadHandler>& h,
382 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
384 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
388 template <typename AsyncReadStream, typename MutableBufferSequence,
389 typename MutableBufferIterator, typename CompletionCondition,
390 typename ReadHandler, typename Executor>
391 struct associated_executor<
392 detail::read_op<AsyncReadStream, MutableBufferSequence,
393 MutableBufferIterator, CompletionCondition, ReadHandler>,
396 typedef typename associated_executor<ReadHandler, Executor>::type type;
399 const detail::read_op<AsyncReadStream, MutableBufferSequence,
400 MutableBufferIterator, CompletionCondition, ReadHandler>& h,
401 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
403 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
407 #endif // !defined(GENERATING_DOCUMENTATION)
409 template <typename AsyncReadStream, typename MutableBufferSequence,
410 typename CompletionCondition, typename ReadHandler>
411 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
412 void (boost::system::error_code, std::size_t))
413 async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
414 CompletionCondition completion_condition,
415 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
417 is_mutable_buffer_sequence<MutableBufferSequence>::value
420 // If you get an error on the following line it means that your handler does
421 // not meet the documented type requirements for a ReadHandler.
422 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
424 async_completion<ReadHandler,
425 void (boost::system::error_code, std::size_t)> init(handler);
427 detail::start_read_buffer_sequence_op(s, buffers,
428 boost::asio::buffer_sequence_begin(buffers), completion_condition,
429 init.completion_handler);
431 return init.result.get();
434 template <typename AsyncReadStream, typename MutableBufferSequence,
435 typename ReadHandler>
436 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
437 void (boost::system::error_code, std::size_t))
438 async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
439 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
441 is_mutable_buffer_sequence<MutableBufferSequence>::value
444 // If you get an error on the following line it means that your handler does
445 // not meet the documented type requirements for a ReadHandler.
446 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
448 async_completion<ReadHandler,
449 void (boost::system::error_code, std::size_t)> init(handler);
451 detail::start_read_buffer_sequence_op(s, buffers,
452 boost::asio::buffer_sequence_begin(buffers), transfer_all(),
453 init.completion_handler);
455 return init.result.get();
460 template <typename AsyncReadStream, typename DynamicBuffer,
461 typename CompletionCondition, typename ReadHandler>
463 : detail::base_from_completion_cond<CompletionCondition>
466 template <typename BufferSequence>
467 read_dynbuf_op(AsyncReadStream& stream,
468 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
469 CompletionCondition completion_condition, ReadHandler& handler)
470 : detail::base_from_completion_cond<
471 CompletionCondition>(completion_condition),
473 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
475 total_transferred_(0),
476 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
480 #if defined(BOOST_ASIO_HAS_MOVE)
481 read_dynbuf_op(const read_dynbuf_op& other)
482 : detail::base_from_completion_cond<CompletionCondition>(other),
483 stream_(other.stream_),
484 buffers_(other.buffers_),
485 start_(other.start_),
486 total_transferred_(other.total_transferred_),
487 handler_(other.handler_)
491 read_dynbuf_op(read_dynbuf_op&& other)
492 : detail::base_from_completion_cond<CompletionCondition>(other),
493 stream_(other.stream_),
494 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
495 start_(other.start_),
496 total_transferred_(other.total_transferred_),
497 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
500 #endif // defined(BOOST_ASIO_HAS_MOVE)
502 void operator()(const boost::system::error_code& ec,
503 std::size_t bytes_transferred, int start = 0)
505 std::size_t max_size, bytes_available;
506 switch (start_ = start)
509 max_size = this->check_for_completion(ec, total_transferred_);
510 bytes_available = std::min<std::size_t>(
511 std::max<std::size_t>(512,
512 buffers_.capacity() - buffers_.size()),
513 std::min<std::size_t>(max_size,
514 buffers_.max_size() - buffers_.size()));
517 stream_.async_read_some(buffers_.prepare(bytes_available),
518 BOOST_ASIO_MOVE_CAST(read_dynbuf_op)(*this));
520 total_transferred_ += bytes_transferred;
521 buffers_.commit(bytes_transferred);
522 max_size = this->check_for_completion(ec, total_transferred_);
523 bytes_available = std::min<std::size_t>(
524 std::max<std::size_t>(512,
525 buffers_.capacity() - buffers_.size()),
526 std::min<std::size_t>(max_size,
527 buffers_.max_size() - buffers_.size()));
528 if ((!ec && bytes_transferred == 0) || bytes_available == 0)
532 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
537 AsyncReadStream& stream_;
538 DynamicBuffer buffers_;
540 std::size_t total_transferred_;
541 ReadHandler handler_;
544 template <typename AsyncReadStream, typename DynamicBuffer,
545 typename CompletionCondition, typename ReadHandler>
546 inline void* asio_handler_allocate(std::size_t size,
547 read_dynbuf_op<AsyncReadStream, DynamicBuffer,
548 CompletionCondition, ReadHandler>* this_handler)
550 return boost_asio_handler_alloc_helpers::allocate(
551 size, this_handler->handler_);
554 template <typename AsyncReadStream, typename DynamicBuffer,
555 typename CompletionCondition, typename ReadHandler>
556 inline void asio_handler_deallocate(void* pointer, std::size_t size,
557 read_dynbuf_op<AsyncReadStream, DynamicBuffer,
558 CompletionCondition, ReadHandler>* this_handler)
560 boost_asio_handler_alloc_helpers::deallocate(
561 pointer, size, this_handler->handler_);
564 template <typename AsyncReadStream, typename DynamicBuffer,
565 typename CompletionCondition, typename ReadHandler>
566 inline bool asio_handler_is_continuation(
567 read_dynbuf_op<AsyncReadStream, DynamicBuffer,
568 CompletionCondition, ReadHandler>* this_handler)
570 return this_handler->start_ == 0 ? true
571 : boost_asio_handler_cont_helpers::is_continuation(
572 this_handler->handler_);
575 template <typename Function, typename AsyncReadStream,
576 typename DynamicBuffer, typename CompletionCondition,
577 typename ReadHandler>
578 inline void asio_handler_invoke(Function& function,
579 read_dynbuf_op<AsyncReadStream, DynamicBuffer,
580 CompletionCondition, ReadHandler>* this_handler)
582 boost_asio_handler_invoke_helpers::invoke(
583 function, this_handler->handler_);
586 template <typename Function, typename AsyncReadStream,
587 typename DynamicBuffer, typename CompletionCondition,
588 typename ReadHandler>
589 inline void asio_handler_invoke(const Function& function,
590 read_dynbuf_op<AsyncReadStream, DynamicBuffer,
591 CompletionCondition, ReadHandler>* this_handler)
593 boost_asio_handler_invoke_helpers::invoke(
594 function, this_handler->handler_);
596 } // namespace detail
598 #if !defined(GENERATING_DOCUMENTATION)
600 template <typename AsyncReadStream, typename DynamicBuffer,
601 typename CompletionCondition, typename ReadHandler, typename Allocator>
602 struct associated_allocator<
603 detail::read_dynbuf_op<AsyncReadStream,
604 DynamicBuffer, CompletionCondition, ReadHandler>,
607 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
610 const detail::read_dynbuf_op<AsyncReadStream,
611 DynamicBuffer, CompletionCondition, ReadHandler>& h,
612 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
614 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
618 template <typename AsyncReadStream, typename DynamicBuffer,
619 typename CompletionCondition, typename ReadHandler, typename Executor>
620 struct associated_executor<
621 detail::read_dynbuf_op<AsyncReadStream,
622 DynamicBuffer, CompletionCondition, ReadHandler>,
625 typedef typename associated_executor<ReadHandler, Executor>::type type;
628 const detail::read_dynbuf_op<AsyncReadStream,
629 DynamicBuffer, CompletionCondition, ReadHandler>& h,
630 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
632 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
636 #endif // !defined(GENERATING_DOCUMENTATION)
638 template <typename AsyncReadStream,
639 typename DynamicBuffer, typename ReadHandler>
640 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
641 void (boost::system::error_code, std::size_t))
642 async_read(AsyncReadStream& s,
643 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
644 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
646 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
650 BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
651 transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
654 template <typename AsyncReadStream, typename DynamicBuffer,
655 typename CompletionCondition, typename ReadHandler>
656 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
657 void (boost::system::error_code, std::size_t))
658 async_read(AsyncReadStream& s,
659 BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
660 CompletionCondition completion_condition,
661 BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
663 is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
666 // If you get an error on the following line it means that your handler does
667 // not meet the documented type requirements for a ReadHandler.
668 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
670 async_completion<ReadHandler,
671 void (boost::system::error_code, std::size_t)> init(handler);
673 detail::read_dynbuf_op<AsyncReadStream,
674 typename decay<DynamicBuffer>::type,
675 CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
676 ReadHandler, void (boost::system::error_code, std::size_t))>(
677 s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
678 completion_condition, init.completion_handler)(
679 boost::system::error_code(), 0, 1);
681 return init.result.get();
684 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
685 #if !defined(BOOST_ASIO_NO_IOSTREAM)
687 template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
688 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
689 void (boost::system::error_code, std::size_t))
690 async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
691 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
693 return async_read(s, basic_streambuf_ref<Allocator>(b),
694 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
697 template <typename AsyncReadStream, typename Allocator,
698 typename CompletionCondition, typename ReadHandler>
699 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
700 void (boost::system::error_code, std::size_t))
701 async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
702 CompletionCondition completion_condition,
703 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
705 return async_read(s, basic_streambuf_ref<Allocator>(b),
706 completion_condition, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
709 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
710 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
715 #include <boost/asio/detail/pop_options.hpp>
717 #endif // BOOST_ASIO_IMPL_READ_HPP