]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/read_at.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / impl / read_at.hpp
1 //
2 // impl/read_at.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_IMPL_READ_AT_HPP
12 #define BOOST_ASIO_IMPL_READ_AT_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <algorithm>
19 #include <boost/asio/associated_allocator.hpp>
20 #include <boost/asio/associated_executor.hpp>
21 #include <boost/asio/buffer.hpp>
22 #include <boost/asio/completion_condition.hpp>
23 #include <boost/asio/detail/array_fwd.hpp>
24 #include <boost/asio/detail/base_from_completion_cond.hpp>
25 #include <boost/asio/detail/bind_handler.hpp>
26 #include <boost/asio/detail/consuming_buffers.hpp>
27 #include <boost/asio/detail/dependent_type.hpp>
28 #include <boost/asio/detail/handler_alloc_helpers.hpp>
29 #include <boost/asio/detail/handler_cont_helpers.hpp>
30 #include <boost/asio/detail/handler_invoke_helpers.hpp>
31 #include <boost/asio/detail/handler_type_requirements.hpp>
32 #include <boost/asio/detail/throw_error.hpp>
33 #include <boost/asio/error.hpp>
34
35 #include <boost/asio/detail/push_options.hpp>
36
37 namespace boost {
38 namespace asio {
39
40 namespace detail
41 {
42 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
43 typename MutableBufferIterator, typename CompletionCondition>
44 std::size_t read_at_buffer_sequence(SyncRandomAccessReadDevice& d,
45 uint64_t offset, const MutableBufferSequence& buffers,
46 const MutableBufferIterator&, CompletionCondition completion_condition,
47 boost::system::error_code& ec)
48 {
49 ec = boost::system::error_code();
50 boost::asio::detail::consuming_buffers<mutable_buffer,
51 MutableBufferSequence, MutableBufferIterator> tmp(buffers);
52 while (!tmp.empty())
53 {
54 if (std::size_t max_size = detail::adapt_completion_condition_result(
55 completion_condition(ec, tmp.total_consumed())))
56 {
57 tmp.consume(d.read_some_at(offset + tmp.total_consumed(),
58 tmp.prepare(max_size), ec));
59 }
60 else
61 break;
62 }
63 return tmp.total_consumed();;
64 }
65 } // namespace detail
66
67 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
68 typename CompletionCondition>
69 std::size_t read_at(SyncRandomAccessReadDevice& d,
70 uint64_t offset, const MutableBufferSequence& buffers,
71 CompletionCondition completion_condition, boost::system::error_code& ec)
72 {
73 return detail::read_at_buffer_sequence(d, offset, buffers,
74 boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
75 }
76
77 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
78 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
79 uint64_t offset, const MutableBufferSequence& buffers)
80 {
81 boost::system::error_code ec;
82 std::size_t bytes_transferred = read_at(
83 d, offset, buffers, transfer_all(), ec);
84 boost::asio::detail::throw_error(ec, "read_at");
85 return bytes_transferred;
86 }
87
88 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
89 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
90 uint64_t offset, const MutableBufferSequence& buffers,
91 boost::system::error_code& ec)
92 {
93 return read_at(d, offset, buffers, transfer_all(), ec);
94 }
95
96 template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
97 typename CompletionCondition>
98 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
99 uint64_t offset, const MutableBufferSequence& buffers,
100 CompletionCondition completion_condition)
101 {
102 boost::system::error_code ec;
103 std::size_t bytes_transferred = read_at(
104 d, offset, buffers, completion_condition, ec);
105 boost::asio::detail::throw_error(ec, "read_at");
106 return bytes_transferred;
107 }
108
109 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
110 #if !defined(BOOST_ASIO_NO_IOSTREAM)
111
112 template <typename SyncRandomAccessReadDevice, typename Allocator,
113 typename CompletionCondition>
114 std::size_t read_at(SyncRandomAccessReadDevice& d,
115 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
116 CompletionCondition completion_condition, boost::system::error_code& ec)
117 {
118 ec = boost::system::error_code();
119 std::size_t total_transferred = 0;
120 std::size_t max_size = detail::adapt_completion_condition_result(
121 completion_condition(ec, total_transferred));
122 std::size_t bytes_available = read_size_helper(b, max_size);
123 while (bytes_available > 0)
124 {
125 std::size_t bytes_transferred = d.read_some_at(
126 offset + total_transferred, b.prepare(bytes_available), ec);
127 b.commit(bytes_transferred);
128 total_transferred += bytes_transferred;
129 max_size = detail::adapt_completion_condition_result(
130 completion_condition(ec, total_transferred));
131 bytes_available = read_size_helper(b, max_size);
132 }
133 return total_transferred;
134 }
135
136 template <typename SyncRandomAccessReadDevice, typename Allocator>
137 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
138 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
139 {
140 boost::system::error_code ec;
141 std::size_t bytes_transferred = read_at(
142 d, offset, b, transfer_all(), ec);
143 boost::asio::detail::throw_error(ec, "read_at");
144 return bytes_transferred;
145 }
146
147 template <typename SyncRandomAccessReadDevice, typename Allocator>
148 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
149 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
150 boost::system::error_code& ec)
151 {
152 return read_at(d, offset, b, transfer_all(), ec);
153 }
154
155 template <typename SyncRandomAccessReadDevice, typename Allocator,
156 typename CompletionCondition>
157 inline std::size_t read_at(SyncRandomAccessReadDevice& d,
158 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
159 CompletionCondition completion_condition)
160 {
161 boost::system::error_code ec;
162 std::size_t bytes_transferred = read_at(
163 d, offset, b, completion_condition, ec);
164 boost::asio::detail::throw_error(ec, "read_at");
165 return bytes_transferred;
166 }
167
168 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
169 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
170
171 namespace detail
172 {
173 template <typename AsyncRandomAccessReadDevice,
174 typename MutableBufferSequence, typename MutableBufferIterator,
175 typename CompletionCondition, typename ReadHandler>
176 class read_at_op
177 : detail::base_from_completion_cond<CompletionCondition>
178 {
179 public:
180 read_at_op(AsyncRandomAccessReadDevice& device,
181 uint64_t offset, const MutableBufferSequence& buffers,
182 CompletionCondition completion_condition, ReadHandler& handler)
183 : detail::base_from_completion_cond<
184 CompletionCondition>(completion_condition),
185 device_(device),
186 offset_(offset),
187 buffers_(buffers),
188 start_(0),
189 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
190 {
191 }
192
193 #if defined(BOOST_ASIO_HAS_MOVE)
194 read_at_op(const read_at_op& other)
195 : detail::base_from_completion_cond<CompletionCondition>(other),
196 device_(other.device_),
197 offset_(other.offset_),
198 buffers_(other.buffers_),
199 start_(other.start_),
200 handler_(other.handler_)
201 {
202 }
203
204 read_at_op(read_at_op&& other)
205 : detail::base_from_completion_cond<CompletionCondition>(other),
206 device_(other.device_),
207 offset_(other.offset_),
208 buffers_(other.buffers_),
209 start_(other.start_),
210 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
211 {
212 }
213 #endif // defined(BOOST_ASIO_HAS_MOVE)
214
215 void operator()(const boost::system::error_code& ec,
216 std::size_t bytes_transferred, int start = 0)
217 {
218 std::size_t max_size;
219 switch (start_ = start)
220 {
221 case 1:
222 max_size = this->check_for_completion(ec, buffers_.total_consumed());
223 do
224 {
225 device_.async_read_some_at(
226 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
227 BOOST_ASIO_MOVE_CAST(read_at_op)(*this));
228 return; default:
229 buffers_.consume(bytes_transferred);
230 if ((!ec && bytes_transferred == 0) || buffers_.empty())
231 break;
232 max_size = this->check_for_completion(ec, buffers_.total_consumed());
233 } while (max_size > 0);
234
235 handler_(ec, buffers_.total_consumed());
236 }
237 }
238
239 //private:
240 AsyncRandomAccessReadDevice& device_;
241 uint64_t offset_;
242 boost::asio::detail::consuming_buffers<mutable_buffer,
243 MutableBufferSequence, MutableBufferIterator> buffers_;
244 int start_;
245 ReadHandler handler_;
246 };
247
248 template <typename AsyncRandomAccessReadDevice,
249 typename MutableBufferSequence, typename MutableBufferIterator,
250 typename CompletionCondition, typename ReadHandler>
251 inline void* asio_handler_allocate(std::size_t size,
252 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
253 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
254 {
255 return boost_asio_handler_alloc_helpers::allocate(
256 size, this_handler->handler_);
257 }
258
259 template <typename AsyncRandomAccessReadDevice,
260 typename MutableBufferSequence, typename MutableBufferIterator,
261 typename CompletionCondition, typename ReadHandler>
262 inline void asio_handler_deallocate(void* pointer, std::size_t size,
263 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
264 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
265 {
266 boost_asio_handler_alloc_helpers::deallocate(
267 pointer, size, this_handler->handler_);
268 }
269
270 template <typename AsyncRandomAccessReadDevice,
271 typename MutableBufferSequence, typename MutableBufferIterator,
272 typename CompletionCondition, typename ReadHandler>
273 inline bool asio_handler_is_continuation(
274 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
275 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
276 {
277 return this_handler->start_ == 0 ? true
278 : boost_asio_handler_cont_helpers::is_continuation(
279 this_handler->handler_);
280 }
281
282 template <typename Function, typename AsyncRandomAccessReadDevice,
283 typename MutableBufferSequence, typename MutableBufferIterator,
284 typename CompletionCondition, typename ReadHandler>
285 inline void asio_handler_invoke(Function& function,
286 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
287 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
288 {
289 boost_asio_handler_invoke_helpers::invoke(
290 function, this_handler->handler_);
291 }
292
293 template <typename Function, typename AsyncRandomAccessReadDevice,
294 typename MutableBufferSequence, typename MutableBufferIterator,
295 typename CompletionCondition, typename ReadHandler>
296 inline void asio_handler_invoke(const Function& function,
297 read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
298 MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)
299 {
300 boost_asio_handler_invoke_helpers::invoke(
301 function, this_handler->handler_);
302 }
303
304 template <typename AsyncRandomAccessReadDevice,
305 typename MutableBufferSequence, typename MutableBufferIterator,
306 typename CompletionCondition, typename ReadHandler>
307 inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d,
308 uint64_t offset, const MutableBufferSequence& buffers,
309 const MutableBufferIterator&, CompletionCondition completion_condition,
310 ReadHandler& handler)
311 {
312 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
313 MutableBufferIterator, CompletionCondition, ReadHandler>(
314 d, offset, buffers, completion_condition, handler)(
315 boost::system::error_code(), 0, 1);
316 }
317 } // namespace detail
318
319 #if !defined(GENERATING_DOCUMENTATION)
320
321 template <typename AsyncRandomAccessReadDevice,
322 typename MutableBufferSequence, typename MutableBufferIterator,
323 typename CompletionCondition, typename ReadHandler, typename Allocator>
324 struct associated_allocator<
325 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
326 MutableBufferIterator, CompletionCondition, ReadHandler>,
327 Allocator>
328 {
329 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
330
331 static type get(
332 const detail::read_at_op<AsyncRandomAccessReadDevice,
333 MutableBufferSequence, MutableBufferIterator,
334 CompletionCondition, ReadHandler>& h,
335 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
336 {
337 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
338 }
339 };
340
341 template <typename AsyncRandomAccessReadDevice,
342 typename MutableBufferSequence, typename MutableBufferIterator,
343 typename CompletionCondition, typename ReadHandler, typename Executor>
344 struct associated_executor<
345 detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
346 MutableBufferIterator, CompletionCondition, ReadHandler>,
347 Executor>
348 {
349 typedef typename associated_executor<ReadHandler, Executor>::type type;
350
351 static type get(
352 const detail::read_at_op<AsyncRandomAccessReadDevice,
353 MutableBufferSequence, MutableBufferIterator,
354 CompletionCondition, ReadHandler>& h,
355 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
356 {
357 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
358 }
359 };
360
361 #endif // !defined(GENERATING_DOCUMENTATION)
362
363 template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
364 typename CompletionCondition, typename ReadHandler>
365 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
366 void (boost::system::error_code, std::size_t))
367 async_read_at(AsyncRandomAccessReadDevice& d,
368 uint64_t offset, const MutableBufferSequence& buffers,
369 CompletionCondition completion_condition,
370 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
371 {
372 // If you get an error on the following line it means that your handler does
373 // not meet the documented type requirements for a ReadHandler.
374 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
375
376 async_completion<ReadHandler,
377 void (boost::system::error_code, std::size_t)> init(handler);
378
379 detail::start_read_at_buffer_sequence_op(d, offset, buffers,
380 boost::asio::buffer_sequence_begin(buffers), completion_condition,
381 init.completion_handler);
382
383 return init.result.get();
384 }
385
386 template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
387 typename ReadHandler>
388 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
389 void (boost::system::error_code, std::size_t))
390 async_read_at(AsyncRandomAccessReadDevice& d,
391 uint64_t offset, const MutableBufferSequence& buffers,
392 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
393 {
394 // If you get an error on the following line it means that your handler does
395 // not meet the documented type requirements for a ReadHandler.
396 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
397
398 async_completion<ReadHandler,
399 void (boost::system::error_code, std::size_t)> init(handler);
400
401 detail::start_read_at_buffer_sequence_op(d, offset, buffers,
402 boost::asio::buffer_sequence_begin(buffers), transfer_all(),
403 init.completion_handler);
404
405 return init.result.get();
406 }
407
408 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
409 #if !defined(BOOST_ASIO_NO_IOSTREAM)
410
411 namespace detail
412 {
413 template <typename AsyncRandomAccessReadDevice, typename Allocator,
414 typename CompletionCondition, typename ReadHandler>
415 class read_at_streambuf_op
416 : detail::base_from_completion_cond<CompletionCondition>
417 {
418 public:
419 read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
420 uint64_t offset, basic_streambuf<Allocator>& streambuf,
421 CompletionCondition completion_condition, ReadHandler& handler)
422 : detail::base_from_completion_cond<
423 CompletionCondition>(completion_condition),
424 device_(device),
425 offset_(offset),
426 streambuf_(streambuf),
427 start_(0),
428 total_transferred_(0),
429 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
430 {
431 }
432
433 #if defined(BOOST_ASIO_HAS_MOVE)
434 read_at_streambuf_op(const read_at_streambuf_op& other)
435 : detail::base_from_completion_cond<CompletionCondition>(other),
436 device_(other.device_),
437 offset_(other.offset_),
438 streambuf_(other.streambuf_),
439 start_(other.start_),
440 total_transferred_(other.total_transferred_),
441 handler_(other.handler_)
442 {
443 }
444
445 read_at_streambuf_op(read_at_streambuf_op&& other)
446 : detail::base_from_completion_cond<CompletionCondition>(other),
447 device_(other.device_),
448 offset_(other.offset_),
449 streambuf_(other.streambuf_),
450 start_(other.start_),
451 total_transferred_(other.total_transferred_),
452 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
453 {
454 }
455 #endif // defined(BOOST_ASIO_HAS_MOVE)
456
457 void operator()(const boost::system::error_code& ec,
458 std::size_t bytes_transferred, int start = 0)
459 {
460 std::size_t max_size, bytes_available;
461 switch (start_ = start)
462 {
463 case 1:
464 max_size = this->check_for_completion(ec, total_transferred_);
465 bytes_available = read_size_helper(streambuf_, max_size);
466 for (;;)
467 {
468 device_.async_read_some_at(offset_ + total_transferred_,
469 streambuf_.prepare(bytes_available),
470 BOOST_ASIO_MOVE_CAST(read_at_streambuf_op)(*this));
471 return; default:
472 total_transferred_ += bytes_transferred;
473 streambuf_.commit(bytes_transferred);
474 max_size = this->check_for_completion(ec, total_transferred_);
475 bytes_available = read_size_helper(streambuf_, max_size);
476 if ((!ec && bytes_transferred == 0) || bytes_available == 0)
477 break;
478 }
479
480 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
481 }
482 }
483
484 //private:
485 AsyncRandomAccessReadDevice& device_;
486 uint64_t offset_;
487 boost::asio::basic_streambuf<Allocator>& streambuf_;
488 int start_;
489 std::size_t total_transferred_;
490 ReadHandler handler_;
491 };
492
493 template <typename AsyncRandomAccessReadDevice, typename Allocator,
494 typename CompletionCondition, typename ReadHandler>
495 inline void* asio_handler_allocate(std::size_t size,
496 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
497 CompletionCondition, ReadHandler>* this_handler)
498 {
499 return boost_asio_handler_alloc_helpers::allocate(
500 size, this_handler->handler_);
501 }
502
503 template <typename AsyncRandomAccessReadDevice, typename Allocator,
504 typename CompletionCondition, typename ReadHandler>
505 inline void asio_handler_deallocate(void* pointer, std::size_t size,
506 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
507 CompletionCondition, ReadHandler>* this_handler)
508 {
509 boost_asio_handler_alloc_helpers::deallocate(
510 pointer, size, this_handler->handler_);
511 }
512
513 template <typename AsyncRandomAccessReadDevice, typename Allocator,
514 typename CompletionCondition, typename ReadHandler>
515 inline bool asio_handler_is_continuation(
516 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
517 CompletionCondition, ReadHandler>* this_handler)
518 {
519 return this_handler->start_ == 0 ? true
520 : boost_asio_handler_cont_helpers::is_continuation(
521 this_handler->handler_);
522 }
523
524 template <typename Function, typename AsyncRandomAccessReadDevice,
525 typename Allocator, typename CompletionCondition, typename ReadHandler>
526 inline void asio_handler_invoke(Function& function,
527 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
528 CompletionCondition, ReadHandler>* this_handler)
529 {
530 boost_asio_handler_invoke_helpers::invoke(
531 function, this_handler->handler_);
532 }
533
534 template <typename Function, typename AsyncRandomAccessReadDevice,
535 typename Allocator, typename CompletionCondition, typename ReadHandler>
536 inline void asio_handler_invoke(const Function& function,
537 read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
538 CompletionCondition, ReadHandler>* this_handler)
539 {
540 boost_asio_handler_invoke_helpers::invoke(
541 function, this_handler->handler_);
542 }
543 } // namespace detail
544
545 #if !defined(GENERATING_DOCUMENTATION)
546
547 template <typename AsyncRandomAccessReadDevice, typename Allocator,
548 typename CompletionCondition, typename ReadHandler, typename Allocator1>
549 struct associated_allocator<
550 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
551 Allocator, CompletionCondition, ReadHandler>,
552 Allocator1>
553 {
554 typedef typename associated_allocator<ReadHandler, Allocator1>::type type;
555
556 static type get(
557 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
558 Allocator, CompletionCondition, ReadHandler>& h,
559 const Allocator1& a = Allocator1()) BOOST_ASIO_NOEXCEPT
560 {
561 return associated_allocator<ReadHandler, Allocator1>::get(h.handler_, a);
562 }
563 };
564
565 template <typename AsyncRandomAccessReadDevice, typename Executor,
566 typename CompletionCondition, typename ReadHandler, typename Executor1>
567 struct associated_executor<
568 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
569 Executor, CompletionCondition, ReadHandler>,
570 Executor1>
571 {
572 typedef typename associated_executor<ReadHandler, Executor1>::type type;
573
574 static type get(
575 const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
576 Executor, CompletionCondition, ReadHandler>& h,
577 const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
578 {
579 return associated_executor<ReadHandler, Executor1>::get(h.handler_, ex);
580 }
581 };
582
583 #endif // !defined(GENERATING_DOCUMENTATION)
584
585 template <typename AsyncRandomAccessReadDevice, typename Allocator,
586 typename CompletionCondition, typename ReadHandler>
587 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
588 void (boost::system::error_code, std::size_t))
589 async_read_at(AsyncRandomAccessReadDevice& d,
590 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
591 CompletionCondition completion_condition,
592 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
593 {
594 // If you get an error on the following line it means that your handler does
595 // not meet the documented type requirements for a ReadHandler.
596 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
597
598 async_completion<ReadHandler,
599 void (boost::system::error_code, std::size_t)> init(handler);
600
601 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
602 CompletionCondition, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
603 void (boost::system::error_code, std::size_t))>(
604 d, offset, b, completion_condition, init.completion_handler)(
605 boost::system::error_code(), 0, 1);
606
607 return init.result.get();
608 }
609
610 template <typename AsyncRandomAccessReadDevice, typename Allocator,
611 typename ReadHandler>
612 inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
613 void (boost::system::error_code, std::size_t))
614 async_read_at(AsyncRandomAccessReadDevice& d,
615 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
616 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
617 {
618 // If you get an error on the following line it means that your handler does
619 // not meet the documented type requirements for a ReadHandler.
620 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
621
622 async_completion<ReadHandler,
623 void (boost::system::error_code, std::size_t)> init(handler);
624
625 detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
626 detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
627 void (boost::system::error_code, std::size_t))>(
628 d, offset, b, transfer_all(), init.completion_handler)(
629 boost::system::error_code(), 0, 1);
630
631 return init.result.get();
632 }
633
634 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
635 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
636
637 } // namespace asio
638 } // namespace boost
639
640 #include <boost/asio/detail/pop_options.hpp>
641
642 #endif // BOOST_ASIO_IMPL_READ_AT_HPP