File indexing completed on 2025-01-18 09:28:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IMPL_READ_AT_HPP
0012 #define BOOST_ASIO_IMPL_READ_AT_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <algorithm>
0019 #include <boost/asio/associator.hpp>
0020 #include <boost/asio/buffer.hpp>
0021 #include <boost/asio/detail/array_fwd.hpp>
0022 #include <boost/asio/detail/base_from_cancellation_state.hpp>
0023 #include <boost/asio/detail/base_from_completion_cond.hpp>
0024 #include <boost/asio/detail/bind_handler.hpp>
0025 #include <boost/asio/detail/consuming_buffers.hpp>
0026 #include <boost/asio/detail/dependent_type.hpp>
0027 #include <boost/asio/detail/handler_cont_helpers.hpp>
0028 #include <boost/asio/detail/handler_tracking.hpp>
0029 #include <boost/asio/detail/handler_type_requirements.hpp>
0030 #include <boost/asio/detail/non_const_lvalue.hpp>
0031 #include <boost/asio/detail/throw_error.hpp>
0032 #include <boost/asio/error.hpp>
0033
0034 #include <boost/asio/detail/push_options.hpp>
0035
0036 namespace boost {
0037 namespace asio {
0038
0039 namespace detail
0040 {
0041 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
0042 typename MutableBufferIterator, typename CompletionCondition>
0043 std::size_t read_at_buffer_sequence(SyncRandomAccessReadDevice& d,
0044 uint64_t offset, const MutableBufferSequence& buffers,
0045 const MutableBufferIterator&, CompletionCondition completion_condition,
0046 boost::system::error_code& ec)
0047 {
0048 ec = boost::system::error_code();
0049 boost::asio::detail::consuming_buffers<mutable_buffer,
0050 MutableBufferSequence, MutableBufferIterator> tmp(buffers);
0051 while (!tmp.empty())
0052 {
0053 if (std::size_t max_size = detail::adapt_completion_condition_result(
0054 completion_condition(ec, tmp.total_consumed())))
0055 {
0056 tmp.consume(d.read_some_at(offset + tmp.total_consumed(),
0057 tmp.prepare(max_size), ec));
0058 }
0059 else
0060 break;
0061 }
0062 return tmp.total_consumed();
0063 }
0064 }
0065
0066 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
0067 typename CompletionCondition>
0068 std::size_t read_at(SyncRandomAccessReadDevice& d,
0069 uint64_t offset, const MutableBufferSequence& buffers,
0070 CompletionCondition completion_condition, boost::system::error_code& ec)
0071 {
0072 return detail::read_at_buffer_sequence(d, offset, buffers,
0073 boost::asio::buffer_sequence_begin(buffers),
0074 static_cast<CompletionCondition&&>(completion_condition), ec);
0075 }
0076
0077 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
0078 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0079 uint64_t offset, const MutableBufferSequence& buffers)
0080 {
0081 boost::system::error_code ec;
0082 std::size_t bytes_transferred = read_at(
0083 d, offset, buffers, transfer_all(), ec);
0084 boost::asio::detail::throw_error(ec, "read_at");
0085 return bytes_transferred;
0086 }
0087
0088 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
0089 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0090 uint64_t offset, const MutableBufferSequence& buffers,
0091 boost::system::error_code& ec)
0092 {
0093 return read_at(d, offset, buffers, transfer_all(), ec);
0094 }
0095
0096 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
0097 typename CompletionCondition>
0098 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0099 uint64_t offset, const MutableBufferSequence& buffers,
0100 CompletionCondition completion_condition)
0101 {
0102 boost::system::error_code ec;
0103 std::size_t bytes_transferred = read_at(d, offset, buffers,
0104 static_cast<CompletionCondition&&>(completion_condition), ec);
0105 boost::asio::detail::throw_error(ec, "read_at");
0106 return bytes_transferred;
0107 }
0108
0109 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0110 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0111
0112 template <typename SyncRandomAccessReadDevice, typename Allocator,
0113 typename CompletionCondition>
0114 std::size_t read_at(SyncRandomAccessReadDevice& d,
0115 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
0116 CompletionCondition completion_condition, boost::system::error_code& ec)
0117 {
0118 ec = boost::system::error_code();
0119 std::size_t total_transferred = 0;
0120 std::size_t max_size = detail::adapt_completion_condition_result(
0121 completion_condition(ec, total_transferred));
0122 std::size_t bytes_available = read_size_helper(b, max_size);
0123 while (bytes_available > 0)
0124 {
0125 std::size_t bytes_transferred = d.read_some_at(
0126 offset + total_transferred, b.prepare(bytes_available), ec);
0127 b.commit(bytes_transferred);
0128 total_transferred += bytes_transferred;
0129 max_size = detail::adapt_completion_condition_result(
0130 completion_condition(ec, total_transferred));
0131 bytes_available = read_size_helper(b, max_size);
0132 }
0133 return total_transferred;
0134 }
0135
0136 template <typename SyncRandomAccessReadDevice, typename Allocator>
0137 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0138 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
0139 {
0140 boost::system::error_code ec;
0141 std::size_t bytes_transferred = read_at(
0142 d, offset, b, transfer_all(), ec);
0143 boost::asio::detail::throw_error(ec, "read_at");
0144 return bytes_transferred;
0145 }
0146
0147 template <typename SyncRandomAccessReadDevice, typename Allocator>
0148 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0149 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
0150 boost::system::error_code& ec)
0151 {
0152 return read_at(d, offset, b, transfer_all(), ec);
0153 }
0154
0155 template <typename SyncRandomAccessReadDevice, typename Allocator,
0156 typename CompletionCondition>
0157 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
0158 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
0159 CompletionCondition completion_condition)
0160 {
0161 boost::system::error_code ec;
0162 std::size_t bytes_transferred = read_at(d, offset, b,
0163 static_cast<CompletionCondition&&>(completion_condition), ec);
0164 boost::asio::detail::throw_error(ec, "read_at");
0165 return bytes_transferred;
0166 }
0167
0168 #endif
0169 #endif
0170
0171 namespace detail
0172 {
0173 template <typename AsyncRandomAccessReadDevice,
0174 typename MutableBufferSequence, typename MutableBufferIterator,
0175 typename CompletionCondition, typename ReadHandler>
0176 class read_at_op
0177 : public base_from_cancellation_state<ReadHandler>,
0178 base_from_completion_cond<CompletionCondition>
0179 {
0180 public:
0181 read_at_op(AsyncRandomAccessReadDevice& device,
0182 uint64_t offset, const MutableBufferSequence& buffers,
0183 CompletionCondition& completion_condition, ReadHandler& handler)
0184 : base_from_cancellation_state<ReadHandler>(
0185 handler, enable_partial_cancellation()),
0186 base_from_completion_cond<CompletionCondition>(completion_condition),
0187 device_(device),
0188 offset_(offset),
0189 buffers_(buffers),
0190 start_(0),
0191 handler_(static_cast<ReadHandler&&>(handler))
0192 {
0193 }
0194
0195 read_at_op(const read_at_op& other)
0196 : base_from_cancellation_state<ReadHandler>(other),
0197 base_from_completion_cond<CompletionCondition>(other),
0198 device_(other.device_),
0199 offset_(other.offset_),
0200 buffers_(other.buffers_),
0201 start_(other.start_),
0202 handler_(other.handler_)
0203 {
0204 }
0205
0206 read_at_op(read_at_op&& other)
0207 : base_from_cancellation_state<ReadHandler>(
0208 static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),
0209 base_from_completion_cond<CompletionCondition>(
0210 static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),
0211 device_(other.device_),
0212 offset_(other.offset_),
0213 buffers_(static_cast<buffers_type&&>(other.buffers_)),
0214 start_(other.start_),
0215 handler_(static_cast<ReadHandler&&>(other.handler_))
0216 {
0217 }
0218
0219 void operator()(boost::system::error_code ec,
0220 std::size_t bytes_transferred, int start = 0)
0221 {
0222 std::size_t max_size;
0223 switch (start_ = start)
0224 {
0225 case 1:
0226 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0227 for (;;)
0228 {
0229 {
0230 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));
0231 device_.async_read_some_at(
0232 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
0233 static_cast<read_at_op&&>(*this));
0234 }
0235 return; default:
0236 buffers_.consume(bytes_transferred);
0237 if ((!ec && bytes_transferred == 0) || buffers_.empty())
0238 break;
0239 max_size = this->check_for_completion(ec, buffers_.total_consumed());
0240 if (max_size == 0)
0241 break;
0242 if (this->cancelled() != cancellation_type::none)
0243 {
0244 ec = boost::asio::error::operation_aborted;
0245 break;
0246 }
0247 }
0248
0249 static_cast<ReadHandler&&>(handler_)(
0250 static_cast<const boost::system::error_code&>(ec),
0251 static_cast<const std::size_t&>(buffers_.total_consumed()));
0252 }
0253 }
0254
0255
0256 typedef boost::asio::detail::consuming_buffers<mutable_buffer,
0257 MutableBufferSequence, MutableBufferIterator> buffers_type;
0258
0259 AsyncRandomAccessReadDevice& device_;
0260 uint64_t offset_;
0261 buffers_type buffers_;
0262 int start_;
0263 ReadHandler handler_;
0264 };
0265
0266 template <typename AsyncRandomAccessReadDevice,
0267 typename MutableBufferSequence, typename MutableBufferIterator,
0268 typename CompletionCondition, typename ReadHandler>
0269 inline bool asio_handler_is_continuation(
0270 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
0271 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
0272 {
0273 return this_handler->start_ == 0 ? true
0274 : boost_asio_handler_cont_helpers::is_continuation(
0275 this_handler->handler_);
0276 }
0277
0278 template <typename AsyncRandomAccessReadDevice,
0279 typename MutableBufferSequence, typename MutableBufferIterator,
0280 typename CompletionCondition, typename ReadHandler>
0281 inline void start_read_at_op(AsyncRandomAccessReadDevice& d,
0282 uint64_t offset, const MutableBufferSequence& buffers,
0283 const MutableBufferIterator&, CompletionCondition& completion_condition,
0284 ReadHandler& handler)
0285 {
0286 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
0287 MutableBufferIterator, CompletionCondition, ReadHandler>(
0288 d, offset, buffers, completion_condition, handler)(
0289 boost::system::error_code(), 0, 1);
0290 }
0291
0292 template <typename AsyncRandomAccessReadDevice>
0293 class initiate_async_read_at
0294 {
0295 public:
0296 typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
0297
0298 explicit initiate_async_read_at(AsyncRandomAccessReadDevice& device)
0299 : device_(device)
0300 {
0301 }
0302
0303 executor_type get_executor() const noexcept
0304 {
0305 return device_.get_executor();
0306 }
0307
0308 template <typename ReadHandler, typename MutableBufferSequence,
0309 typename CompletionCondition>
0310 void operator()(ReadHandler&& handler,
0311 uint64_t offset, const MutableBufferSequence& buffers,
0312 CompletionCondition&& completion_cond) const
0313 {
0314
0315
0316 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
0317
0318 non_const_lvalue<ReadHandler> handler2(handler);
0319 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0320 start_read_at_op(device_, offset, buffers,
0321 boost::asio::buffer_sequence_begin(buffers),
0322 completion_cond2.value, handler2.value);
0323 }
0324
0325 private:
0326 AsyncRandomAccessReadDevice& device_;
0327 };
0328 }
0329
0330 #if !defined(GENERATING_DOCUMENTATION)
0331
0332 template <template <typename, typename> class Associator,
0333 typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
0334 typename MutableBufferIterator, typename CompletionCondition,
0335 typename ReadHandler, typename DefaultCandidate>
0336 struct associator<Associator,
0337 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
0338 MutableBufferIterator, CompletionCondition, ReadHandler>,
0339 DefaultCandidate>
0340 : Associator<ReadHandler, DefaultCandidate>
0341 {
0342 static typename Associator<ReadHandler, DefaultCandidate>::type get(
0343 const detail::read_at_op<AsyncRandomAccessReadDevice,
0344 MutableBufferSequence, MutableBufferIterator,
0345 CompletionCondition, ReadHandler>& h) noexcept
0346 {
0347 return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
0348 }
0349
0350 static auto get(
0351 const detail::read_at_op<AsyncRandomAccessReadDevice,
0352 MutableBufferSequence, MutableBufferIterator,
0353 CompletionCondition, ReadHandler>& h,
0354 const DefaultCandidate& c) noexcept
0355 -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))
0356 {
0357 return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
0358 }
0359 };
0360
0361 #endif
0362
0363 template <typename AsyncRandomAccessReadDevice,
0364 typename MutableBufferSequence, typename CompletionCondition,
0365 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0366 std::size_t)) ReadToken>
0367 inline auto async_read_at(AsyncRandomAccessReadDevice& d,
0368 uint64_t offset, const MutableBufferSequence& buffers,
0369 CompletionCondition completion_condition, ReadToken&& token)
0370 -> decltype(
0371 async_initiate<ReadToken,
0372 void (boost::system::error_code, std::size_t)>(
0373 declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),
0374 token, offset, buffers,
0375 static_cast<CompletionCondition&&>(completion_condition)))
0376 {
0377 return async_initiate<ReadToken,
0378 void (boost::system::error_code, std::size_t)>(
0379 detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),
0380 token, offset, buffers,
0381 static_cast<CompletionCondition&&>(completion_condition));
0382 }
0383
0384 template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
0385 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0386 std::size_t)) ReadToken>
0387 inline auto async_read_at(AsyncRandomAccessReadDevice& d,
0388 uint64_t offset, const MutableBufferSequence& buffers, ReadToken&& token)
0389 -> decltype(
0390 async_initiate<ReadToken,
0391 void (boost::system::error_code, std::size_t)>(
0392 declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),
0393 token, offset, buffers, transfer_all()))
0394 {
0395 return async_initiate<ReadToken,
0396 void (boost::system::error_code, std::size_t)>(
0397 detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),
0398 token, offset, buffers, transfer_all());
0399 }
0400
0401 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
0402 #if !defined(BOOST_ASIO_NO_IOSTREAM)
0403
0404 namespace detail
0405 {
0406 template <typename AsyncRandomAccessReadDevice, typename Allocator,
0407 typename CompletionCondition, typename ReadHandler>
0408 class read_at_streambuf_op
0409 : public base_from_cancellation_state<ReadHandler>,
0410 base_from_completion_cond<CompletionCondition>
0411 {
0412 public:
0413 read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
0414 uint64_t offset, basic_streambuf<Allocator>& streambuf,
0415 CompletionCondition& completion_condition, ReadHandler& handler)
0416 : base_from_cancellation_state<ReadHandler>(
0417 handler, enable_partial_cancellation()),
0418 base_from_completion_cond<CompletionCondition>(completion_condition),
0419 device_(device),
0420 offset_(offset),
0421 streambuf_(streambuf),
0422 start_(0),
0423 total_transferred_(0),
0424 handler_(static_cast<ReadHandler&&>(handler))
0425 {
0426 }
0427
0428 read_at_streambuf_op(const read_at_streambuf_op& other)
0429 : base_from_cancellation_state<ReadHandler>(other),
0430 base_from_completion_cond<CompletionCondition>(other),
0431 device_(other.device_),
0432 offset_(other.offset_),
0433 streambuf_(other.streambuf_),
0434 start_(other.start_),
0435 total_transferred_(other.total_transferred_),
0436 handler_(other.handler_)
0437 {
0438 }
0439
0440 read_at_streambuf_op(read_at_streambuf_op&& other)
0441 : base_from_cancellation_state<ReadHandler>(
0442 static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),
0443 base_from_completion_cond<CompletionCondition>(
0444 static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),
0445 device_(other.device_),
0446 offset_(other.offset_),
0447 streambuf_(other.streambuf_),
0448 start_(other.start_),
0449 total_transferred_(other.total_transferred_),
0450 handler_(static_cast<ReadHandler&&>(other.handler_))
0451 {
0452 }
0453
0454 void operator()(boost::system::error_code ec,
0455 std::size_t bytes_transferred, int start = 0)
0456 {
0457 std::size_t max_size, bytes_available;
0458 switch (start_ = start)
0459 {
0460 case 1:
0461 max_size = this->check_for_completion(ec, total_transferred_);
0462 bytes_available = read_size_helper(streambuf_, max_size);
0463 for (;;)
0464 {
0465 {
0466 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));
0467 device_.async_read_some_at(offset_ + total_transferred_,
0468 streambuf_.prepare(bytes_available),
0469 static_cast<read_at_streambuf_op&&>(*this));
0470 }
0471 return; default:
0472 total_transferred_ += bytes_transferred;
0473 streambuf_.commit(bytes_transferred);
0474 max_size = this->check_for_completion(ec, total_transferred_);
0475 bytes_available = read_size_helper(streambuf_, max_size);
0476 if ((!ec && bytes_transferred == 0) || bytes_available == 0)
0477 break;
0478 if (this->cancelled() != cancellation_type::none)
0479 {
0480 ec = boost::asio::error::operation_aborted;
0481 break;
0482 }
0483 }
0484
0485 static_cast<ReadHandler&&>(handler_)(
0486 static_cast<const boost::system::error_code&>(ec),
0487 static_cast<const std::size_t&>(total_transferred_));
0488 }
0489 }
0490
0491
0492 AsyncRandomAccessReadDevice& device_;
0493 uint64_t offset_;
0494 boost::asio::basic_streambuf<Allocator>& streambuf_;
0495 int start_;
0496 std::size_t total_transferred_;
0497 ReadHandler handler_;
0498 };
0499
0500 template <typename AsyncRandomAccessReadDevice, typename Allocator,
0501 typename CompletionCondition, typename ReadHandler>
0502 inline bool asio_handler_is_continuation(
0503 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
0504 CompletionCondition, ReadHandler>* this_handler)
0505 {
0506 return this_handler->start_ == 0 ? true
0507 : boost_asio_handler_cont_helpers::is_continuation(
0508 this_handler->handler_);
0509 }
0510
0511 template <typename AsyncRandomAccessReadDevice>
0512 class initiate_async_read_at_streambuf
0513 {
0514 public:
0515 typedef typename AsyncRandomAccessReadDevice::executor_type executor_type;
0516
0517 explicit initiate_async_read_at_streambuf(
0518 AsyncRandomAccessReadDevice& device)
0519 : device_(device)
0520 {
0521 }
0522
0523 executor_type get_executor() const noexcept
0524 {
0525 return device_.get_executor();
0526 }
0527
0528 template <typename ReadHandler,
0529 typename Allocator, typename CompletionCondition>
0530 void operator()(ReadHandler&& handler,
0531 uint64_t offset, basic_streambuf<Allocator>* b,
0532 CompletionCondition&& completion_cond) const
0533 {
0534
0535
0536 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
0537
0538 non_const_lvalue<ReadHandler> handler2(handler);
0539 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
0540 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
0541 CompletionCondition, decay_t<ReadHandler>>(
0542 device_, offset, *b, completion_cond2.value, handler2.value)(
0543 boost::system::error_code(), 0, 1);
0544 }
0545
0546 private:
0547 AsyncRandomAccessReadDevice& device_;
0548 };
0549 }
0550
0551 #if !defined(GENERATING_DOCUMENTATION)
0552
0553 template <template <typename, typename> class Associator,
0554 typename AsyncRandomAccessReadDevice, typename Executor,
0555 typename CompletionCondition, typename ReadHandler,
0556 typename DefaultCandidate>
0557 struct associator<Associator,
0558 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
0559 Executor, CompletionCondition, ReadHandler>,
0560 DefaultCandidate>
0561 : Associator<ReadHandler, DefaultCandidate>
0562 {
0563 static typename Associator<ReadHandler, DefaultCandidate>::type get(
0564 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
0565 Executor, CompletionCondition, ReadHandler>& h) noexcept
0566 {
0567 return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);
0568 }
0569
0570 static auto get(
0571 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
0572 Executor, CompletionCondition, ReadHandler>& h,
0573 const DefaultCandidate& c) noexcept
0574 -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))
0575 {
0576 return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);
0577 }
0578 };
0579
0580 #endif
0581
0582 template <typename AsyncRandomAccessReadDevice,
0583 typename Allocator, typename CompletionCondition,
0584 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0585 std::size_t)) ReadToken>
0586 inline auto async_read_at(AsyncRandomAccessReadDevice& d,
0587 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
0588 CompletionCondition completion_condition, ReadToken&& token)
0589 -> decltype(
0590 async_initiate<ReadToken,
0591 void (boost::system::error_code, std::size_t)>(
0592 declval<detail::initiate_async_read_at_streambuf<
0593 AsyncRandomAccessReadDevice>>(),
0594 token, offset, &b,
0595 static_cast<CompletionCondition&&>(completion_condition)))
0596 {
0597 return async_initiate<ReadToken,
0598 void (boost::system::error_code, std::size_t)>(
0599 detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
0600 token, offset, &b,
0601 static_cast<CompletionCondition&&>(completion_condition));
0602 }
0603
0604 template <typename AsyncRandomAccessReadDevice, typename Allocator,
0605 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0606 std::size_t)) ReadToken>
0607 inline auto async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
0608 boost::asio::basic_streambuf<Allocator>& b, ReadToken&& token)
0609 -> decltype(
0610 async_initiate<ReadToken,
0611 void (boost::system::error_code, std::size_t)>(
0612 declval<detail::initiate_async_read_at_streambuf<
0613 AsyncRandomAccessReadDevice>>(),
0614 token, offset, &b, transfer_all()))
0615 {
0616 return async_initiate<ReadToken,
0617 void (boost::system::error_code, std::size_t)>(
0618 detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),
0619 token, offset, &b, transfer_all());
0620 }
0621
0622 #endif
0623 #endif
0624
0625 }
0626 }
0627
0628 #include <boost/asio/detail/pop_options.hpp>
0629
0630 #endif