diff options
Diffstat (limited to '3rdParty/Boost/src/boost/asio/impl/write.ipp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/write.ipp | 180 |
1 files changed, 140 insertions, 40 deletions
diff --git a/3rdParty/Boost/src/boost/asio/impl/write.ipp b/3rdParty/Boost/src/boost/asio/impl/write.ipp index 76bace3..28a5273 100644 --- a/3rdParty/Boost/src/boost/asio/impl/write.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/write.ipp @@ -19,6 +19,7 @@ #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/base_from_completion_cond.hpp> #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/consuming_buffers.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> @@ -37,14 +38,14 @@ std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, boost::asio::detail::consuming_buffers< const_buffer, ConstBufferSequence> tmp(buffers); std::size_t total_transferred = 0; - tmp.set_max_size(detail::adapt_completion_condition_result( + tmp.prepare(detail::adapt_completion_condition_result( completion_condition(ec, total_transferred))); while (tmp.begin() != tmp.end()) { std::size_t bytes_transferred = s.write_some(tmp, ec); tmp.consume(bytes_transferred); total_transferred += bytes_transferred; - tmp.set_max_size(detail::adapt_completion_condition_result( + tmp.prepare(detail::adapt_completion_condition_result( completion_condition(ec, total_transferred))); } return total_transferred; @@ -111,51 +112,164 @@ namespace detail { template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> - class write_handler + class write_op + : detail::base_from_completion_cond<CompletionCondition> { public: - typedef boost::asio::detail::consuming_buffers< - const_buffer, ConstBufferSequence> buffers_type; - - write_handler(AsyncWriteStream& stream, const buffers_type& buffers, + write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, CompletionCondition completion_condition, WriteHandler handler) - : stream_(stream), + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), buffers_(buffers), total_transferred_(0), - completion_condition_(completion_condition), - handler_(handler) + handler_(handler), + start_(true) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + switch (start_) + { + case true: start_ = false; + buffers_.prepare(this->check(ec, total_transferred_)); + for (;;) + { + stream_.async_write_some(buffers_, *this); + return; default: + total_transferred_ += bytes_transferred; + buffers_.consume(bytes_transferred); + buffers_.prepare(this->check(ec, total_transferred_)); + if ((!ec && bytes_transferred == 0) + || buffers_.begin() == buffers_.end()) + break; + } + + handler_(ec, total_transferred_); + } + } + + //private: + AsyncWriteStream& stream_; + boost::asio::detail::consuming_buffers< + const_buffer, ConstBufferSequence> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + bool start_; + }; + + template <typename AsyncWriteStream, + typename CompletionCondition, typename WriteHandler> + class write_op<AsyncWriteStream, boost::asio::mutable_buffers_1, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_op(AsyncWriteStream& stream, + const boost::asio::mutable_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffer_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) { } void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred) { - total_transferred_ += bytes_transferred; - buffers_.consume(bytes_transferred); - buffers_.set_max_size(detail::adapt_completion_condition_result( - completion_condition_(ec, total_transferred_))); - if (buffers_.begin() == buffers_.end()) + std::size_t n = 0; + switch (start_) { + case true: start_ = false; + n = this->check(ec, total_transferred_); + for (;;) + { + stream_.async_write_some(boost::asio::buffer( + buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check(ec, total_transferred_)) == 0 + || total_transferred_ == boost::asio::buffer_size(buffer_)) + break; + } + handler_(ec, total_transferred_); } - else + } + + //private: + AsyncWriteStream& stream_; + boost::asio::mutable_buffer buffer_; + std::size_t total_transferred_; + WriteHandler handler_; + bool start_; + }; + + template <typename AsyncWriteStream, + typename CompletionCondition, typename WriteHandler> + class write_op<AsyncWriteStream, boost::asio::const_buffers_1, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_op(AsyncWriteStream& stream, + const boost::asio::const_buffers_1& buffers, + CompletionCondition completion_condition, + WriteHandler handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffer_(buffers), + total_transferred_(0), + handler_(handler), + start_(true) + { + } + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred) + { + std::size_t n = 0; + switch (start_) { - stream_.async_write_some(buffers_, *this); + case true: start_ = false; + n = this->check(ec, total_transferred_); + for (;;) + { + stream_.async_write_some(boost::asio::buffer( + buffer_ + total_transferred_, n), *this); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check(ec, total_transferred_)) == 0 + || total_transferred_ == boost::asio::buffer_size(buffer_)) + break; + } + + handler_(ec, total_transferred_); } } //private: AsyncWriteStream& stream_; - buffers_type buffers_; + boost::asio::const_buffer buffer_; std::size_t total_transferred_; - CompletionCondition completion_condition_; WriteHandler handler_; + bool start_; }; template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, - write_handler<AsyncWriteStream, ConstBufferSequence, + write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( @@ -165,7 +279,7 @@ namespace detail template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - write_handler<AsyncWriteStream, ConstBufferSequence, + write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( @@ -176,7 +290,7 @@ namespace detail typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void asio_handler_invoke(const Function& function, - write_handler<AsyncWriteStream, ConstBufferSequence, + write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( @@ -189,24 +303,10 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, WriteHandler handler) { - boost::asio::detail::consuming_buffers< - const_buffer, ConstBufferSequence> tmp(buffers); - - boost::system::error_code ec; - std::size_t total_transferred = 0; - tmp.set_max_size(detail::adapt_completion_condition_result( - completion_condition(ec, total_transferred))); - if (tmp.begin() == tmp.end()) - { - s.get_io_service().post(detail::bind_handler( - handler, ec, total_transferred)); - return; - } - - s.async_write_some(tmp, - detail::write_handler<AsyncWriteStream, ConstBufferSequence, - CompletionCondition, WriteHandler>( - s, tmp, completion_condition, handler)); + detail::write_op<AsyncWriteStream, ConstBufferSequence, + CompletionCondition, WriteHandler>( + s, buffers, completion_condition, handler)( + boost::system::error_code(), 0); } template <typename AsyncWriteStream, typename ConstBufferSequence, |