5 // Copyright (c) 2003-2016 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_WRITE_AT_HPP
12 #define BOOST_ASIO_IMPL_WRITE_AT_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/buffer.hpp>
19 #include <boost/asio/completion_condition.hpp>
20 #include <boost/asio/detail/array_fwd.hpp>
21 #include <boost/asio/detail/base_from_completion_cond.hpp>
22 #include <boost/asio/detail/bind_handler.hpp>
23 #include <boost/asio/detail/consuming_buffers.hpp>
24 #include <boost/asio/detail/dependent_type.hpp>
25 #include <boost/asio/detail/handler_alloc_helpers.hpp>
26 #include <boost/asio/detail/handler_cont_helpers.hpp>
27 #include <boost/asio/detail/handler_invoke_helpers.hpp>
28 #include <boost/asio/detail/handler_type_requirements.hpp>
29 #include <boost/asio/detail/throw_error.hpp>
31 #include <boost/asio/detail/push_options.hpp>
36 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
37 typename CompletionCondition>
38 std::size_t write_at(SyncRandomAccessWriteDevice& d,
39 uint64_t offset, const ConstBufferSequence& buffers,
40 CompletionCondition completion_condition, boost::system::error_code& ec)
42 ec = boost::system::error_code();
43 boost::asio::detail::consuming_buffers<
44 const_buffer, ConstBufferSequence> tmp(buffers);
45 std::size_t total_transferred = 0;
46 tmp.prepare(detail::adapt_completion_condition_result(
47 completion_condition(ec, total_transferred)));
48 while (tmp.begin() != tmp.end())
50 std::size_t bytes_transferred = d.write_some_at(
51 offset + total_transferred, tmp, ec);
52 tmp.consume(bytes_transferred);
53 total_transferred += bytes_transferred;
54 tmp.prepare(detail::adapt_completion_condition_result(
55 completion_condition(ec, total_transferred)));
57 return total_transferred;
60 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
61 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
62 uint64_t offset, const ConstBufferSequence& buffers)
64 boost::system::error_code ec;
65 std::size_t bytes_transferred = write_at(
66 d, offset, buffers, transfer_all(), ec);
67 boost::asio::detail::throw_error(ec, "write_at");
68 return bytes_transferred;
71 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
72 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
73 uint64_t offset, const ConstBufferSequence& buffers,
74 boost::system::error_code& ec)
76 return write_at(d, offset, buffers, transfer_all(), ec);
79 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
80 typename CompletionCondition>
81 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
82 uint64_t offset, const ConstBufferSequence& buffers,
83 CompletionCondition completion_condition)
85 boost::system::error_code ec;
86 std::size_t bytes_transferred = write_at(
87 d, offset, buffers, completion_condition, ec);
88 boost::asio::detail::throw_error(ec, "write_at");
89 return bytes_transferred;
92 #if !defined(BOOST_ASIO_NO_IOSTREAM)
94 template <typename SyncRandomAccessWriteDevice, typename Allocator,
95 typename CompletionCondition>
96 std::size_t write_at(SyncRandomAccessWriteDevice& d,
97 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
98 CompletionCondition completion_condition, boost::system::error_code& ec)
100 std::size_t bytes_transferred = write_at(
101 d, offset, b.data(), completion_condition, ec);
102 b.consume(bytes_transferred);
103 return bytes_transferred;
106 template <typename SyncRandomAccessWriteDevice, typename Allocator>
107 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
108 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
110 boost::system::error_code ec;
111 std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
112 boost::asio::detail::throw_error(ec, "write_at");
113 return bytes_transferred;
116 template <typename SyncRandomAccessWriteDevice, typename Allocator>
117 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
118 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
119 boost::system::error_code& ec)
121 return write_at(d, offset, b, transfer_all(), ec);
124 template <typename SyncRandomAccessWriteDevice, typename Allocator,
125 typename CompletionCondition>
126 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
127 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
128 CompletionCondition completion_condition)
130 boost::system::error_code ec;
131 std::size_t bytes_transferred = write_at(
132 d, offset, b, completion_condition, ec);
133 boost::asio::detail::throw_error(ec, "write_at");
134 return bytes_transferred;
137 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
141 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
142 typename CompletionCondition, typename WriteHandler>
144 : detail::base_from_completion_cond<CompletionCondition>
147 write_at_op(AsyncRandomAccessWriteDevice& device,
148 uint64_t offset, const ConstBufferSequence& buffers,
149 CompletionCondition completion_condition, WriteHandler& handler)
150 : detail::base_from_completion_cond<
151 CompletionCondition>(completion_condition),
156 total_transferred_(0),
157 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
161 #if defined(BOOST_ASIO_HAS_MOVE)
162 write_at_op(const write_at_op& other)
163 : detail::base_from_completion_cond<CompletionCondition>(other),
164 device_(other.device_),
165 offset_(other.offset_),
166 buffers_(other.buffers_),
167 start_(other.start_),
168 total_transferred_(other.total_transferred_),
169 handler_(other.handler_)
173 write_at_op(write_at_op&& other)
174 : detail::base_from_completion_cond<CompletionCondition>(other),
175 device_(other.device_),
176 offset_(other.offset_),
177 buffers_(other.buffers_),
178 start_(other.start_),
179 total_transferred_(other.total_transferred_),
180 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
183 #endif // defined(BOOST_ASIO_HAS_MOVE)
185 void operator()(const boost::system::error_code& ec,
186 std::size_t bytes_transferred, int start = 0)
188 switch (start_ = start)
191 buffers_.prepare(this->check_for_completion(ec, total_transferred_));
194 device_.async_write_some_at(
195 offset_ + total_transferred_, buffers_,
196 BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
198 total_transferred_ += bytes_transferred;
199 buffers_.consume(bytes_transferred);
200 buffers_.prepare(this->check_for_completion(ec, total_transferred_));
201 if ((!ec && bytes_transferred == 0)
202 || buffers_.begin() == buffers_.end())
206 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
211 AsyncRandomAccessWriteDevice& device_;
213 boost::asio::detail::consuming_buffers<
214 const_buffer, ConstBufferSequence> buffers_;
216 std::size_t total_transferred_;
217 WriteHandler handler_;
220 template <typename AsyncRandomAccessWriteDevice,
221 typename CompletionCondition, typename WriteHandler>
222 class write_at_op<AsyncRandomAccessWriteDevice,
223 boost::asio::mutable_buffers_1, CompletionCondition, WriteHandler>
224 : detail::base_from_completion_cond<CompletionCondition>
227 write_at_op(AsyncRandomAccessWriteDevice& device,
228 uint64_t offset, const boost::asio::mutable_buffers_1& buffers,
229 CompletionCondition completion_condition,
230 WriteHandler& handler)
231 : detail::base_from_completion_cond<
232 CompletionCondition>(completion_condition),
237 total_transferred_(0),
238 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
242 #if defined(BOOST_ASIO_HAS_MOVE)
243 write_at_op(const write_at_op& other)
244 : detail::base_from_completion_cond<CompletionCondition>(other),
245 device_(other.device_),
246 offset_(other.offset_),
247 buffer_(other.buffer_),
248 start_(other.start_),
249 total_transferred_(other.total_transferred_),
250 handler_(other.handler_)
254 write_at_op(write_at_op&& other)
255 : detail::base_from_completion_cond<CompletionCondition>(other),
256 device_(other.device_),
257 offset_(other.offset_),
258 buffer_(other.buffer_),
259 start_(other.start_),
260 total_transferred_(other.total_transferred_),
261 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(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)
270 switch (start_ = start)
273 n = this->check_for_completion(ec, total_transferred_);
276 device_.async_write_some_at(offset_ + total_transferred_,
277 boost::asio::buffer(buffer_ + total_transferred_, n),
278 BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
280 total_transferred_ += bytes_transferred;
281 if ((!ec && bytes_transferred == 0)
282 || (n = this->check_for_completion(ec, total_transferred_)) == 0
283 || total_transferred_ == boost::asio::buffer_size(buffer_))
287 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
292 AsyncRandomAccessWriteDevice& device_;
294 boost::asio::mutable_buffer buffer_;
296 std::size_t total_transferred_;
297 WriteHandler handler_;
300 template <typename AsyncRandomAccessWriteDevice,
301 typename CompletionCondition, typename WriteHandler>
302 class write_at_op<AsyncRandomAccessWriteDevice, boost::asio::const_buffers_1,
303 CompletionCondition, WriteHandler>
304 : detail::base_from_completion_cond<CompletionCondition>
307 write_at_op(AsyncRandomAccessWriteDevice& device,
308 uint64_t offset, const boost::asio::const_buffers_1& buffers,
309 CompletionCondition completion_condition,
310 WriteHandler& handler)
311 : detail::base_from_completion_cond<
312 CompletionCondition>(completion_condition),
317 total_transferred_(0),
318 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
322 #if defined(BOOST_ASIO_HAS_MOVE)
323 write_at_op(const write_at_op& other)
324 : detail::base_from_completion_cond<CompletionCondition>(other),
325 device_(other.device_),
326 offset_(other.offset_),
327 buffer_(other.buffer_),
328 start_(other.start_),
329 total_transferred_(other.total_transferred_),
330 handler_(other.handler_)
334 write_at_op(write_at_op&& other)
335 : detail::base_from_completion_cond<CompletionCondition>(other),
336 device_(other.device_),
337 offset_(other.offset_),
338 buffer_(other.buffer_),
339 start_(other.start_),
340 total_transferred_(other.total_transferred_),
341 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
344 #endif // defined(BOOST_ASIO_HAS_MOVE)
346 void operator()(const boost::system::error_code& ec,
347 std::size_t bytes_transferred, int start = 0)
350 switch (start_ = start)
353 n = this->check_for_completion(ec, total_transferred_);
356 device_.async_write_some_at(offset_ + total_transferred_,
357 boost::asio::buffer(buffer_ + total_transferred_, n),
358 BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
360 total_transferred_ += bytes_transferred;
361 if ((!ec && bytes_transferred == 0)
362 || (n = this->check_for_completion(ec, total_transferred_)) == 0
363 || total_transferred_ == boost::asio::buffer_size(buffer_))
367 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
372 AsyncRandomAccessWriteDevice& device_;
374 boost::asio::const_buffer buffer_;
376 std::size_t total_transferred_;
377 WriteHandler handler_;
380 template <typename AsyncRandomAccessWriteDevice, typename Elem,
381 typename CompletionCondition, typename WriteHandler>
382 class write_at_op<AsyncRandomAccessWriteDevice, boost::array<Elem, 2>,
383 CompletionCondition, WriteHandler>
384 : detail::base_from_completion_cond<CompletionCondition>
387 write_at_op(AsyncRandomAccessWriteDevice& device,
388 uint64_t offset, const boost::array<Elem, 2>& buffers,
389 CompletionCondition completion_condition, WriteHandler& handler)
390 : detail::base_from_completion_cond<
391 CompletionCondition>(completion_condition),
396 total_transferred_(0),
397 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
401 #if defined(BOOST_ASIO_HAS_MOVE)
402 write_at_op(const write_at_op& other)
403 : detail::base_from_completion_cond<CompletionCondition>(other),
404 device_(other.device_),
405 offset_(other.offset_),
406 buffers_(other.buffers_),
407 start_(other.start_),
408 total_transferred_(other.total_transferred_),
409 handler_(other.handler_)
413 write_at_op(write_at_op&& other)
414 : detail::base_from_completion_cond<CompletionCondition>(other),
415 device_(other.device_),
416 offset_(other.offset_),
417 buffers_(other.buffers_),
418 start_(other.start_),
419 total_transferred_(other.total_transferred_),
420 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
423 #endif // defined(BOOST_ASIO_HAS_MOVE)
425 void operator()(const boost::system::error_code& ec,
426 std::size_t bytes_transferred, int start = 0)
428 typename boost::asio::detail::dependent_type<Elem,
429 boost::array<boost::asio::const_buffer, 2> >::type bufs = {{
430 boost::asio::const_buffer(buffers_[0]),
431 boost::asio::const_buffer(buffers_[1]) }};
432 std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
433 std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
435 switch (start_ = start)
438 n = this->check_for_completion(ec, total_transferred_);
441 bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
442 bufs[1] = boost::asio::buffer(
443 bufs[1] + (total_transferred_ < buffer_size0
444 ? 0 : total_transferred_ - buffer_size0),
445 n - boost::asio::buffer_size(bufs[0]));
446 device_.async_write_some_at(offset_ + total_transferred_,
447 bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
449 total_transferred_ += bytes_transferred;
450 if ((!ec && bytes_transferred == 0)
451 || (n = this->check_for_completion(ec, total_transferred_)) == 0
452 || total_transferred_ == buffer_size0 + buffer_size1)
456 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
461 AsyncRandomAccessWriteDevice& device_;
463 boost::array<Elem, 2> buffers_;
465 std::size_t total_transferred_;
466 WriteHandler handler_;
469 #if defined(BOOST_ASIO_HAS_STD_ARRAY)
471 template <typename AsyncRandomAccessWriteDevice, typename Elem,
472 typename CompletionCondition, typename WriteHandler>
473 class write_at_op<AsyncRandomAccessWriteDevice, std::array<Elem, 2>,
474 CompletionCondition, WriteHandler>
475 : detail::base_from_completion_cond<CompletionCondition>
478 write_at_op(AsyncRandomAccessWriteDevice& device,
479 uint64_t offset, const std::array<Elem, 2>& buffers,
480 CompletionCondition completion_condition, WriteHandler& handler)
481 : detail::base_from_completion_cond<
482 CompletionCondition>(completion_condition),
487 total_transferred_(0),
488 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
492 #if defined(BOOST_ASIO_HAS_MOVE)
493 write_at_op(const write_at_op& other)
494 : detail::base_from_completion_cond<CompletionCondition>(other),
495 device_(other.device_),
496 offset_(other.offset_),
497 buffers_(other.buffers_),
498 start_(other.start_),
499 total_transferred_(other.total_transferred_),
500 handler_(other.handler_)
504 write_at_op(write_at_op&& other)
505 : detail::base_from_completion_cond<CompletionCondition>(other),
506 device_(other.device_),
507 offset_(other.offset_),
508 buffers_(other.buffers_),
509 start_(other.start_),
510 total_transferred_(other.total_transferred_),
511 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
514 #endif // defined(BOOST_ASIO_HAS_MOVE)
516 void operator()(const boost::system::error_code& ec,
517 std::size_t bytes_transferred, int start = 0)
519 typename boost::asio::detail::dependent_type<Elem,
520 std::array<boost::asio::const_buffer, 2> >::type bufs = {{
521 boost::asio::const_buffer(buffers_[0]),
522 boost::asio::const_buffer(buffers_[1]) }};
523 std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
524 std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
526 switch (start_ = start)
529 n = this->check_for_completion(ec, total_transferred_);
532 bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
533 bufs[1] = boost::asio::buffer(
534 bufs[1] + (total_transferred_ < buffer_size0
535 ? 0 : total_transferred_ - buffer_size0),
536 n - boost::asio::buffer_size(bufs[0]));
537 device_.async_write_some_at(offset_ + total_transferred_,
538 bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
540 total_transferred_ += bytes_transferred;
541 if ((!ec && bytes_transferred == 0)
542 || (n = this->check_for_completion(ec, total_transferred_)) == 0
543 || total_transferred_ == buffer_size0 + buffer_size1)
547 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
552 AsyncRandomAccessWriteDevice& device_;
554 std::array<Elem, 2> buffers_;
556 std::size_t total_transferred_;
557 WriteHandler handler_;
560 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
562 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
563 typename CompletionCondition, typename WriteHandler>
564 inline void* asio_handler_allocate(std::size_t size,
565 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
566 CompletionCondition, WriteHandler>* this_handler)
568 return boost_asio_handler_alloc_helpers::allocate(
569 size, this_handler->handler_);
572 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
573 typename CompletionCondition, typename WriteHandler>
574 inline void asio_handler_deallocate(void* pointer, std::size_t size,
575 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
576 CompletionCondition, WriteHandler>* this_handler)
578 boost_asio_handler_alloc_helpers::deallocate(
579 pointer, size, this_handler->handler_);
582 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
583 typename CompletionCondition, typename WriteHandler>
584 inline bool asio_handler_is_continuation(
585 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
586 CompletionCondition, WriteHandler>* this_handler)
588 return this_handler->start_ == 0 ? true
589 : boost_asio_handler_cont_helpers::is_continuation(
590 this_handler->handler_);
593 template <typename Function, typename AsyncRandomAccessWriteDevice,
594 typename ConstBufferSequence, typename CompletionCondition,
595 typename WriteHandler>
596 inline void asio_handler_invoke(Function& function,
597 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
598 CompletionCondition, WriteHandler>* this_handler)
600 boost_asio_handler_invoke_helpers::invoke(
601 function, this_handler->handler_);
604 template <typename Function, typename AsyncRandomAccessWriteDevice,
605 typename ConstBufferSequence, typename CompletionCondition,
606 typename WriteHandler>
607 inline void asio_handler_invoke(const Function& function,
608 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
609 CompletionCondition, WriteHandler>* this_handler)
611 boost_asio_handler_invoke_helpers::invoke(
612 function, this_handler->handler_);
615 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
616 typename CompletionCondition, typename WriteHandler>
617 inline write_at_op<AsyncRandomAccessWriteDevice,
618 ConstBufferSequence, CompletionCondition, WriteHandler>
619 make_write_at_op(AsyncRandomAccessWriteDevice& d,
620 uint64_t offset, const ConstBufferSequence& buffers,
621 CompletionCondition completion_condition, WriteHandler handler)
623 return write_at_op<AsyncRandomAccessWriteDevice,
624 ConstBufferSequence, CompletionCondition, WriteHandler>(
625 d, offset, buffers, completion_condition, handler);
627 } // namespace detail
629 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
630 typename CompletionCondition, typename WriteHandler>
631 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
632 void (boost::system::error_code, std::size_t))
633 async_write_at(AsyncRandomAccessWriteDevice& d,
634 uint64_t offset, const ConstBufferSequence& buffers,
635 CompletionCondition completion_condition,
636 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
638 // If you get an error on the following line it means that your handler does
639 // not meet the documented type requirements for a WriteHandler.
640 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
642 detail::async_result_init<
643 WriteHandler, void (boost::system::error_code, std::size_t)> init(
644 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
646 detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
647 CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
648 WriteHandler, void (boost::system::error_code, std::size_t))>(
649 d, offset, buffers, completion_condition, init.handler)(
650 boost::system::error_code(), 0, 1);
652 return init.result.get();
655 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
656 typename WriteHandler>
657 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
658 void (boost::system::error_code, std::size_t))
659 async_write_at(AsyncRandomAccessWriteDevice& d,
660 uint64_t offset, const ConstBufferSequence& buffers,
661 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
663 // If you get an error on the following line it means that your handler does
664 // not meet the documented type requirements for a WriteHandler.
665 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
667 detail::async_result_init<
668 WriteHandler, void (boost::system::error_code, std::size_t)> init(
669 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
671 detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
672 detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(
673 WriteHandler, void (boost::system::error_code, std::size_t))>(
674 d, offset, buffers, transfer_all(), init.handler)(
675 boost::system::error_code(), 0, 1);
677 return init.result.get();
680 #if !defined(BOOST_ASIO_NO_IOSTREAM)
684 template <typename Allocator, typename WriteHandler>
685 class write_at_streambuf_op
688 write_at_streambuf_op(
689 boost::asio::basic_streambuf<Allocator>& streambuf,
690 WriteHandler& handler)
691 : streambuf_(streambuf),
692 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
696 #if defined(BOOST_ASIO_HAS_MOVE)
697 write_at_streambuf_op(const write_at_streambuf_op& other)
698 : streambuf_(other.streambuf_),
699 handler_(other.handler_)
703 write_at_streambuf_op(write_at_streambuf_op&& other)
704 : streambuf_(other.streambuf_),
705 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
708 #endif // defined(BOOST_ASIO_HAS_MOVE)
710 void operator()(const boost::system::error_code& ec,
711 const std::size_t bytes_transferred)
713 streambuf_.consume(bytes_transferred);
714 handler_(ec, bytes_transferred);
718 boost::asio::basic_streambuf<Allocator>& streambuf_;
719 WriteHandler handler_;
722 template <typename Allocator, typename WriteHandler>
723 inline void* asio_handler_allocate(std::size_t size,
724 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
726 return boost_asio_handler_alloc_helpers::allocate(
727 size, this_handler->handler_);
730 template <typename Allocator, typename WriteHandler>
731 inline void asio_handler_deallocate(void* pointer, std::size_t size,
732 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
734 boost_asio_handler_alloc_helpers::deallocate(
735 pointer, size, this_handler->handler_);
738 template <typename Allocator, typename WriteHandler>
739 inline bool asio_handler_is_continuation(
740 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
742 return boost_asio_handler_cont_helpers::is_continuation(
743 this_handler->handler_);
746 template <typename Function, typename Allocator, typename WriteHandler>
747 inline void asio_handler_invoke(Function& function,
748 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
750 boost_asio_handler_invoke_helpers::invoke(
751 function, this_handler->handler_);
754 template <typename Function, typename Allocator, typename WriteHandler>
755 inline void asio_handler_invoke(const Function& function,
756 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
758 boost_asio_handler_invoke_helpers::invoke(
759 function, this_handler->handler_);
762 template <typename Allocator, typename WriteHandler>
763 inline write_at_streambuf_op<Allocator, WriteHandler>
764 make_write_at_streambuf_op(
765 boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
767 return write_at_streambuf_op<Allocator, WriteHandler>(b, handler);
769 } // namespace detail
771 template <typename AsyncRandomAccessWriteDevice, typename Allocator,
772 typename CompletionCondition, typename WriteHandler>
773 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
774 void (boost::system::error_code, std::size_t))
775 async_write_at(AsyncRandomAccessWriteDevice& d,
776 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
777 CompletionCondition completion_condition,
778 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
780 // If you get an error on the following line it means that your handler does
781 // not meet the documented type requirements for a WriteHandler.
782 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
784 detail::async_result_init<
785 WriteHandler, void (boost::system::error_code, std::size_t)> init(
786 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
788 async_write_at(d, offset, b.data(), completion_condition,
789 detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
790 WriteHandler, void (boost::system::error_code, std::size_t))>(
793 return init.result.get();
796 template <typename AsyncRandomAccessWriteDevice, typename Allocator,
797 typename WriteHandler>
798 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
799 void (boost::system::error_code, std::size_t))
800 async_write_at(AsyncRandomAccessWriteDevice& d,
801 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
802 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
804 // If you get an error on the following line it means that your handler does
805 // not meet the documented type requirements for a WriteHandler.
806 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
808 detail::async_result_init<
809 WriteHandler, void (boost::system::error_code, std::size_t)> init(
810 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
812 async_write_at(d, offset, b.data(), transfer_all(),
813 detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
814 WriteHandler, void (boost::system::error_code, std::size_t))>(
817 return init.result.get();
820 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
825 #include <boost/asio/detail/pop_options.hpp>
827 #endif // BOOST_ASIO_IMPL_WRITE_AT_HPP