5 // Copyright (c) 2003-2019 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_AT_HPP
12 #define BOOST_ASIO_IMPL_READ_AT_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/non_const_lvalue.hpp>
33 #include <boost/asio/detail/throw_error.hpp>
34 #include <boost/asio/error.hpp>
36 #include <boost/asio/detail/push_options.hpp>
43 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
44 typename MutableBufferIterator, typename CompletionCondition>
45 std::size_t read_at_buffer_sequence(SyncRandomAccessReadDevice& d,
46 uint64_t offset, const MutableBufferSequence& buffers,
47 const MutableBufferIterator&, CompletionCondition completion_condition,
48 boost::system::error_code& ec)
50 ec = boost::system::error_code();
51 boost::asio::detail::consuming_buffers<mutable_buffer,
52 MutableBufferSequence, MutableBufferIterator> tmp(buffers);
55 if (std::size_t max_size = detail::adapt_completion_condition_result(
56 completion_condition(ec, tmp.total_consumed())))
58 tmp.consume(d.read_some_at(offset + tmp.total_consumed(),
59 tmp.prepare(max_size), ec));
64 return tmp.total_consumed();;
68 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
69 typename CompletionCondition>
70 std::size_t read_at(SyncRandomAccessReadDevice& d,
71 uint64_t offset, const MutableBufferSequence& buffers,
72 CompletionCondition completion_condition, boost::system::error_code& ec)
74 return detail::read_at_buffer_sequence(d, offset, buffers,
75 boost::asio::buffer_sequence_begin(buffers),
76 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
79 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
80 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
81 uint64_t offset, const MutableBufferSequence& buffers)
83 boost::system::error_code ec;
84 std::size_t bytes_transferred = read_at(
85 d, offset, buffers, transfer_all(), ec);
86 boost::asio::detail::throw_error(ec, "read_at");
87 return bytes_transferred;
90 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
91 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
92 uint64_t offset, const MutableBufferSequence& buffers,
93 boost::system::error_code& ec)
95 return read_at(d, offset, buffers, transfer_all(), ec);
98 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
99 typename CompletionCondition>
100 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
101 uint64_t offset, const MutableBufferSequence& buffers,
102 CompletionCondition completion_condition)
104 boost::system::error_code ec;
105 std::size_t bytes_transferred = read_at(d, offset, buffers,
106 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
107 boost::asio::detail::throw_error(ec, "read_at");
108 return bytes_transferred;
111 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
112 #if !defined(BOOST_ASIO_NO_IOSTREAM)
114 template <typename SyncRandomAccessReadDevice, typename Allocator,
115 typename CompletionCondition>
116 std::size_t read_at(SyncRandomAccessReadDevice& d,
117 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
118 CompletionCondition completion_condition, boost::system::error_code& ec)
120 ec = boost::system::error_code();
121 std::size_t total_transferred = 0;
122 std::size_t max_size = detail::adapt_completion_condition_result(
123 completion_condition(ec, total_transferred));
124 std::size_t bytes_available = read_size_helper(b, max_size);
125 while (bytes_available > 0)
127 std::size_t bytes_transferred = d.read_some_at(
128 offset + total_transferred, b.prepare(bytes_available), ec);
129 b.commit(bytes_transferred);
130 total_transferred += bytes_transferred;
131 max_size = detail::adapt_completion_condition_result(
132 completion_condition(ec, total_transferred));
133 bytes_available = read_size_helper(b, max_size);
135 return total_transferred;
138 template <typename SyncRandomAccessReadDevice, typename Allocator>
139 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
140 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
142 boost::system::error_code ec;
143 std::size_t bytes_transferred = read_at(
144 d, offset, b, transfer_all(), ec);
145 boost::asio::detail::throw_error(ec, "read_at");
146 return bytes_transferred;
149 template <typename SyncRandomAccessReadDevice, typename Allocator>
150 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
151 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
152 boost::system::error_code& ec)
154 return read_at(d, offset, b, transfer_all(), ec);
157 template <typename SyncRandomAccessReadDevice, typename Allocator,
158 typename CompletionCondition>
159 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
160 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
161 CompletionCondition completion_condition)
163 boost::system::error_code ec;
164 std::size_t bytes_transferred = read_at(d, offset, b,
165 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
166 boost::asio::detail::throw_error(ec, "read_at");
167 return bytes_transferred;
170 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
171 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
175 template <typename AsyncRandomAccessReadDevice,
176 typename MutableBufferSequence, typename MutableBufferIterator,
177 typename CompletionCondition, typename ReadHandler>
179 : detail::base_from_completion_cond<CompletionCondition>
182 read_at_op(AsyncRandomAccessReadDevice& device,
183 uint64_t offset, const MutableBufferSequence& buffers,
184 CompletionCondition& completion_condition, ReadHandler& handler)
185 : detail::base_from_completion_cond<
186 CompletionCondition>(completion_condition),
191 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
195 #if defined(BOOST_ASIO_HAS_MOVE)
196 read_at_op(const read_at_op& other)
197 : detail::base_from_completion_cond<CompletionCondition>(other),
198 device_(other.device_),
199 offset_(other.offset_),
200 buffers_(other.buffers_),
201 start_(other.start_),
202 handler_(other.handler_)
206 read_at_op(read_at_op&& other)
207 : detail::base_from_completion_cond<CompletionCondition>(
208 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
209 CompletionCondition>)(other)),
210 device_(other.device_),
211 offset_(other.offset_),
212 buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
213 start_(other.start_),
214 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
217 #endif // defined(BOOST_ASIO_HAS_MOVE)
219 void operator()(const boost::system::error_code& ec,
220 std::size_t bytes_transferred, int start = 0)
222 std::size_t max_size;
223 switch (start_ = start)
226 max_size = this->check_for_completion(ec, buffers_.total_consumed());
229 device_.async_read_some_at(
230 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
231 BOOST_ASIO_MOVE_CAST(read_at_op)(*this));
233 buffers_.consume(bytes_transferred);
234 if ((!ec && bytes_transferred == 0) || buffers_.empty())
236 max_size = this->check_for_completion(ec, buffers_.total_consumed());
237 } while (max_size > 0);
239 handler_(ec, buffers_.total_consumed());
244 typedef boost::asio::detail::consuming_buffers<mutable_buffer,
245 MutableBufferSequence, MutableBufferIterator> buffers_type;
247 AsyncRandomAccessReadDevice& device_;
249 buffers_type buffers_;
251 ReadHandler handler_;
254 template <typename AsyncRandomAccessReadDevice,
255 typename MutableBufferSequence, typename MutableBufferIterator,
256 typename CompletionCondition, typename ReadHandler>
257 inline void* asio_handler_allocate(std::size_t size,
258 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
259 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
261 return boost_asio_handler_alloc_helpers::allocate(
262 size, this_handler->handler_);
265 template <typename AsyncRandomAccessReadDevice,
266 typename MutableBufferSequence, typename MutableBufferIterator,
267 typename CompletionCondition, typename ReadHandler>
268 inline void asio_handler_deallocate(void* pointer, std::size_t size,
269 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
270 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
272 boost_asio_handler_alloc_helpers::deallocate(
273 pointer, size, this_handler->handler_);
276 template <typename AsyncRandomAccessReadDevice,
277 typename MutableBufferSequence, typename MutableBufferIterator,
278 typename CompletionCondition, typename ReadHandler>
279 inline bool asio_handler_is_continuation(
280 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
281 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
283 return this_handler->start_ == 0 ? true
284 : boost_asio_handler_cont_helpers::is_continuation(
285 this_handler->handler_);
288 template <typename Function, typename AsyncRandomAccessReadDevice,
289 typename MutableBufferSequence, typename MutableBufferIterator,
290 typename CompletionCondition, typename ReadHandler>
291 inline void asio_handler_invoke(Function& function,
292 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
293 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
295 boost_asio_handler_invoke_helpers::invoke(
296 function, this_handler->handler_);
299 template <typename Function, typename AsyncRandomAccessReadDevice,
300 typename MutableBufferSequence, typename MutableBufferIterator,
301 typename CompletionCondition, typename ReadHandler>
302 inline void asio_handler_invoke(const Function& function,
303 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
304 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
306 boost_asio_handler_invoke_helpers::invoke(
307 function, this_handler->handler_);
310 template <typename AsyncRandomAccessReadDevice,
311 typename MutableBufferSequence, typename MutableBufferIterator,
312 typename CompletionCondition, typename ReadHandler>
313 inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d,
314 uint64_t offset, const MutableBufferSequence& buffers,
315 const MutableBufferIterator&, CompletionCondition& completion_condition,
316 ReadHandler& handler)
318 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
319 MutableBufferIterator, CompletionCondition, ReadHandler>(
320 d, offset, buffers, completion_condition, handler)(
321 boost::system::error_code(), 0, 1);
324 template <typename AsyncRandomAccessReadDevice>
325 class initiate_async_read_at_buffer_sequence
328 typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
330 explicit initiate_async_read_at_buffer_sequence(
331 AsyncRandomAccessReadDevice& device)
336 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
338 return device_.get_executor();
341 template <typename ReadHandler, typename MutableBufferSequence,
342 typename CompletionCondition>
343 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
344 uint64_t offset, const MutableBufferSequence& buffers,
345 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
347 // If you get an error on the following line it means that your handler
348 // does not meet the documented type requirements for a ReadHandler.
349 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
351 non_const_lvalue<ReadHandler> handler2(handler);
352 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
353 start_read_at_buffer_sequence_op(device_, offset, buffers,
354 boost::asio::buffer_sequence_begin(buffers),
355 completion_cond2.value, handler2.value);
359 AsyncRandomAccessReadDevice& device_;
361 } // namespace detail
363 #if !defined(GENERATING_DOCUMENTATION)
365 template <typename AsyncRandomAccessReadDevice,
366 typename MutableBufferSequence, typename MutableBufferIterator,
367 typename CompletionCondition, typename ReadHandler, typename Allocator>
368 struct associated_allocator<
369 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
370 MutableBufferIterator, CompletionCondition, ReadHandler>,
373 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
376 const detail::read_at_op<AsyncRandomAccessReadDevice,
377 MutableBufferSequence, MutableBufferIterator,
378 CompletionCondition, ReadHandler>& h,
379 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
381 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
385 template <typename AsyncRandomAccessReadDevice,
386 typename MutableBufferSequence, typename MutableBufferIterator,
387 typename CompletionCondition, typename ReadHandler, typename Executor>
388 struct associated_executor<
389 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
390 MutableBufferIterator, CompletionCondition, ReadHandler>,
393 typedef typename associated_executor<ReadHandler, Executor>::type type;
396 const detail::read_at_op<AsyncRandomAccessReadDevice,
397 MutableBufferSequence, MutableBufferIterator,
398 CompletionCondition, ReadHandler>& h,
399 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
401 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
405 #endif // !defined(GENERATING_DOCUMENTATION)
407 template <typename AsyncRandomAccessReadDevice,
408 typename MutableBufferSequence, typename CompletionCondition,
409 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
410 std::size_t)) ReadHandler>
411 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
412 void (boost::system::error_code, std::size_t))
413 async_read_at(AsyncRandomAccessReadDevice& d,
414 uint64_t offset, const MutableBufferSequence& buffers,
415 CompletionCondition completion_condition,
416 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
418 return async_initiate<ReadHandler,
419 void (boost::system::error_code, std::size_t)>(
420 detail::initiate_async_read_at_buffer_sequence<
421 AsyncRandomAccessReadDevice>(d),
422 handler, offset, buffers,
423 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
426 template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
427 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
428 std::size_t)) ReadHandler>
429 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
430 void (boost::system::error_code, std::size_t))
431 async_read_at(AsyncRandomAccessReadDevice& d,
432 uint64_t offset, const MutableBufferSequence& buffers,
433 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
435 return async_initiate<ReadHandler,
436 void (boost::system::error_code, std::size_t)>(
437 detail::initiate_async_read_at_buffer_sequence<
438 AsyncRandomAccessReadDevice>(d),
439 handler, offset, buffers, transfer_all());
442 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
443 #if !defined(BOOST_ASIO_NO_IOSTREAM)
447 template <typename AsyncRandomAccessReadDevice, typename Allocator,
448 typename CompletionCondition, typename ReadHandler>
449 class read_at_streambuf_op
450 : detail::base_from_completion_cond<CompletionCondition>
453 read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
454 uint64_t offset, basic_streambuf<Allocator>& streambuf,
455 CompletionCondition& completion_condition, ReadHandler& handler)
456 : detail::base_from_completion_cond<
457 CompletionCondition>(completion_condition),
460 streambuf_(streambuf),
462 total_transferred_(0),
463 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
467 #if defined(BOOST_ASIO_HAS_MOVE)
468 read_at_streambuf_op(const read_at_streambuf_op& other)
469 : detail::base_from_completion_cond<CompletionCondition>(other),
470 device_(other.device_),
471 offset_(other.offset_),
472 streambuf_(other.streambuf_),
473 start_(other.start_),
474 total_transferred_(other.total_transferred_),
475 handler_(other.handler_)
479 read_at_streambuf_op(read_at_streambuf_op&& other)
480 : detail::base_from_completion_cond<CompletionCondition>(
481 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
482 CompletionCondition>)(other)),
483 device_(other.device_),
484 offset_(other.offset_),
485 streambuf_(other.streambuf_),
486 start_(other.start_),
487 total_transferred_(other.total_transferred_),
488 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
491 #endif // defined(BOOST_ASIO_HAS_MOVE)
493 void operator()(const boost::system::error_code& ec,
494 std::size_t bytes_transferred, int start = 0)
496 std::size_t max_size, bytes_available;
497 switch (start_ = start)
500 max_size = this->check_for_completion(ec, total_transferred_);
501 bytes_available = read_size_helper(streambuf_, max_size);
504 device_.async_read_some_at(offset_ + total_transferred_,
505 streambuf_.prepare(bytes_available),
506 BOOST_ASIO_MOVE_CAST(read_at_streambuf_op)(*this));
508 total_transferred_ += bytes_transferred;
509 streambuf_.commit(bytes_transferred);
510 max_size = this->check_for_completion(ec, total_transferred_);
511 bytes_available = read_size_helper(streambuf_, max_size);
512 if ((!ec && bytes_transferred == 0) || bytes_available == 0)
516 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
521 AsyncRandomAccessReadDevice& device_;
523 boost::asio::basic_streambuf<Allocator>& streambuf_;
525 std::size_t total_transferred_;
526 ReadHandler handler_;
529 template <typename AsyncRandomAccessReadDevice, typename Allocator,
530 typename CompletionCondition, typename ReadHandler>
531 inline void* asio_handler_allocate(std::size_t size,
532 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
533 CompletionCondition, ReadHandler>* this_handler)
535 return boost_asio_handler_alloc_helpers::allocate(
536 size, this_handler->handler_);
539 template <typename AsyncRandomAccessReadDevice, typename Allocator,
540 typename CompletionCondition, typename ReadHandler>
541 inline void asio_handler_deallocate(void* pointer, std::size_t size,
542 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
543 CompletionCondition, ReadHandler>* this_handler)
545 boost_asio_handler_alloc_helpers::deallocate(
546 pointer, size, this_handler->handler_);
549 template <typename AsyncRandomAccessReadDevice, typename Allocator,
550 typename CompletionCondition, typename ReadHandler>
551 inline bool asio_handler_is_continuation(
552 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
553 CompletionCondition, ReadHandler>* this_handler)
555 return this_handler->start_ == 0 ? true
556 : boost_asio_handler_cont_helpers::is_continuation(
557 this_handler->handler_);
560 template <typename Function, typename AsyncRandomAccessReadDevice,
561 typename Allocator, typename CompletionCondition, typename ReadHandler>
562 inline void asio_handler_invoke(Function& function,
563 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
564 CompletionCondition, ReadHandler>* this_handler)
566 boost_asio_handler_invoke_helpers::invoke(
567 function, this_handler->handler_);
570 template <typename Function, typename AsyncRandomAccessReadDevice,
571 typename Allocator, typename CompletionCondition, typename ReadHandler>
572 inline void asio_handler_invoke(const Function& function,
573 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
574 CompletionCondition, ReadHandler>* this_handler)
576 boost_asio_handler_invoke_helpers::invoke(
577 function, this_handler->handler_);
580 template <typename AsyncRandomAccessReadDevice>
581 class initiate_async_read_at_streambuf
584 typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
586 explicit initiate_async_read_at_streambuf(
587 AsyncRandomAccessReadDevice& device)
592 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
594 return device_.get_executor();
597 template <typename ReadHandler,
598 typename Allocator, typename CompletionCondition>
599 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
600 uint64_t offset, basic_streambuf<Allocator>* b,
601 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
603 // If you get an error on the following line it means that your handler
604 // does not meet the documented type requirements for a ReadHandler.
605 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
607 non_const_lvalue<ReadHandler> handler2(handler);
608 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
609 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
610 CompletionCondition, typename decay<ReadHandler>::type>(
611 device_, offset, *b, completion_cond2.value, handler2.value)(
612 boost::system::error_code(), 0, 1);
616 AsyncRandomAccessReadDevice& device_;
618 } // namespace detail
620 #if !defined(GENERATING_DOCUMENTATION)
622 template <typename AsyncRandomAccessReadDevice, typename Allocator,
623 typename CompletionCondition, typename ReadHandler, typename Allocator1>
624 struct associated_allocator<
625 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
626 Allocator, CompletionCondition, ReadHandler>,
629 typedef typename associated_allocator<ReadHandler, Allocator1>::type type;
632 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
633 Allocator, CompletionCondition, ReadHandler>& h,
634 const Allocator1& a = Allocator1()) BOOST_ASIO_NOEXCEPT
636 return associated_allocator<ReadHandler, Allocator1>::get(h.handler_, a);
640 template <typename AsyncRandomAccessReadDevice, typename Executor,
641 typename CompletionCondition, typename ReadHandler, typename Executor1>
642 struct associated_executor<
643 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
644 Executor, CompletionCondition, ReadHandler>,
647 typedef typename associated_executor<ReadHandler, Executor1>::type type;
650 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
651 Executor, CompletionCondition, ReadHandler>& h,
652 const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
654 return associated_executor<ReadHandler, Executor1>::get(h.handler_, ex);
658 #endif // !defined(GENERATING_DOCUMENTATION)
660 template <typename AsyncRandomAccessReadDevice,
661 typename Allocator, typename CompletionCondition,
662 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
663 std::size_t)) ReadHandler>
664 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
665 void (boost::system::error_code, std::size_t))
666 async_read_at(AsyncRandomAccessReadDevice& d,
667 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
668 CompletionCondition completion_condition,
669 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
671 return async_initiate<ReadHandler,
672 void (boost::system::error_code, std::size_t)>(
673 detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
675 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
678 template <typename AsyncRandomAccessReadDevice, typename Allocator,
679 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
680 std::size_t)) ReadHandler>
681 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
682 void (boost::system::error_code, std::size_t))
683 async_read_at(AsyncRandomAccessReadDevice& d,
684 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
685 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
687 return async_initiate<ReadHandler,
688 void (boost::system::error_code, std::size_t)>(
689 detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
690 handler, offset, &b, transfer_all());
693 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
694 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
699 #include <boost/asio/detail/pop_options.hpp>
701 #endif // BOOST_ASIO_IMPL_READ_AT_HPP