From a579568eda35c57c17bc9f029ca6215987ca496a Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Thu, 19 Sep 2013 22:25:32 +1000 Subject: [PATCH] Update buffered stream operations to adhere to current handler patterns. --- asio/include/asio/buffered_read_stream.hpp | 189 ++------- asio/include/asio/buffered_stream.hpp | 32 +- asio/include/asio/buffered_write_stream.hpp | 170 ++------- .../asio/impl/buffered_read_stream.hpp | 358 ++++++++++++++++++ .../asio/impl/buffered_write_stream.hpp | 335 ++++++++++++++++ asio/src/tests/unit/buffered_read_stream.cpp | 109 ++++++ asio/src/tests/unit/buffered_stream.cpp | 120 ++++++ asio/src/tests/unit/buffered_write_stream.cpp | 109 ++++++ 8 files changed, 1109 insertions(+), 313 deletions(-) create mode 100644 asio/include/asio/impl/buffered_read_stream.hpp create mode 100644 asio/include/asio/impl/buffered_write_stream.hpp diff --git a/asio/include/asio/buffered_read_stream.hpp b/asio/include/asio/buffered_read_stream.hpp index 5fe48581..f7507c05 100644 --- a/asio/include/asio/buffered_read_stream.hpp +++ b/asio/include/asio/buffered_read_stream.hpp @@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include +#include "asio/async_result.hpp" #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffer.hpp" #include "asio/detail/bind_handler.hpp" @@ -133,199 +134,65 @@ public: /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template - void async_write_some(const ConstBufferSequence& buffers, - WriteHandler handler) + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) { - next_layer_.async_write_some(buffers, handler); + detail::async_result_init< + WriteHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(WriteHandler)(handler)); + + next_layer_.async_write_some(buffers, + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(WriteHandler, + void (asio::error_code, std::size_t)))(init.handler)); + + return init.result.get(); } /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation. Throws an exception on failure. - std::size_t fill() - { - detail::buffer_resize_guard - resize_guard(storage_); - std::size_t previous_size = storage_.size(); - storage_.resize(storage_.capacity()); - storage_.resize(previous_size + next_layer_.read_some(buffer( - storage_.data() + previous_size, - storage_.size() - previous_size))); - resize_guard.commit(); - return storage_.size() - previous_size; - } + std::size_t fill(); /// Fill the buffer with some data. Returns the number of bytes placed in the /// buffer as a result of the operation, or 0 if an error occurred. - std::size_t fill(asio::error_code& ec) - { - detail::buffer_resize_guard - resize_guard(storage_); - std::size_t previous_size = storage_.size(); - storage_.resize(storage_.capacity()); - storage_.resize(previous_size + next_layer_.read_some(buffer( - storage_.data() + previous_size, - storage_.size() - previous_size), - ec)); - resize_guard.commit(); - return storage_.size() - previous_size; - } - - template - class fill_handler - { - public: - fill_handler(asio::io_service& io_service, - detail::buffered_stream_storage& storage, - std::size_t previous_size, ReadHandler handler) - : io_service_(io_service), - storage_(storage), - previous_size_(previous_size), - handler_(handler) - { - } - - void operator()(const asio::error_code& ec, - std::size_t bytes_transferred) - { - storage_.resize(previous_size_ + bytes_transferred); - io_service_.dispatch(detail::bind_handler( - handler_, ec, bytes_transferred)); - } - - private: - asio::io_service& io_service_; - detail::buffered_stream_storage& storage_; - std::size_t previous_size_; - ReadHandler handler_; - }; + std::size_t fill(asio::error_code& ec); /// Start an asynchronous fill. template - void async_fill(ReadHandler handler) - { - std::size_t previous_size = storage_.size(); - storage_.resize(storage_.capacity()); - next_layer_.async_read_some( - buffer( - storage_.data() + previous_size, - storage_.size() - previous_size), - fill_handler(get_io_service(), - storage_, previous_size, handler)); - } + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_fill(ASIO_MOVE_ARG(ReadHandler) handler); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure. template - std::size_t read_some(const MutableBufferSequence& buffers) - { - if (asio::buffer_size(buffers) == 0) - return 0; - - if (storage_.empty()) - fill(); - - return copy(buffers); - } + std::size_t read_some(const MutableBufferSequence& buffers); /// Read some data from the stream. Returns the number of bytes read or 0 if /// an error occurred. template std::size_t read_some(const MutableBufferSequence& buffers, - asio::error_code& ec) - { - ec = asio::error_code(); - - if (asio::buffer_size(buffers) == 0) - return 0; - - if (storage_.empty() && !fill(ec)) - return 0; - - return copy(buffers); - } - - template - class read_some_handler - { - public: - read_some_handler(asio::io_service& io_service, - detail::buffered_stream_storage& storage, - const MutableBufferSequence& buffers, ReadHandler handler) - : io_service_(io_service), - storage_(storage), - buffers_(buffers), - handler_(handler) - { - } - - void operator()(const asio::error_code& ec, std::size_t) - { - if (ec || storage_.empty()) - { - std::size_t length = 0; - io_service_.dispatch(detail::bind_handler(handler_, ec, length)); - } - else - { - std::size_t bytes_copied = asio::buffer_copy( - buffers_, storage_.data(), storage_.size()); - storage_.consume(bytes_copied); - io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); - } - } - - private: - asio::io_service& io_service_; - detail::buffered_stream_storage& storage_; - MutableBufferSequence buffers_; - ReadHandler handler_; - }; + asio::error_code& ec); /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template - void async_read_some(const MutableBufferSequence& buffers, - ReadHandler handler) - { - if (asio::buffer_size(buffers) == 0) - { - get_io_service().post(detail::bind_handler( - handler, asio::error_code(), 0)); - } - else if (storage_.empty()) - { - async_fill(read_some_handler( - get_io_service(), storage_, buffers, handler)); - } - else - { - std::size_t length = copy(buffers); - get_io_service().post(detail::bind_handler( - handler, asio::error_code(), length)); - } - } + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler); /// Peek at the incoming data on the stream. Returns the number of bytes read. /// Throws an exception on failure. template - std::size_t peek(const MutableBufferSequence& buffers) - { - if (storage_.empty()) - fill(); - return peek_copy(buffers); - } + std::size_t peek(const MutableBufferSequence& buffers); /// Peek at the incoming data on the stream. Returns the number of bytes read, /// or 0 if an error occurred. template std::size_t peek(const MutableBufferSequence& buffers, - asio::error_code& ec) - { - ec = asio::error_code(); - if (storage_.empty() && !fill(ec)) - return 0; - return peek_copy(buffers); - } + asio::error_code& ec); /// Determine the amount of data that may be read without blocking. std::size_t in_avail() @@ -372,4 +239,6 @@ private: #include "asio/detail/pop_options.hpp" +#include "asio/impl/buffered_read_stream.hpp" + #endif // ASIO_BUFFERED_READ_STREAM_HPP diff --git a/asio/include/asio/buffered_stream.hpp b/asio/include/asio/buffered_stream.hpp index 2a690ef0..29f42f8c 100644 --- a/asio/include/asio/buffered_stream.hpp +++ b/asio/include/asio/buffered_stream.hpp @@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include +#include "asio/async_result.hpp" #include "asio/buffered_read_stream.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffered_stream_fwd.hpp" @@ -122,9 +123,12 @@ public: /// Start an asynchronous flush. template - void async_flush(WriteHandler handler) + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_flush(ASIO_MOVE_ARG(WriteHandler) handler) { - return stream_impl_.next_layer().async_flush(handler); + return stream_impl_.next_layer().async_flush( + ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Write the given data to the stream. Returns the number of bytes written. @@ -147,10 +151,13 @@ public: /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template - void async_write_some(const ConstBufferSequence& buffers, - WriteHandler handler) + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) { - stream_impl_.async_write_some(buffers, handler); + return stream_impl_.async_write_some(buffers, + ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the @@ -169,9 +176,11 @@ public: /// Start an asynchronous fill. template - void async_fill(ReadHandler handler) + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_fill(ASIO_MOVE_ARG(ReadHandler) handler) { - stream_impl_.async_fill(handler); + return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Read some data from the stream. Returns the number of bytes read. Throws @@ -194,10 +203,13 @@ public: /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template - void async_read_some(const MutableBufferSequence& buffers, - ReadHandler handler) + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) { - stream_impl_.async_read_some(buffers, handler); + return stream_impl_.async_read_some(buffers, + ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Peek at the incoming data on the stream. Returns the number of bytes read. diff --git a/asio/include/asio/buffered_write_stream.hpp b/asio/include/asio/buffered_write_stream.hpp index 000f30db..c220323e 100644 --- a/asio/include/asio/buffered_write_stream.hpp +++ b/asio/include/asio/buffered_write_stream.hpp @@ -117,156 +117,37 @@ public: /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation. Throws an /// exception on failure. - std::size_t flush() - { - std::size_t bytes_written = write(next_layer_, - buffer(storage_.data(), storage_.size())); - storage_.consume(bytes_written); - return bytes_written; - } + std::size_t flush(); /// Flush all data from the buffer to the next layer. Returns the number of /// bytes written to the next layer on the last write operation, or 0 if an /// error occurred. - std::size_t flush(asio::error_code& ec) - { - std::size_t bytes_written = write(next_layer_, - buffer(storage_.data(), storage_.size()), - transfer_all(), ec); - storage_.consume(bytes_written); - return bytes_written; - } - - template - class flush_handler - { - public: - flush_handler(asio::io_service& io_service, - detail::buffered_stream_storage& storage, WriteHandler handler) - : io_service_(io_service), - storage_(storage), - handler_(handler) - { - } - - void operator()(const asio::error_code& ec, - std::size_t bytes_written) - { - storage_.consume(bytes_written); - io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_written)); - } - - private: - asio::io_service& io_service_; - detail::buffered_stream_storage& storage_; - WriteHandler handler_; - }; + std::size_t flush(asio::error_code& ec); /// Start an asynchronous flush. template - void async_flush(WriteHandler handler) - { - async_write(next_layer_, buffer(storage_.data(), storage_.size()), - flush_handler(get_io_service(), storage_, handler)); - } + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_flush(ASIO_MOVE_ARG(WriteHandler) handler); /// Write the given data to the stream. Returns the number of bytes written. /// Throws an exception on failure. template - std::size_t write_some(const ConstBufferSequence& buffers) - { - if (asio::buffer_size(buffers) == 0) - return 0; - - if (storage_.size() == storage_.capacity()) - flush(); - - return copy(buffers); - } + std::size_t write_some(const ConstBufferSequence& buffers); /// Write the given data to the stream. Returns the number of bytes written, /// or 0 if an error occurred and the error handler did not throw. template std::size_t write_some(const ConstBufferSequence& buffers, - asio::error_code& ec) - { - ec = asio::error_code(); - - if (asio::buffer_size(buffers) == 0) - return 0; - - if (storage_.size() == storage_.capacity() && !flush(ec)) - return 0; - - return copy(buffers); - } - - template - class write_some_handler - { - public: - write_some_handler(asio::io_service& io_service, - detail::buffered_stream_storage& storage, - const ConstBufferSequence& buffers, WriteHandler handler) - : io_service_(io_service), - storage_(storage), - buffers_(buffers), - handler_(handler) - { - } - - void operator()(const asio::error_code& ec, std::size_t) - { - if (ec) - { - std::size_t length = 0; - io_service_.dispatch(detail::bind_handler(handler_, ec, length)); - } - else - { - std::size_t orig_size = storage_.size(); - std::size_t space_avail = storage_.capacity() - orig_size; - std::size_t bytes_avail = asio::buffer_size(buffers_); - std::size_t length = bytes_avail < space_avail - ? bytes_avail : space_avail; - storage_.resize(orig_size + length); - std::size_t bytes_copied = asio::buffer_copy( - storage_.data() + orig_size, buffers_, length); - - io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); - } - } - - private: - asio::io_service& io_service_; - detail::buffered_stream_storage& storage_; - ConstBufferSequence buffers_; - WriteHandler handler_; - }; + asio::error_code& ec); /// Start an asynchronous write. The data being written must be valid for the /// lifetime of the asynchronous operation. template - void async_write_some(const ConstBufferSequence& buffers, - WriteHandler handler) - { - if (asio::buffer_size(buffers) == 0) - { - get_io_service().post(detail::bind_handler( - handler, asio::error_code(), 0)); - } - else if (storage_.size() == storage_.capacity()) - { - async_flush(write_some_handler( - get_io_service(), storage_, buffers, handler)); - } - else - { - std::size_t bytes_copied = copy(buffers); - get_io_service().post(detail::bind_handler( - handler, asio::error_code(), bytes_copied)); - } - } + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure. @@ -288,10 +169,20 @@ public: /// Start an asynchronous read. The buffer into which the data will be read /// must be valid for the lifetime of the asynchronous operation. template - void async_read_some(const MutableBufferSequence& buffers, - ReadHandler handler) + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) { - next_layer_.async_read_some(buffers, handler); + detail::async_result_init< + ReadHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(ReadHandler)(handler)); + + next_layer_.async_read_some(buffers, + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(ReadHandler, + void (asio::error_code, std::size_t)))(init.handler)); + + return init.result.get(); } /// Peek at the incoming data on the stream. Returns the number of bytes read. @@ -327,16 +218,7 @@ private: /// Copy data into the internal buffer from the specified source buffer. /// Returns the number of bytes copied. template - std::size_t copy(const ConstBufferSequence& buffers) - { - std::size_t orig_size = storage_.size(); - std::size_t space_avail = storage_.capacity() - orig_size; - std::size_t bytes_avail = asio::buffer_size(buffers); - std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; - storage_.resize(orig_size + length); - return asio::buffer_copy( - storage_.data() + orig_size, buffers, length); - } + std::size_t copy(const ConstBufferSequence& buffers); /// The next layer. Stream next_layer_; @@ -349,4 +231,6 @@ private: #include "asio/detail/pop_options.hpp" +#include "asio/impl/buffered_write_stream.hpp" + #endif // ASIO_BUFFERED_WRITE_STREAM_HPP diff --git a/asio/include/asio/impl/buffered_read_stream.hpp b/asio/include/asio/impl/buffered_read_stream.hpp new file mode 100644 index 00000000..1d10995d --- /dev/null +++ b/asio/include/asio/impl/buffered_read_stream.hpp @@ -0,0 +1,358 @@ +// +// impl/buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IMPL_BUFFERED_READ_STREAM_HPP +#define ASIO_IMPL_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +std::size_t buffered_read_stream::fill() +{ + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size))); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +template +std::size_t buffered_read_stream::fill(asio::error_code& ec) +{ + detail::buffer_resize_guard + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + ec)); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +namespace detail +{ + template + class buffered_fill_handler + { + public: + buffered_fill_handler(detail::buffered_stream_storage& storage, + std::size_t previous_size, ReadHandler& handler) + : storage_(storage), + previous_size_(previous_size), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_fill_handler(const buffered_fill_handler& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(other.handler_) + { + } + + buffered_fill_handler(buffered_fill_handler&& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_transferred) + { + storage_.resize(previous_size_ + bytes_transferred); + handler_(ec, bytes_transferred); + } + + //private: + detail::buffered_stream_storage& storage_; + std::size_t previous_size_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_fill_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_fill_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_fill_handler* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_fill_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_fill_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream::async_fill( + ASIO_MOVE_ARG(ReadHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::async_result_init< + ReadHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(ReadHandler)(handler)); + + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + next_layer_.async_read_some( + buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + detail::buffered_fill_handler( + storage_, previous_size, init.handler)); + + return init.result.get(); +} + +template +template +std::size_t buffered_read_stream::read_some( + const MutableBufferSequence& buffers) +{ + if (asio::buffer_size(buffers) == 0) + return 0; + + if (storage_.empty()) + this->fill(); + + return this->copy(buffers); +} + +template +template +std::size_t buffered_read_stream::read_some( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + + if (asio::buffer_size(buffers) == 0) + return 0; + + if (storage_.empty() && !this->fill(ec)) + return 0; + + return this->copy(buffers); +} + +namespace detail +{ + template + class buffered_read_some_handler + { + public: + buffered_read_some_handler(detail::buffered_stream_storage& storage, + const MutableBufferSequence& buffers, ReadHandler& handler) + : storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_read_some_handler(const buffered_read_some_handler& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(other.handler_) + { + } + + buffered_read_some_handler(buffered_read_some_handler&& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec || storage_.empty()) + { + const std::size_t length = 0; + handler_(ec, length); + } + else + { + const std::size_t bytes_copied = asio::buffer_copy( + buffers_, storage_.data(), storage_.size()); + storage_.consume(bytes_copied); + handler_(ec, bytes_copied); + } + } + + //private: + detail::buffered_stream_storage& storage_; + MutableBufferSequence buffers_; + ReadHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +template +ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream::async_read_some( + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::async_result_init< + ReadHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(ReadHandler)(handler)); + + if (asio::buffer_size(buffers) == 0 || !storage_.empty()) + { + next_layer_.async_read_some(asio::mutable_buffers_1(0, 0), + detail::buffered_read_some_handler< + MutableBufferSequence, ASIO_HANDLER_TYPE( + ReadHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.handler)); + } + else + { + this->async_fill(detail::buffered_read_some_handler< + MutableBufferSequence, ASIO_HANDLER_TYPE( + ReadHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.handler)); + } + + return init.result.get(); +} + +template +template +std::size_t buffered_read_stream::peek( + const MutableBufferSequence& buffers) +{ + if (storage_.empty()) + this->fill(); + return this->peek_copy(buffers); +} + +template +template +std::size_t buffered_read_stream::peek( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + if (storage_.empty() && !this->fill(ec)) + return 0; + return this->peek_copy(buffers); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_BUFFERED_READ_STREAM_HPP diff --git a/asio/include/asio/impl/buffered_write_stream.hpp b/asio/include/asio/impl/buffered_write_stream.hpp new file mode 100644 index 00000000..62adfa54 --- /dev/null +++ b/asio/include/asio/impl/buffered_write_stream.hpp @@ -0,0 +1,335 @@ +// +// impl/buffered_write_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP +#define ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template +std::size_t buffered_write_stream::flush() +{ + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size())); + storage_.consume(bytes_written); + return bytes_written; +} + +template +std::size_t buffered_write_stream::flush(asio::error_code& ec) +{ + std::size_t bytes_written = write(next_layer_, + buffer(storage_.data(), storage_.size()), + transfer_all(), ec); + storage_.consume(bytes_written); + return bytes_written; +} + +namespace detail +{ + template + class buffered_flush_handler + { + public: + buffered_flush_handler(detail::buffered_stream_storage& storage, + WriteHandler& handler) + : storage_(storage), + handler_(handler) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_flush_handler(const buffered_flush_handler& other) + : storage_(other.storage_), + handler_(other.handler_) + { + } + + buffered_flush_handler(buffered_flush_handler&& other) + : storage_(other.storage_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_written) + { + storage_.consume(bytes_written); + handler_(ec, bytes_written); + } + + //private: + detail::buffered_stream_storage& storage_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_flush_handler* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_flush_handler* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_flush_handler* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_flush_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_flush_handler* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} + +template +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +buffered_write_stream::async_flush( + ASIO_MOVE_ARG(WriteHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::async_result_init< + WriteHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(WriteHandler)(handler)); + + async_write(next_layer_, buffer(storage_.data(), storage_.size()), + detail::buffered_flush_handler( + storage_, init.handler)); + + return init.result.get(); +} + +template +template +std::size_t buffered_write_stream::write_some(const ConstBufferSequence& buffers) +{ + if (asio::buffer_size(buffers) == 0) + return 0; + + if (storage_.size() == storage_.capacity()) + this->flush(); + + return this->copy(buffers); +} + +template +template +std::size_t buffered_write_stream::write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) +{ + ec = asio::error_code(); + + if (asio::buffer_size(buffers) == 0) + return 0; + + if (storage_.size() == storage_.capacity() && !flush(ec)) + return 0; + + return this->copy(buffers); +} + +namespace detail +{ + template + class buffered_write_some_handler + { + public: + buffered_write_some_handler(detail::buffered_stream_storage& storage, + const ConstBufferSequence& buffers, WriteHandler& handler) + : storage_(storage), + buffers_(buffers), + handler_(handler) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_write_some_handler(const buffered_write_some_handler& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(other.handler_) + { + } + + buffered_write_some_handler(buffered_write_some_handler&& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec) + { + const std::size_t length = 0; + handler_(ec, length); + } + else + { + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_avail = asio::buffer_size(buffers_); + std::size_t length = bytes_avail < space_avail + ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + const std::size_t bytes_copied = asio::buffer_copy( + storage_.data() + orig_size, buffers_, length); + handler_(ec, bytes_copied); + } + } + + //private: + detail::buffered_stream_storage& storage_; + ConstBufferSequence buffers_; + WriteHandler handler_; + }; + + template + inline void* asio_handler_allocate(std::size_t size, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template + inline void asio_handler_deallocate(void* pointer, std::size_t size, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template + inline bool asio_handler_is_continuation( + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template + inline void asio_handler_invoke(Function& function, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template + inline void asio_handler_invoke(const Function& function, + buffered_write_some_handler< + ConstBufferSequence, WriteHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } +} // namespace detail + +template +template +ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) +buffered_write_stream::async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::async_result_init< + WriteHandler, void (asio::error_code, std::size_t)> init( + ASIO_MOVE_CAST(WriteHandler)(handler)); + + if (asio::buffer_size(buffers) == 0 + || storage_.size() < storage_.capacity()) + { + next_layer_.async_write_some(asio::const_buffers_1(0, 0), + detail::buffered_write_some_handler< + ConstBufferSequence, ASIO_HANDLER_TYPE( + WriteHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.handler)); + } + else + { + this->async_flush(detail::buffered_write_some_handler< + ConstBufferSequence, ASIO_HANDLER_TYPE( + WriteHandler, void (asio::error_code, std::size_t))>( + storage_, buffers, init.handler)); + } + + return init.result.get(); +} + +template +template +std::size_t buffered_write_stream::copy(const ConstBufferSequence& buffers) +{ + std::size_t orig_size = storage_.size(); + std::size_t space_avail = storage_.capacity() - orig_size; + std::size_t bytes_avail = asio::buffer_size(buffers); + std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + return asio::buffer_copy( + storage_.data() + orig_size, buffers, length); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP diff --git a/asio/src/tests/unit/buffered_read_stream.cpp b/asio/src/tests/unit/buffered_read_stream.cpp index 1799b8e1..24ab42b1 100644 --- a/asio/src/tests/unit/buffered_read_stream.cpp +++ b/asio/src/tests/unit/buffered_read_stream.cpp @@ -17,12 +17,19 @@ #include "asio/buffered_read_stream.hpp" #include +#include "archetypes/async_result.hpp" #include "asio/buffer.hpp" #include "asio/io_service.hpp" #include "asio/ip/tcp.hpp" #include "asio/system_error.hpp" #include "unit_test.hpp" +#if defined(ASIO_HAS_BOOST_ARRAY) +# include +#else // defined(ASIO_HAS_BOOST_ARRAY) +# include +#endif // defined(ASIO_HAS_BOOST_ARRAY) + #if defined(ASIO_HAS_BOOST_BIND) # include #else // defined(ASIO_HAS_BOOST_BIND) @@ -32,6 +39,107 @@ typedef asio::buffered_read_stream< asio::ip::tcp::socket> stream_type; +void write_some_handler(const asio::error_code&, std::size_t) +{ +} + +void fill_handler(const asio::error_code&, std::size_t) +{ +} + +void read_some_handler(const asio::error_code&, std::size_t) +{ +} + +void test_compile() +{ +#if defined(ASIO_HAS_BOOST_ARRAY) + using boost::array; +#else // defined(ASIO_HAS_BOOST_ARRAY) + using std::array; +#endif // defined(ASIO_HAS_BOOST_ARRAY) + + using namespace asio; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + array mutable_buffers = {{ + asio::buffer(mutable_char_buffer, 10), + asio::buffer(mutable_char_buffer + 10, 10) }}; + array const_buffers = {{ + asio::buffer(const_char_buffer, 10), + asio::buffer(const_char_buffer + 10, 10) }}; + archetypes::lazy_handler lazy; + asio::error_code ec; + + stream_type stream1(ios); + stream_type stream2(ios, 1024); + + io_service& ios_ref = stream1.get_io_service(); + (void)ios_ref; + + stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer(); + (void)lowest_layer; + + stream1.write_some(buffer(mutable_char_buffer)); + stream1.write_some(buffer(const_char_buffer)); + stream1.write_some(mutable_buffers); + stream1.write_some(const_buffers); + stream1.write_some(null_buffers()); + stream1.write_some(buffer(mutable_char_buffer), ec); + stream1.write_some(buffer(const_char_buffer), ec); + stream1.write_some(mutable_buffers, ec); + stream1.write_some(const_buffers, ec); + stream1.write_some(null_buffers(), ec); + + stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler); + stream1.async_write_some(buffer(const_char_buffer), &write_some_handler); + stream1.async_write_some(mutable_buffers, &write_some_handler); + stream1.async_write_some(const_buffers, &write_some_handler); + stream1.async_write_some(null_buffers(), &write_some_handler); + int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy); + (void)i1; + int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy); + (void)i2; + int i3 = stream1.async_write_some(mutable_buffers, lazy); + (void)i3; + int i4 = stream1.async_write_some(const_buffers, lazy); + (void)i4; + int i5 = stream1.async_write_some(null_buffers(), lazy); + (void)i5; + + stream1.fill(); + stream1.fill(ec); + + stream1.async_fill(&fill_handler); + int i6 = stream1.async_fill(lazy); + (void)i6; + + stream1.read_some(buffer(mutable_char_buffer)); + stream1.read_some(mutable_buffers); + stream1.read_some(null_buffers()); + stream1.read_some(buffer(mutable_char_buffer), ec); + stream1.read_some(mutable_buffers, ec); + stream1.read_some(null_buffers(), ec); + + stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler); + stream1.async_read_some(mutable_buffers, &read_some_handler); + stream1.async_read_some(null_buffers(), &read_some_handler); + int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy); + (void)i7; + int i8 = stream1.async_read_some(mutable_buffers, lazy); + (void)i8; + int i9 = stream1.async_read_some(null_buffers(), lazy); + (void)i9; + } + catch (std::exception&) + { + } +} + void test_sync_operations() { using namespace std; // For memcmp. @@ -224,6 +332,7 @@ void test_async_operations() ASIO_TEST_SUITE ( "buffered_read_stream", + ASIO_TEST_CASE(test_compile) ASIO_TEST_CASE(test_sync_operations) ASIO_TEST_CASE(test_async_operations) ) diff --git a/asio/src/tests/unit/buffered_stream.cpp b/asio/src/tests/unit/buffered_stream.cpp index c2e606fd..bcb6c216 100644 --- a/asio/src/tests/unit/buffered_stream.cpp +++ b/asio/src/tests/unit/buffered_stream.cpp @@ -17,12 +17,19 @@ #include "asio/buffered_stream.hpp" #include +#include "archetypes/async_result.hpp" #include "asio/buffer.hpp" #include "asio/io_service.hpp" #include "asio/ip/tcp.hpp" #include "asio/system_error.hpp" #include "unit_test.hpp" +#if defined(ASIO_HAS_BOOST_ARRAY) +# include +#else // defined(ASIO_HAS_BOOST_ARRAY) +# include +#endif // defined(ASIO_HAS_BOOST_ARRAY) + #if defined(ASIO_HAS_BOOST_BIND) # include #else // defined(ASIO_HAS_BOOST_BIND) @@ -32,6 +39,118 @@ typedef asio::buffered_stream< asio::ip::tcp::socket> stream_type; +void write_some_handler(const asio::error_code&, std::size_t) +{ +} + +void flush_handler(const asio::error_code&, std::size_t) +{ +} + +void fill_handler(const asio::error_code&, std::size_t) +{ +} + +void read_some_handler(const asio::error_code&, std::size_t) +{ +} + +void test_compile() +{ +#if defined(ASIO_HAS_BOOST_ARRAY) + using boost::array; +#else // defined(ASIO_HAS_BOOST_ARRAY) + using std::array; +#endif // defined(ASIO_HAS_BOOST_ARRAY) + + using namespace asio; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + array mutable_buffers = {{ + asio::buffer(mutable_char_buffer, 10), + asio::buffer(mutable_char_buffer + 10, 10) }}; + array const_buffers = {{ + asio::buffer(const_char_buffer, 10), + asio::buffer(const_char_buffer + 10, 10) }}; + archetypes::lazy_handler lazy; + asio::error_code ec; + + stream_type stream1(ios); + stream_type stream2(ios, 1024, 1024); + + io_service& ios_ref = stream1.get_io_service(); + (void)ios_ref; + + stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer(); + (void)lowest_layer; + + stream1.write_some(buffer(mutable_char_buffer)); + stream1.write_some(buffer(const_char_buffer)); + stream1.write_some(mutable_buffers); + stream1.write_some(const_buffers); + stream1.write_some(null_buffers()); + stream1.write_some(buffer(mutable_char_buffer), ec); + stream1.write_some(buffer(const_char_buffer), ec); + stream1.write_some(mutable_buffers, ec); + stream1.write_some(const_buffers, ec); + stream1.write_some(null_buffers(), ec); + + stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler); + stream1.async_write_some(buffer(const_char_buffer), &write_some_handler); + stream1.async_write_some(mutable_buffers, &write_some_handler); + stream1.async_write_some(const_buffers, &write_some_handler); + stream1.async_write_some(null_buffers(), &write_some_handler); + int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy); + (void)i1; + int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy); + (void)i2; + int i3 = stream1.async_write_some(mutable_buffers, lazy); + (void)i3; + int i4 = stream1.async_write_some(const_buffers, lazy); + (void)i4; + int i5 = stream1.async_write_some(null_buffers(), lazy); + (void)i5; + + stream1.flush(); + stream1.flush(ec); + + stream1.async_flush(&flush_handler); + int i6 = stream1.async_flush(lazy); + (void)i6; + + stream1.fill(); + stream1.fill(ec); + + stream1.async_fill(&fill_handler); + int i7 = stream1.async_fill(lazy); + (void)i7; + + stream1.read_some(buffer(mutable_char_buffer)); + stream1.read_some(mutable_buffers); + stream1.read_some(null_buffers()); + stream1.read_some(buffer(mutable_char_buffer), ec); + stream1.read_some(mutable_buffers, ec); + stream1.read_some(null_buffers(), ec); + + stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler); + stream1.async_read_some(mutable_buffers, &read_some_handler); + stream1.async_read_some(null_buffers(), &read_some_handler); + int i8 = stream1.async_read_some(buffer(mutable_char_buffer), lazy); + (void)i8; + int i9 = stream1.async_read_some(mutable_buffers, lazy); + (void)i9; + int i10 = stream1.async_read_some(null_buffers(), lazy); + (void)i10; + } + catch (std::exception&) + { + } +} + void test_sync_operations() { using namespace std; // For memcmp. @@ -239,6 +358,7 @@ void test_async_operations() ASIO_TEST_SUITE ( "buffered_stream", + ASIO_TEST_CASE(test_compile) ASIO_TEST_CASE(test_sync_operations) ASIO_TEST_CASE(test_async_operations) ) diff --git a/asio/src/tests/unit/buffered_write_stream.cpp b/asio/src/tests/unit/buffered_write_stream.cpp index 799c832b..e936095e 100644 --- a/asio/src/tests/unit/buffered_write_stream.cpp +++ b/asio/src/tests/unit/buffered_write_stream.cpp @@ -17,12 +17,19 @@ #include "asio/buffered_write_stream.hpp" #include +#include "archetypes/async_result.hpp" #include "asio/buffer.hpp" #include "asio/io_service.hpp" #include "asio/ip/tcp.hpp" #include "asio/system_error.hpp" #include "unit_test.hpp" +#if defined(ASIO_HAS_BOOST_ARRAY) +# include +#else // defined(ASIO_HAS_BOOST_ARRAY) +# include +#endif // defined(ASIO_HAS_BOOST_ARRAY) + #if defined(ASIO_HAS_BOOST_BIND) # include #else // defined(ASIO_HAS_BOOST_BIND) @@ -32,6 +39,107 @@ typedef asio::buffered_write_stream< asio::ip::tcp::socket> stream_type; +void write_some_handler(const asio::error_code&, std::size_t) +{ +} + +void flush_handler(const asio::error_code&, std::size_t) +{ +} + +void read_some_handler(const asio::error_code&, std::size_t) +{ +} + +void test_compile() +{ +#if defined(ASIO_HAS_BOOST_ARRAY) + using boost::array; +#else // defined(ASIO_HAS_BOOST_ARRAY) + using std::array; +#endif // defined(ASIO_HAS_BOOST_ARRAY) + + using namespace asio; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + array mutable_buffers = {{ + asio::buffer(mutable_char_buffer, 10), + asio::buffer(mutable_char_buffer + 10, 10) }}; + array const_buffers = {{ + asio::buffer(const_char_buffer, 10), + asio::buffer(const_char_buffer + 10, 10) }}; + archetypes::lazy_handler lazy; + asio::error_code ec; + + stream_type stream1(ios); + stream_type stream2(ios, 1024); + + io_service& ios_ref = stream1.get_io_service(); + (void)ios_ref; + + stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer(); + (void)lowest_layer; + + stream1.write_some(buffer(mutable_char_buffer)); + stream1.write_some(buffer(const_char_buffer)); + stream1.write_some(mutable_buffers); + stream1.write_some(const_buffers); + stream1.write_some(null_buffers()); + stream1.write_some(buffer(mutable_char_buffer), ec); + stream1.write_some(buffer(const_char_buffer), ec); + stream1.write_some(mutable_buffers, ec); + stream1.write_some(const_buffers, ec); + stream1.write_some(null_buffers(), ec); + + stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler); + stream1.async_write_some(buffer(const_char_buffer), &write_some_handler); + stream1.async_write_some(mutable_buffers, &write_some_handler); + stream1.async_write_some(const_buffers, &write_some_handler); + stream1.async_write_some(null_buffers(), &write_some_handler); + int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy); + (void)i1; + int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy); + (void)i2; + int i3 = stream1.async_write_some(mutable_buffers, lazy); + (void)i3; + int i4 = stream1.async_write_some(const_buffers, lazy); + (void)i4; + int i5 = stream1.async_write_some(null_buffers(), lazy); + (void)i5; + + stream1.flush(); + stream1.flush(ec); + + stream1.async_flush(&flush_handler); + int i6 = stream1.async_flush(lazy); + (void)i6; + + stream1.read_some(buffer(mutable_char_buffer)); + stream1.read_some(mutable_buffers); + stream1.read_some(null_buffers()); + stream1.read_some(buffer(mutable_char_buffer), ec); + stream1.read_some(mutable_buffers, ec); + stream1.read_some(null_buffers(), ec); + + stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler); + stream1.async_read_some(mutable_buffers, &read_some_handler); + stream1.async_read_some(null_buffers(), &read_some_handler); + int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy); + (void)i7; + int i8 = stream1.async_read_some(mutable_buffers, lazy); + (void)i8; + int i9 = stream1.async_read_some(null_buffers(), lazy); + (void)i9; + } + catch (std::exception&) + { + } +} + void test_sync_operations() { using namespace std; // For memcmp. @@ -239,6 +347,7 @@ void test_async_operations() ASIO_TEST_SUITE ( "buffered_write_stream", + ASIO_TEST_CASE(test_compile) ASIO_TEST_CASE(test_sync_operations) ASIO_TEST_CASE(test_async_operations) )