Chris@16: // Chris@16: // impl/write_at.hpp Chris@16: // ~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_IMPL_WRITE_AT_HPP Chris@16: #define BOOST_ASIO_IMPL_WRITE_AT_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: Chris@16: template Chris@16: std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: CompletionCondition completion_condition, boost::system::error_code& ec) Chris@16: { Chris@16: ec = boost::system::error_code(); Chris@16: boost::asio::detail::consuming_buffers< Chris@16: const_buffer, ConstBufferSequence> tmp(buffers); Chris@16: std::size_t total_transferred = 0; Chris@16: tmp.prepare(detail::adapt_completion_condition_result( Chris@16: completion_condition(ec, total_transferred))); Chris@16: while (tmp.begin() != tmp.end()) Chris@16: { Chris@16: std::size_t bytes_transferred = d.write_some_at( Chris@16: offset + total_transferred, tmp, ec); Chris@16: tmp.consume(bytes_transferred); Chris@16: total_transferred += bytes_transferred; Chris@16: tmp.prepare(detail::adapt_completion_condition_result( Chris@16: completion_condition(ec, total_transferred))); Chris@16: } Chris@16: return total_transferred; Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t bytes_transferred = write_at( Chris@16: d, offset, buffers, transfer_all(), ec); Chris@16: boost::asio::detail::throw_error(ec, "write_at"); Chris@16: return bytes_transferred; Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: boost::system::error_code& ec) Chris@16: { Chris@16: return write_at(d, offset, buffers, transfer_all(), ec); Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: CompletionCondition completion_condition) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t bytes_transferred = write_at( Chris@16: d, offset, buffers, completion_condition, ec); Chris@16: boost::asio::detail::throw_error(ec, "write_at"); Chris@16: return bytes_transferred; Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_ASIO_NO_IOSTREAM) Chris@16: Chris@16: template Chris@16: std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b, Chris@16: CompletionCondition completion_condition, boost::system::error_code& ec) Chris@16: { Chris@16: std::size_t bytes_transferred = write_at( Chris@16: d, offset, b.data(), completion_condition, ec); Chris@16: b.consume(bytes_transferred); Chris@16: return bytes_transferred; Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec); Chris@16: boost::asio::detail::throw_error(ec, "write_at"); Chris@16: return bytes_transferred; Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b, Chris@16: boost::system::error_code& ec) Chris@16: { Chris@16: return write_at(d, offset, b, transfer_all(), ec); Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t write_at(SyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b, Chris@16: CompletionCondition completion_condition) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t bytes_transferred = write_at( Chris@16: d, offset, b, completion_condition, ec); Chris@16: boost::asio::detail::throw_error(ec, "write_at"); Chris@16: return bytes_transferred; Chris@16: } Chris@16: Chris@16: #endif // !defined(BOOST_ASIO_NO_IOSTREAM) Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: class write_at_op Chris@16: : detail::base_from_completion_cond Chris@16: { Chris@16: public: Chris@16: write_at_op(AsyncRandomAccessWriteDevice& device, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: CompletionCondition completion_condition, WriteHandler& handler) Chris@16: : detail::base_from_completion_cond< Chris@16: CompletionCondition>(completion_condition), Chris@16: device_(device), Chris@16: offset_(offset), Chris@16: buffers_(buffers), Chris@16: start_(0), Chris@16: total_transferred_(0), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_op(const write_at_op& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_op(write_at_op&& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: std::size_t bytes_transferred, int start = 0) Chris@16: { Chris@16: switch (start_ = start) Chris@16: { Chris@16: case 1: Chris@16: buffers_.prepare(this->check_for_completion(ec, total_transferred_)); Chris@16: for (;;) Chris@16: { Chris@16: device_.async_write_some_at( Chris@16: offset_ + total_transferred_, buffers_, Chris@16: BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); Chris@16: return; default: Chris@16: total_transferred_ += bytes_transferred; Chris@16: buffers_.consume(bytes_transferred); Chris@16: buffers_.prepare(this->check_for_completion(ec, total_transferred_)); Chris@16: if ((!ec && bytes_transferred == 0) Chris@16: || buffers_.begin() == buffers_.end()) Chris@16: break; Chris@16: } Chris@16: Chris@16: handler_(ec, static_cast(total_transferred_)); Chris@16: } Chris@16: } Chris@16: Chris@16: //private: Chris@16: AsyncRandomAccessWriteDevice& device_; Chris@16: uint64_t offset_; Chris@16: boost::asio::detail::consuming_buffers< Chris@16: const_buffer, ConstBufferSequence> buffers_; Chris@16: int start_; Chris@16: std::size_t total_transferred_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class write_at_op Chris@16: : detail::base_from_completion_cond Chris@16: { Chris@16: public: Chris@16: write_at_op(AsyncRandomAccessWriteDevice& device, Chris@16: uint64_t offset, const boost::asio::mutable_buffers_1& buffers, Chris@16: CompletionCondition completion_condition, Chris@16: WriteHandler& handler) Chris@16: : detail::base_from_completion_cond< Chris@16: CompletionCondition>(completion_condition), Chris@16: device_(device), Chris@16: offset_(offset), Chris@16: buffer_(buffers), Chris@16: start_(0), Chris@16: total_transferred_(0), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_op(const write_at_op& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffer_(other.buffer_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_op(write_at_op&& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffer_(other.buffer_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: std::size_t bytes_transferred, int start = 0) Chris@16: { Chris@16: std::size_t n = 0; Chris@16: switch (start_ = start) Chris@16: { Chris@16: case 1: Chris@16: n = this->check_for_completion(ec, total_transferred_); Chris@16: for (;;) Chris@16: { Chris@16: device_.async_write_some_at(offset_ + total_transferred_, Chris@16: boost::asio::buffer(buffer_ + total_transferred_, n), Chris@16: BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); Chris@16: return; default: Chris@16: total_transferred_ += bytes_transferred; Chris@16: if ((!ec && bytes_transferred == 0) Chris@16: || (n = this->check_for_completion(ec, total_transferred_)) == 0 Chris@16: || total_transferred_ == boost::asio::buffer_size(buffer_)) Chris@16: break; Chris@16: } Chris@16: Chris@16: handler_(ec, static_cast(total_transferred_)); Chris@16: } Chris@16: } Chris@16: Chris@16: //private: Chris@16: AsyncRandomAccessWriteDevice& device_; Chris@16: uint64_t offset_; Chris@16: boost::asio::mutable_buffer buffer_; Chris@16: int start_; Chris@16: std::size_t total_transferred_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class write_at_op Chris@16: : detail::base_from_completion_cond Chris@16: { Chris@16: public: Chris@16: write_at_op(AsyncRandomAccessWriteDevice& device, Chris@16: uint64_t offset, const boost::asio::const_buffers_1& buffers, Chris@16: CompletionCondition completion_condition, Chris@16: WriteHandler& handler) Chris@16: : detail::base_from_completion_cond< Chris@16: CompletionCondition>(completion_condition), Chris@16: device_(device), Chris@16: offset_(offset), Chris@16: buffer_(buffers), Chris@16: start_(0), Chris@16: total_transferred_(0), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_op(const write_at_op& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffer_(other.buffer_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_op(write_at_op&& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffer_(other.buffer_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: std::size_t bytes_transferred, int start = 0) Chris@16: { Chris@16: std::size_t n = 0; Chris@16: switch (start_ = start) Chris@16: { Chris@16: case 1: Chris@16: n = this->check_for_completion(ec, total_transferred_); Chris@16: for (;;) Chris@16: { Chris@16: device_.async_write_some_at(offset_ + total_transferred_, Chris@16: boost::asio::buffer(buffer_ + total_transferred_, n), Chris@16: BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); Chris@16: return; default: Chris@16: total_transferred_ += bytes_transferred; Chris@16: if ((!ec && bytes_transferred == 0) Chris@16: || (n = this->check_for_completion(ec, total_transferred_)) == 0 Chris@16: || total_transferred_ == boost::asio::buffer_size(buffer_)) Chris@16: break; Chris@16: } Chris@16: Chris@16: handler_(ec, static_cast(total_transferred_)); Chris@16: } Chris@16: } Chris@16: Chris@16: //private: Chris@16: AsyncRandomAccessWriteDevice& device_; Chris@16: uint64_t offset_; Chris@16: boost::asio::const_buffer buffer_; Chris@16: int start_; Chris@16: std::size_t total_transferred_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class write_at_op, Chris@16: CompletionCondition, WriteHandler> Chris@16: : detail::base_from_completion_cond Chris@16: { Chris@16: public: Chris@16: write_at_op(AsyncRandomAccessWriteDevice& device, Chris@16: uint64_t offset, const boost::array& buffers, Chris@16: CompletionCondition completion_condition, WriteHandler& handler) Chris@16: : detail::base_from_completion_cond< Chris@16: CompletionCondition>(completion_condition), Chris@16: device_(device), Chris@16: offset_(offset), Chris@16: buffers_(buffers), Chris@16: start_(0), Chris@16: total_transferred_(0), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_op(const write_at_op& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_op(write_at_op&& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: std::size_t bytes_transferred, int start = 0) Chris@16: { Chris@16: typename boost::asio::detail::dependent_type >::type bufs = {{ Chris@16: boost::asio::const_buffer(buffers_[0]), Chris@16: boost::asio::const_buffer(buffers_[1]) }}; Chris@16: std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); Chris@16: std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); Chris@16: std::size_t n = 0; Chris@16: switch (start_ = start) Chris@16: { Chris@16: case 1: Chris@16: n = this->check_for_completion(ec, total_transferred_); Chris@16: for (;;) Chris@16: { Chris@16: bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); Chris@16: bufs[1] = boost::asio::buffer( Chris@16: bufs[1] + (total_transferred_ < buffer_size0 Chris@16: ? 0 : total_transferred_ - buffer_size0), Chris@16: n - boost::asio::buffer_size(bufs[0])); Chris@16: device_.async_write_some_at(offset_ + total_transferred_, Chris@16: bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); Chris@16: return; default: Chris@16: total_transferred_ += bytes_transferred; Chris@16: if ((!ec && bytes_transferred == 0) Chris@16: || (n = this->check_for_completion(ec, total_transferred_)) == 0 Chris@16: || total_transferred_ == buffer_size0 + buffer_size1) Chris@16: break; Chris@16: } Chris@16: Chris@16: handler_(ec, static_cast(total_transferred_)); Chris@16: } Chris@16: } Chris@16: Chris@16: //private: Chris@16: AsyncRandomAccessWriteDevice& device_; Chris@16: uint64_t offset_; Chris@16: boost::array buffers_; Chris@16: int start_; Chris@16: std::size_t total_transferred_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_STD_ARRAY) Chris@16: Chris@16: template Chris@16: class write_at_op, Chris@16: CompletionCondition, WriteHandler> Chris@16: : detail::base_from_completion_cond Chris@16: { Chris@16: public: Chris@16: write_at_op(AsyncRandomAccessWriteDevice& device, Chris@16: uint64_t offset, const std::array& buffers, Chris@16: CompletionCondition completion_condition, WriteHandler& handler) Chris@16: : detail::base_from_completion_cond< Chris@16: CompletionCondition>(completion_condition), Chris@16: device_(device), Chris@16: offset_(offset), Chris@16: buffers_(buffers), Chris@16: start_(0), Chris@16: total_transferred_(0), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_op(const write_at_op& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_op(write_at_op&& other) Chris@16: : detail::base_from_completion_cond(other), Chris@16: device_(other.device_), Chris@16: offset_(other.offset_), Chris@16: buffers_(other.buffers_), Chris@16: start_(other.start_), Chris@16: total_transferred_(other.total_transferred_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: std::size_t bytes_transferred, int start = 0) Chris@16: { Chris@16: typename boost::asio::detail::dependent_type >::type bufs = {{ Chris@16: boost::asio::const_buffer(buffers_[0]), Chris@16: boost::asio::const_buffer(buffers_[1]) }}; Chris@16: std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); Chris@16: std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); Chris@16: std::size_t n = 0; Chris@16: switch (start_ = start) Chris@16: { Chris@16: case 1: Chris@16: n = this->check_for_completion(ec, total_transferred_); Chris@16: for (;;) Chris@16: { Chris@16: bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); Chris@16: bufs[1] = boost::asio::buffer( Chris@16: bufs[1] + (total_transferred_ < buffer_size0 Chris@16: ? 0 : total_transferred_ - buffer_size0), Chris@16: n - boost::asio::buffer_size(bufs[0])); Chris@16: device_.async_write_some_at(offset_ + total_transferred_, Chris@16: bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); Chris@16: return; default: Chris@16: total_transferred_ += bytes_transferred; Chris@16: if ((!ec && bytes_transferred == 0) Chris@16: || (n = this->check_for_completion(ec, total_transferred_)) == 0 Chris@16: || total_transferred_ == buffer_size0 + buffer_size1) Chris@16: break; Chris@16: } Chris@16: Chris@16: handler_(ec, static_cast(total_transferred_)); Chris@16: } Chris@16: } Chris@16: Chris@16: //private: Chris@16: AsyncRandomAccessWriteDevice& device_; Chris@16: uint64_t offset_; Chris@16: std::array buffers_; Chris@16: int start_; Chris@16: std::size_t total_transferred_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: #endif // defined(BOOST_ASIO_HAS_STD_ARRAY) Chris@16: Chris@16: template Chris@16: inline void* asio_handler_allocate(std::size_t size, Chris@16: write_at_op* this_handler) Chris@16: { Chris@16: return boost_asio_handler_alloc_helpers::allocate( Chris@16: size, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_deallocate(void* pointer, std::size_t size, Chris@16: write_at_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_alloc_helpers::deallocate( Chris@16: pointer, size, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool asio_handler_is_continuation( Chris@16: write_at_op* this_handler) Chris@16: { Chris@16: return this_handler->start_ == 0 ? true Chris@16: : boost_asio_handler_cont_helpers::is_continuation( Chris@16: this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_invoke(Function& function, Chris@16: write_at_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_invoke_helpers::invoke( Chris@16: function, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_invoke(const Function& function, Chris@16: write_at_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_invoke_helpers::invoke( Chris@16: function, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline write_at_op Chris@16: make_write_at_op(AsyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: CompletionCondition completion_condition, WriteHandler handler) Chris@16: { Chris@16: return write_at_op( Chris@16: d, offset, buffers, completion_condition, handler); Chris@16: } Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, Chris@16: void (boost::system::error_code, std::size_t)) Chris@16: async_write_at(AsyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: CompletionCondition completion_condition, Chris@16: BOOST_ASIO_MOVE_ARG(WriteHandler) handler) Chris@16: { Chris@16: // If you get an error on the following line it means that your handler does Chris@16: // not meet the documented type requirements for a WriteHandler. Chris@16: BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; Chris@16: Chris@16: detail::async_result_init< Chris@16: WriteHandler, void (boost::system::error_code, std::size_t)> init( Chris@16: BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); Chris@16: Chris@16: detail::write_at_op( Chris@16: d, offset, buffers, completion_condition, init.handler)( Chris@16: boost::system::error_code(), 0, 1); Chris@16: Chris@16: return init.result.get(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, Chris@16: void (boost::system::error_code, std::size_t)) Chris@16: async_write_at(AsyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, const ConstBufferSequence& buffers, Chris@16: BOOST_ASIO_MOVE_ARG(WriteHandler) handler) Chris@16: { Chris@16: // If you get an error on the following line it means that your handler does Chris@16: // not meet the documented type requirements for a WriteHandler. Chris@16: BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; Chris@16: Chris@16: detail::async_result_init< Chris@16: WriteHandler, void (boost::system::error_code, std::size_t)> init( Chris@16: BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); Chris@16: Chris@16: detail::write_at_op( Chris@16: d, offset, buffers, transfer_all(), init.handler)( Chris@16: boost::system::error_code(), 0, 1); Chris@16: Chris@16: return init.result.get(); Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_ASIO_NO_IOSTREAM) Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: class write_at_streambuf_op Chris@16: { Chris@16: public: Chris@16: write_at_streambuf_op( Chris@16: boost::asio::basic_streambuf& streambuf, Chris@16: WriteHandler& handler) Chris@16: : streambuf_(streambuf), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) Chris@16: { Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_MOVE) Chris@16: write_at_streambuf_op(const write_at_streambuf_op& other) Chris@16: : streambuf_(other.streambuf_), Chris@16: handler_(other.handler_) Chris@16: { Chris@16: } Chris@16: Chris@16: write_at_streambuf_op(write_at_streambuf_op&& other) Chris@16: : streambuf_(other.streambuf_), Chris@16: handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) Chris@16: { Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_HAS_MOVE) Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, Chris@16: const std::size_t bytes_transferred) Chris@16: { Chris@16: streambuf_.consume(bytes_transferred); Chris@16: handler_(ec, bytes_transferred); Chris@16: } Chris@16: Chris@16: //private: Chris@16: boost::asio::basic_streambuf& streambuf_; Chris@16: WriteHandler handler_; Chris@16: }; Chris@16: Chris@16: template Chris@16: inline void* asio_handler_allocate(std::size_t size, Chris@16: write_at_streambuf_op* this_handler) Chris@16: { Chris@16: return boost_asio_handler_alloc_helpers::allocate( Chris@16: size, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_deallocate(void* pointer, std::size_t size, Chris@16: write_at_streambuf_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_alloc_helpers::deallocate( Chris@16: pointer, size, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool asio_handler_is_continuation( Chris@16: write_at_streambuf_op* this_handler) Chris@16: { Chris@16: return boost_asio_handler_cont_helpers::is_continuation( Chris@16: this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_invoke(Function& function, Chris@16: write_at_streambuf_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_invoke_helpers::invoke( Chris@16: function, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void asio_handler_invoke(const Function& function, Chris@16: write_at_streambuf_op* this_handler) Chris@16: { Chris@16: boost_asio_handler_invoke_helpers::invoke( Chris@16: function, this_handler->handler_); Chris@16: } Chris@16: Chris@16: template Chris@16: inline write_at_streambuf_op Chris@16: make_write_at_streambuf_op( Chris@16: boost::asio::basic_streambuf& b, WriteHandler handler) Chris@16: { Chris@16: return write_at_streambuf_op(b, handler); Chris@16: } Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, Chris@16: void (boost::system::error_code, std::size_t)) Chris@16: async_write_at(AsyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b, Chris@16: CompletionCondition completion_condition, Chris@16: BOOST_ASIO_MOVE_ARG(WriteHandler) handler) Chris@16: { Chris@16: // If you get an error on the following line it means that your handler does Chris@16: // not meet the documented type requirements for a WriteHandler. Chris@16: BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; Chris@16: Chris@16: detail::async_result_init< Chris@16: WriteHandler, void (boost::system::error_code, std::size_t)> init( Chris@16: BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); Chris@16: Chris@16: async_write_at(d, offset, b.data(), completion_condition, Chris@16: detail::write_at_streambuf_op( Chris@16: b, init.handler)); Chris@16: Chris@16: return init.result.get(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, Chris@16: void (boost::system::error_code, std::size_t)) Chris@16: async_write_at(AsyncRandomAccessWriteDevice& d, Chris@16: uint64_t offset, boost::asio::basic_streambuf& b, Chris@16: BOOST_ASIO_MOVE_ARG(WriteHandler) handler) Chris@16: { Chris@16: // If you get an error on the following line it means that your handler does Chris@16: // not meet the documented type requirements for a WriteHandler. Chris@16: BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; Chris@16: Chris@16: detail::async_result_init< Chris@16: WriteHandler, void (boost::system::error_code, std::size_t)> init( Chris@16: BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); Chris@16: Chris@16: async_write_at(d, offset, b.data(), transfer_all(), Chris@16: detail::write_at_streambuf_op( Chris@16: b, init.handler)); Chris@16: Chris@16: return init.result.get(); Chris@16: } Chris@16: Chris@16: #endif // !defined(BOOST_ASIO_NO_IOSTREAM) Chris@16: Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_IMPL_WRITE_AT_HPP