diff options
Diffstat (limited to '3rdParty/Boost/src/boost/asio/impl')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/connect.hpp | 391 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/error.ipp | 28 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/io_service.hpp | 53 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/io_service.ipp | 30 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/read.hpp | 366 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/read_at.hpp | 387 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/read_until.hpp | 288 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp | 2 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp | 2 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/write.hpp | 397 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/impl/write_at.hpp | 414 |
11 files changed, 2106 insertions, 252 deletions
diff --git a/3rdParty/Boost/src/boost/asio/impl/connect.hpp b/3rdParty/Boost/src/boost/asio/impl/connect.hpp new file mode 100644 index 0000000..a21bb2d --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/impl/connect.hpp @@ -0,0 +1,391 @@ +// +// impl/connect.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2012 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 BOOST_ASIO_IMPL_CONNECT_HPP +#define BOOST_ASIO_IMPL_CONNECT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/consuming_buffers.hpp> +#include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> +#include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { + +namespace detail +{ + struct default_connect_condition + { + template <typename Iterator> + Iterator operator()(const boost::system::error_code&, Iterator next) + { + return next; + } + }; +} + +template <typename Protocol, typename SocketService, typename Iterator> +Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin) +{ + boost::system::error_code ec; + Iterator result = connect(s, begin, ec); + boost::asio::detail::throw_error(ec, "connect"); + return result; +} + +template <typename Protocol, typename SocketService, typename Iterator> +inline Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, boost::system::error_code& ec) +{ + return connect(s, begin, Iterator(), detail::default_connect_condition(), ec); +} + +template <typename Protocol, typename SocketService, typename Iterator> +Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end) +{ + boost::system::error_code ec; + Iterator result = connect(s, begin, end, ec); + boost::asio::detail::throw_error(ec, "connect"); + return result; +} + +template <typename Protocol, typename SocketService, typename Iterator> +inline Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end, boost::system::error_code& ec) +{ + return connect(s, begin, end, detail::default_connect_condition(), ec); +} + +template <typename Protocol, typename SocketService, + typename Iterator, typename ConnectCondition> +Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, ConnectCondition connect_condition) +{ + boost::system::error_code ec; + Iterator result = connect(s, begin, connect_condition, ec); + boost::asio::detail::throw_error(ec, "connect"); + return result; +} + +template <typename Protocol, typename SocketService, + typename Iterator, typename ConnectCondition> +inline Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, ConnectCondition connect_condition, + boost::system::error_code& ec) +{ + return connect(s, begin, Iterator(), connect_condition, ec); +} + +template <typename Protocol, typename SocketService, + typename Iterator, typename ConnectCondition> +Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end, ConnectCondition connect_condition) +{ + boost::system::error_code ec; + Iterator result = connect(s, begin, end, connect_condition, ec); + boost::asio::detail::throw_error(ec, "connect"); + return result; +} + +template <typename Protocol, typename SocketService, + typename Iterator, typename ConnectCondition> +Iterator connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + boost::system::error_code& ec) +{ + ec = boost::system::error_code(); + + for (Iterator iter = begin; iter != end; ++iter) + { + iter = connect_condition(ec, iter); + if (iter != end) + { + s.close(ec); + s.connect(*iter, ec); + if (!ec) + return iter; + } + } + + if (!ec) + ec = boost::asio::error::not_found; + + return end; +} + +namespace detail +{ + // Enable the empty base class optimisation for the connect condition. + template <typename ConnectCondition> + class base_from_connect_condition + { + protected: + explicit base_from_connect_condition( + const ConnectCondition& connect_condition) + : connect_condition_(connect_condition) + { + } + + template <typename Iterator> + void check_condition(const boost::system::error_code& ec, + Iterator& iter, Iterator& end) + { + if (iter != end) + iter = connect_condition_(ec, static_cast<const Iterator&>(iter)); + } + + private: + ConnectCondition connect_condition_; + }; + + // The default_connect_condition implementation is essentially a no-op. This + // template specialisation lets us eliminate all costs associated with it. + template <> + class base_from_connect_condition<default_connect_condition> + { + protected: + explicit base_from_connect_condition(const default_connect_condition&) + { + } + + template <typename Iterator> + void check_condition(const boost::system::error_code&, Iterator&, Iterator&) + { + } + }; + + template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + class connect_op : base_from_connect_condition<ConnectCondition> + { + public: + connect_op(basic_socket<Protocol, SocketService>& sock, + const Iterator& begin, const Iterator& end, + const ConnectCondition& connect_condition, + ComposedConnectHandler& handler) + : base_from_connect_condition<ConnectCondition>(connect_condition), + socket_(sock), + iter_(begin), + end_(end), + handler_(BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + connect_op(const connect_op& other) + : base_from_connect_condition<ConnectCondition>(other), + socket_(other.socket_), + iter_(other.iter_), + end_(other.end_), + handler_(other.handler_) + { + } + + connect_op(connect_op&& other) + : base_from_connect_condition<ConnectCondition>(other), + socket_(other.socket_), + iter_(other.iter_), + end_(other.end_), + handler_(BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(boost::system::error_code ec, int start = 0) + { + switch (start) + { + case 1: + for (;;) + { + this->check_condition(ec, iter_, end_); + + if (iter_ != end_) + { + socket_.close(ec); + socket_.async_connect(*iter_, + BOOST_ASIO_MOVE_CAST(connect_op)(*this)); + return; + } + + if (start) + { + ec = boost::asio::error::not_found; + socket_.get_io_service().post(detail::bind_handler(*this, ec)); + return; + } + + default: + + if (iter_ == end_) + break; + + if (!socket_.is_open()) + { + ec = boost::asio::error::operation_aborted; + break; + } + + if (!ec) + break; + + ++iter_; + } + + handler_(static_cast<const boost::system::error_code&>(ec), + static_cast<const Iterator&>(iter_)); + } + } + + //private: + basic_socket<Protocol, SocketService>& socket_; + Iterator iter_; + Iterator end_; + ComposedConnectHandler handler_; + }; + + template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + inline void* asio_handler_allocate(std::size_t size, + connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler>* this_handler) + { + return boost_asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); + } + + template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + inline void asio_handler_deallocate(void* pointer, std::size_t size, + connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler>* this_handler) + { + boost_asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); + } + + template <typename Function, typename Protocol, + typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + inline void asio_handler_invoke(Function& function, + connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename Protocol, + typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + inline void asio_handler_invoke(const Function& function, + connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> + inline connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler> + make_connect_op(basic_socket<Protocol, SocketService>& sock, + const Iterator& begin, const Iterator& end, + const ConnectCondition& connect_condition, + ComposedConnectHandler handler) + { + return connect_op<Protocol, SocketService, Iterator, + ConnectCondition, ComposedConnectHandler>( + sock, begin, end, connect_condition, handler); + } +} // namespace detail + +template <typename Protocol, typename SocketService, + typename Iterator, typename ComposedConnectHandler> +inline void async_connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ComposedConnectHandler. + BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( + ComposedConnectHandler, handler, Iterator) type_check; + + detail::make_connect_op(s, begin, Iterator(), + detail::default_connect_condition(), + BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(handler))( + boost::system::error_code(), 1); +} + +template <typename Protocol, typename SocketService, + typename Iterator, typename ComposedConnectHandler> +inline void async_connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end, + BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ComposedConnectHandler. + BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( + ComposedConnectHandler, handler, Iterator) type_check; + + detail::make_connect_op(s, begin, end, + detail::default_connect_condition(), + BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(handler))( + boost::system::error_code(), 1); +} + +template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> +inline void async_connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, ConnectCondition connect_condition, + BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ComposedConnectHandler. + BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( + ComposedConnectHandler, handler, Iterator) type_check; + + detail::make_connect_op(s, begin, Iterator(), connect_condition, + BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(handler))( + boost::system::error_code(), 1); +} + +template <typename Protocol, typename SocketService, typename Iterator, + typename ConnectCondition, typename ComposedConnectHandler> +void async_connect(basic_socket<Protocol, SocketService>& s, + Iterator begin, Iterator end, ConnectCondition connect_condition, + BOOST_ASIO_MOVE_ARG(ComposedConnectHandler) handler) +{ + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ComposedConnectHandler. + BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( + ComposedConnectHandler, handler, Iterator) type_check; + + detail::make_connect_op(s, begin, end, connect_condition, + BOOST_ASIO_MOVE_CAST(ComposedConnectHandler)(handler))( + boost::system::error_code(), 1); +} + +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // BOOST_ASIO_IMPL_CONNECT_HPP diff --git a/3rdParty/Boost/src/boost/asio/impl/error.ipp b/3rdParty/Boost/src/boost/asio/impl/error.ipp index 7c045c0..cfb7a99 100644 --- a/3rdParty/Boost/src/boost/asio/impl/error.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/error.ipp @@ -2,7 +2,7 @@ // impl/error.ipp // ~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -16,8 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> -#include <boost/cerrno.hpp> -#include <boost/system/error_code.hpp> #include <boost/asio/error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -122,30 +120,6 @@ const boost::system::error_category& get_misc_category() return instance; } -namespace detail { - -class ssl_category : public boost::system::error_category -{ -public: - const char* name() const - { - return "asio.ssl"; - } - - std::string message(int) const - { - return "asio.ssl error"; - } -}; - -} // namespace detail - -const boost::system::error_category& get_ssl_category() -{ - static detail::ssl_category instance; - return instance; -} - } // namespace error } // namespace asio } // namespace boost diff --git a/3rdParty/Boost/src/boost/asio/impl/io_service.hpp b/3rdParty/Boost/src/boost/asio/impl/io_service.hpp index 152f983..510de0e 100644 --- a/3rdParty/Boost/src/boost/asio/impl/io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/io_service.hpp @@ -2,7 +2,7 @@ // impl/io_service.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -15,6 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/service_registry.hpp> #include <boost/asio/detail/push_options.hpp> @@ -32,6 +33,13 @@ inline Service& use_service(io_service& ios) return ios.service_registry_->template use_service<Service>(); } +template <> +inline detail::io_service_impl& use_service<detail::io_service_impl>( + io_service& ios) +{ + return ios.impl_; +} + template <typename Service> inline void add_service(io_service& ios, Service* svc) { @@ -68,16 +76,25 @@ inline bool has_service(io_service& ios) namespace boost { namespace asio { -template <typename Handler> -inline void io_service::dispatch(Handler handler) +template <typename CompletionHandler> +inline void io_service::dispatch( + BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) { - impl_.dispatch(handler); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a CompletionHandler. + BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check; + + impl_.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); } -template <typename Handler> -inline void io_service::post(Handler handler) +template <typename CompletionHandler> +inline void io_service::post(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) { - impl_.post(handler); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a CompletionHandler. + BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check; + + impl_.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); } template <typename Handler> @@ -92,35 +109,25 @@ io_service::wrap(Handler handler) } inline io_service::work::work(boost::asio::io_service& io_service) - : io_service_(io_service) + : io_service_impl_(io_service.impl_) { - io_service_.impl_.work_started(); + io_service_impl_.work_started(); } inline io_service::work::work(const work& other) - : io_service_(other.io_service_) + : io_service_impl_(other.io_service_impl_) { - io_service_.impl_.work_started(); + io_service_impl_.work_started(); } inline io_service::work::~work() { - io_service_.impl_.work_finished(); -} - -inline boost::asio::io_service& io_service::work::io_service() -{ - return io_service_; + io_service_impl_.work_finished(); } inline boost::asio::io_service& io_service::work::get_io_service() { - return io_service_; -} - -inline boost::asio::io_service& io_service::service::io_service() -{ - return owner_; + return io_service_impl_.get_io_service(); } inline boost::asio::io_service& io_service::service::get_io_service() diff --git a/3rdParty/Boost/src/boost/asio/impl/io_service.ipp b/3rdParty/Boost/src/boost/asio/impl/io_service.ipp index a0b34af..1e3af48 100644 --- a/3rdParty/Boost/src/boost/asio/impl/io_service.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/io_service.ipp @@ -2,7 +2,7 @@ // impl/io_service.ipp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -18,6 +18,7 @@ #include <boost/asio/detail/config.hpp> #include <boost/limits.hpp> #include <boost/asio/io_service.hpp> +#include <boost/asio/detail/scoped_ptr.hpp> #include <boost/asio/detail/service_registry.hpp> #include <boost/asio/detail/throw_error.hpp> @@ -33,17 +34,18 @@ namespace boost { namespace asio { io_service::io_service() - : service_registry_(new boost::asio::detail::service_registry(*this)), - impl_(service_registry_->use_service<impl_type>()) + : service_registry_(new boost::asio::detail::service_registry( + *this, static_cast<impl_type*>(0), + (std::numeric_limits<std::size_t>::max)())), + impl_(service_registry_->first_service<impl_type>()) { - impl_.init((std::numeric_limits<std::size_t>::max)()); } io_service::io_service(std::size_t concurrency_hint) - : service_registry_(new boost::asio::detail::service_registry(*this)), - impl_(service_registry_->use_service<impl_type>()) + : service_registry_(new boost::asio::detail::service_registry( + *this, static_cast<impl_type*>(0), concurrency_hint)), + impl_(service_registry_->first_service<impl_type>()) { - impl_.init(concurrency_hint); } io_service::~io_service() @@ -108,11 +110,21 @@ void io_service::stop() impl_.stop(); } +bool io_service::stopped() const +{ + return impl_.stopped(); +} + void io_service::reset() { impl_.reset(); } +void io_service::notify_fork(boost::asio::io_service::fork_event event) +{ + service_registry_->notify_fork(event); +} + io_service::service::service(boost::asio::io_service& owner) : owner_(owner), next_(0) @@ -123,6 +135,10 @@ io_service::service::~service() { } +void io_service::service::fork_service(boost::asio::io_service::fork_event) +{ +} + service_already_exists::service_already_exists() : std::logic_error("Service already exists.") { diff --git a/3rdParty/Boost/src/boost/asio/impl/read.hpp b/3rdParty/Boost/src/boost/asio/impl/read.hpp index 9fba190..9290cd4 100644 --- a/3rdParty/Boost/src/boost/asio/impl/read.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/read.hpp @@ -2,7 +2,7 @@ // impl/read.hpp // ~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -18,11 +18,14 @@ #include <algorithm> #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/array_fwd.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/dependent_type.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> @@ -58,10 +61,17 @@ inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers) { boost::system::error_code ec; std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read"); return bytes_transferred; } +template <typename SyncReadStream, typename MutableBufferSequence> +inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, + boost::system::error_code& ec) +{ + return read(s, buffers, transfer_all(), ec); +} + template <typename SyncReadStream, typename MutableBufferSequence, typename CompletionCondition> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, @@ -69,7 +79,7 @@ inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, { boost::system::error_code ec; std::size_t bytes_transferred = read(s, buffers, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read"); return bytes_transferred; } @@ -104,10 +114,18 @@ inline std::size_t read(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read(s, b, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read"); return bytes_transferred; } +template <typename SyncReadStream, typename Allocator> +inline std::size_t read(SyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + boost::system::error_code& ec) +{ + return read(s, b, transfer_all(), ec); +} + template <typename SyncReadStream, typename Allocator, typename CompletionCondition> inline std::size_t read(SyncReadStream& s, @@ -116,7 +134,7 @@ inline std::size_t read(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read(s, b, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read"); return bytes_transferred; } @@ -131,15 +149,35 @@ namespace detail { public: read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_op(const read_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_op(read_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } +#endif // defined(BOOST_ASIO_HAS_MOVE) void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) @@ -150,7 +188,8 @@ namespace detail buffers_.prepare(this->check_for_completion(ec, total_transferred_)); for (;;) { - stream_.async_read_some(buffers_, *this); + stream_.async_read_some(buffers_, + BOOST_ASIO_MOVE_CAST(read_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); @@ -181,17 +220,36 @@ namespace detail public: read_op(AsyncReadStream& stream, const boost::asio::mutable_buffers_1& buffers, - CompletionCondition completion_condition, - ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_op(const read_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) { } + read_op(read_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -202,8 +260,9 @@ namespace detail n = this->check_for_completion(ec, total_transferred_); for (;;) { - stream_.async_read_some(boost::asio::buffer( - buffer_ + total_transferred_, n), *this); + stream_.async_read_some( + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(read_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -223,6 +282,168 @@ namespace detail ReadHandler handler_; }; + template <typename AsyncReadStream, typename Elem, + typename CompletionCondition, typename ReadHandler> + class read_op<AsyncReadStream, boost::array<Elem, 2>, + CompletionCondition, ReadHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + read_op(AsyncReadStream& stream, const boost::array<Elem, 2>& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_op(const read_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_op(read_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + boost::array<boost::asio::mutable_buffer, 2> >::type bufs = {{ + boost::asio::mutable_buffer(buffers_[0]), + boost::asio::mutable_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + stream_.async_read_some(bufs, BOOST_ASIO_MOVE_CAST(read_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncReadStream& stream_; + boost::array<Elem, 2> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + +#if defined(BOOST_ASIO_HAS_STD_ARRAY) + + template <typename AsyncReadStream, typename Elem, + typename CompletionCondition, typename ReadHandler> + class read_op<AsyncReadStream, std::array<Elem, 2>, + CompletionCondition, ReadHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + read_op(AsyncReadStream& stream, const std::array<Elem, 2>& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_op(const read_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_op(read_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + std::array<boost::asio::mutable_buffer, 2> >::type bufs = {{ + boost::asio::mutable_buffer(buffers_[0]), + boost::asio::mutable_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + stream_.async_read_some(bufs, BOOST_ASIO_MOVE_CAST(read_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncReadStream& stream_; + std::array<Elem, 2> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + +#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) + template <typename AsyncReadStream, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void* asio_handler_allocate(std::size_t size, @@ -246,6 +467,17 @@ namespace detail template <typename Function, typename AsyncReadStream, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_op<AsyncReadStream, MutableBufferSequence, + CompletionCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, + typename MutableBufferSequence, typename CompletionCondition, + typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_op<AsyncReadStream, MutableBufferSequence, CompletionCondition, ReadHandler>* this_handler) @@ -253,25 +485,47 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename MutableBufferSequence, + typename CompletionCondition, typename ReadHandler> + inline read_op<AsyncReadStream, MutableBufferSequence, + CompletionCondition, ReadHandler> + make_read_op(AsyncReadStream& s, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) + { + return read_op<AsyncReadStream, MutableBufferSequence, CompletionCondition, + ReadHandler>(s, buffers, completion_condition, handler); + } } // namespace detail template <typename AsyncReadStream, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_op<AsyncReadStream, MutableBufferSequence, - CompletionCondition, ReadHandler>( - s, buffers, completion_condition, 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_op( + s, buffers, completion_condition, + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( boost::system::error_code(), 0, 1); } template <typename AsyncReadStream, typename MutableBufferSequence, typename ReadHandler> inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, - ReadHandler handler) + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - async_read(s, buffers, transfer_all(), 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_op( + s, buffers, transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } #if !defined(BOOST_NO_IOSTREAM) @@ -286,15 +540,35 @@ namespace detail public: read_streambuf_op(AsyncReadStream& stream, basic_streambuf<Allocator>& streambuf, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), streambuf_(streambuf), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_streambuf_op(const read_streambuf_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + streambuf_(other.streambuf_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_streambuf_op(read_streambuf_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + streambuf_(other.streambuf_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } +#endif // defined(BOOST_ASIO_HAS_MOVE) void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) @@ -307,7 +581,8 @@ namespace detail bytes_available = read_size_helper(streambuf_, max_size); for (;;) { - stream_.async_read_some(streambuf_.prepare(bytes_available), *this); + stream_.async_read_some(streambuf_.prepare(bytes_available), + BOOST_ASIO_MOVE_CAST(read_streambuf_op)(*this)); return; default: total_transferred_ += bytes_transferred; streambuf_.commit(bytes_transferred); @@ -350,6 +625,16 @@ namespace detail template <typename Function, typename AsyncReadStream, typename Allocator, typename CompletionCondition, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_streambuf_op<AsyncReadStream, Allocator, + CompletionCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, + typename Allocator, typename CompletionCondition, typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_streambuf_op<AsyncReadStream, Allocator, CompletionCondition, ReadHandler>* this_handler) @@ -357,25 +642,48 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename Allocator, + typename CompletionCondition, typename ReadHandler> + inline read_streambuf_op<AsyncReadStream, Allocator, + CompletionCondition, ReadHandler> + make_read_streambuf_op( + AsyncReadStream& s, boost::asio::basic_streambuf<Allocator>& b, + CompletionCondition completion_condition, ReadHandler handler) + { + return read_streambuf_op<AsyncReadStream, Allocator, CompletionCondition, + ReadHandler>(s, b, completion_condition, handler); + } } // namespace detail template <typename AsyncReadStream, typename Allocator, typename CompletionCondition, typename ReadHandler> inline void async_read(AsyncReadStream& s, boost::asio::basic_streambuf<Allocator>& b, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_streambuf_op<AsyncReadStream, - Allocator, CompletionCondition, ReadHandler>( - s, b, completion_condition, handler)( - boost::system::error_code(), 0, 1); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_streambuf_op( + s, b, completion_condition, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } template <typename AsyncReadStream, typename Allocator, typename ReadHandler> inline void async_read(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, ReadHandler handler) + boost::asio::basic_streambuf<Allocator>& b, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - async_read(s, b, transfer_all(), 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_streambuf_op( + s, b, transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } #endif // !defined(BOOST_NO_IOSTREAM) diff --git a/3rdParty/Boost/src/boost/asio/impl/read_at.hpp b/3rdParty/Boost/src/boost/asio/impl/read_at.hpp index dcf2c33..08e37fe 100644 --- a/3rdParty/Boost/src/boost/asio/impl/read_at.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/read_at.hpp @@ -2,7 +2,7 @@ // impl/read_at.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -18,11 +18,14 @@ #include <algorithm> #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/array_fwd.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/dependent_type.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> @@ -62,10 +65,18 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = read_at( d, offset, buffers, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } +template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence> +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + boost::system::error_code& ec) +{ + return read_at(d, offset, buffers, transfer_all(), ec); +} + template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, @@ -75,7 +86,7 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = read_at( d, offset, buffers, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } @@ -112,10 +123,18 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = read_at( d, offset, b, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } +template <typename SyncRandomAccessReadDevice, typename Allocator> +inline std::size_t read_at(SyncRandomAccessReadDevice& d, + boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, + boost::system::error_code& ec) +{ + return read_at(d, offset, b, transfer_all(), ec); +} + template <typename SyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, @@ -125,7 +144,7 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = read_at( d, offset, b, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_at"); return bytes_transferred; } @@ -142,16 +161,38 @@ namespace detail public: read_at_op(AsyncRandomAccessReadDevice& device, boost::uint64_t offset, const MutableBufferSequence& buffers, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffers_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_at_op(const read_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_at_op(read_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } +#endif // defined(BOOST_ASIO_HAS_MOVE) void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) @@ -162,8 +203,8 @@ namespace detail buffers_.prepare(this->check_for_completion(ec, total_transferred_)); for (;;) { - device_.async_read_some_at( - offset_ + total_transferred_, buffers_, *this); + device_.async_read_some_at(offset_ + total_transferred_, + buffers_, BOOST_ASIO_MOVE_CAST(read_at_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); @@ -195,16 +236,38 @@ namespace detail public: read_at_op(AsyncRandomAccessReadDevice& device, boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_at_op(const read_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_at_op(read_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { } +#endif // defined(BOOST_ASIO_HAS_MOVE) void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) @@ -217,7 +280,8 @@ namespace detail for (;;) { device_.async_read_some_at(offset_ + total_transferred_, - boost::asio::buffer(buffer_ + total_transferred_, n), *this); + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(read_at_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -238,6 +302,180 @@ namespace detail ReadHandler handler_; }; + template <typename AsyncRandomAccessReadDevice, typename Elem, + typename CompletionCondition, typename ReadHandler> + class read_at_op<AsyncRandomAccessReadDevice, boost::array<Elem, 2>, + CompletionCondition, ReadHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + read_at_op(AsyncRandomAccessReadDevice& device, + boost::uint64_t offset, const boost::array<Elem, 2>& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_at_op(const read_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_at_op(read_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + boost::array<boost::asio::mutable_buffer, 2> >::type bufs = {{ + boost::asio::mutable_buffer(buffers_[0]), + boost::asio::mutable_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + device_.async_read_some_at(offset_ + total_transferred_, + bufs, BOOST_ASIO_MOVE_CAST(read_at_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncRandomAccessReadDevice& device_; + boost::uint64_t offset_; + boost::array<Elem, 2> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + +#if defined(BOOST_ASIO_HAS_STD_ARRAY) + + template <typename AsyncRandomAccessReadDevice, typename Elem, + typename CompletionCondition, typename ReadHandler> + class read_at_op<AsyncRandomAccessReadDevice, std::array<Elem, 2>, + CompletionCondition, ReadHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + read_at_op(AsyncRandomAccessReadDevice& device, + boost::uint64_t offset, const std::array<Elem, 2>& buffers, + CompletionCondition completion_condition, ReadHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_at_op(const read_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + read_at_op(read_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + std::array<boost::asio::mutable_buffer, 2> >::type bufs = {{ + boost::asio::mutable_buffer(buffers_[0]), + boost::asio::mutable_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + device_.async_read_some_at(offset_ + total_transferred_, + bufs, BOOST_ASIO_MOVE_CAST(read_at_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncRandomAccessReadDevice& device_; + boost::uint64_t offset_; + std::array<Elem, 2> buffers_; + std::size_t total_transferred_; + ReadHandler handler_; + }; + +#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) + template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> @@ -263,6 +501,17 @@ namespace detail template <typename Function, typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, + CompletionCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncRandomAccessReadDevice, + typename MutableBufferSequence, typename CompletionCondition, + typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, CompletionCondition, ReadHandler>* this_handler) @@ -270,17 +519,36 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncRandomAccessReadDevice, + typename MutableBufferSequence, typename CompletionCondition, + typename ReadHandler> + inline read_at_op<AsyncRandomAccessReadDevice, + MutableBufferSequence, CompletionCondition, ReadHandler> + make_read_at_op(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, const MutableBufferSequence& buffers, + CompletionCondition completion_condition, ReadHandler handler) + { + return read_at_op<AsyncRandomAccessReadDevice, + MutableBufferSequence, CompletionCondition, ReadHandler>( + d, offset, buffers, completion_condition, handler); + } } // namespace detail template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, typename ReadHandler> inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, const MutableBufferSequence& buffers, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_at_op<AsyncRandomAccessReadDevice, - MutableBufferSequence, CompletionCondition, ReadHandler>( - d, offset, buffers, completion_condition, 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_at_op( + d, offset, buffers, completion_condition, + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( boost::system::error_code(), 0, 1); } @@ -288,9 +556,16 @@ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename ReadHandler> inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, const MutableBufferSequence& buffers, - ReadHandler handler) + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - async_read_at(d, offset, buffers, transfer_all(), 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_at_op( + d, offset, buffers, transfer_all(), + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } #if !defined(BOOST_NO_IOSTREAM) @@ -305,17 +580,39 @@ namespace detail public: read_at_streambuf_op(AsyncRandomAccessReadDevice& device, boost::uint64_t offset, basic_streambuf<Allocator>& streambuf, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, ReadHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), streambuf_(streambuf), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + read_at_streambuf_op(const read_at_streambuf_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + streambuf_(other.streambuf_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) { } + read_at_streambuf_op(read_at_streambuf_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + streambuf_(other.streambuf_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -328,7 +625,8 @@ namespace detail for (;;) { device_.async_read_some_at(offset_ + total_transferred_, - streambuf_.prepare(bytes_available), *this); + streambuf_.prepare(bytes_available), + BOOST_ASIO_MOVE_CAST(read_at_streambuf_op)(*this)); return; default: total_transferred_ += bytes_transferred; streambuf_.commit(bytes_transferred); @@ -372,6 +670,16 @@ namespace detail template <typename Function, typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, + CompletionCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncRandomAccessReadDevice, + typename Allocator, typename CompletionCondition, typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, CompletionCondition, ReadHandler>* this_handler) @@ -379,17 +687,35 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncRandomAccessReadDevice, typename Allocator, + typename CompletionCondition, typename ReadHandler> + inline read_at_streambuf_op<AsyncRandomAccessReadDevice, + Allocator, CompletionCondition, ReadHandler> + make_read_at_streambuf_op(AsyncRandomAccessReadDevice& d, + boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, + CompletionCondition completion_condition, ReadHandler handler) + { + return read_at_streambuf_op<AsyncRandomAccessReadDevice, + Allocator, CompletionCondition, ReadHandler>( + d, offset, b, completion_condition, handler); + } } // namespace detail template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler> inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, - CompletionCondition completion_condition, ReadHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, - Allocator, CompletionCondition, ReadHandler>( - d, offset, b, completion_condition, 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_at_streambuf_op( + d, offset, b, completion_condition, + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( boost::system::error_code(), 0, 1); } @@ -397,9 +723,16 @@ template <typename AsyncRandomAccessReadDevice, typename Allocator, typename ReadHandler> inline void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, - ReadHandler handler) + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - async_read_at(d, offset, b, transfer_all(), 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. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_at_streambuf_op( + d, offset, b, transfer_all(), + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } #endif // !defined(BOOST_NO_IOSTREAM) diff --git a/3rdParty/Boost/src/boost/asio/impl/read_until.hpp b/3rdParty/Boost/src/boost/asio/impl/read_until.hpp index 5eeb1bc..1b9a8f3 100644 --- a/3rdParty/Boost/src/boost/asio/impl/read_until.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/read_until.hpp @@ -2,7 +2,7 @@ // impl/read_until.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -25,6 +25,7 @@ #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -38,7 +39,7 @@ inline std::size_t read_until(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read_until(s, b, delim, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } @@ -56,11 +57,11 @@ std::size_t read_until(SyncReadStream& s, typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = b.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position; + iterator start_pos = begin + search_position; iterator end = iterator::end(buffers); // Look for a match. - iterator iter = std::find(start, end, delim); + iterator iter = std::find(start_pos, end, delim); if (iter != end) { // Found a match. We're done. @@ -94,7 +95,7 @@ inline std::size_t read_until(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read_until(s, b, delim, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } @@ -147,12 +148,12 @@ std::size_t read_until(SyncReadStream& s, typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = b.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position; + iterator start_pos = begin + search_position; iterator end = iterator::end(buffers); // Look for a match. std::pair<iterator, bool> result = detail::partial_search( - start, end, delim.begin(), delim.end()); + start_pos, end, delim.begin(), delim.end()); if (result.first != end) { if (result.second) @@ -194,7 +195,7 @@ inline std::size_t read_until(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read_until(s, b, expr, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } @@ -212,14 +213,14 @@ std::size_t read_until(SyncReadStream& s, typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = b.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position; + iterator start_pos = begin + search_position; iterator end = iterator::end(buffers); // Look for a match. boost::match_results<iterator, typename std::vector<boost::sub_match<iterator> >::allocator_type> match_results; - if (regex_search(start, end, match_results, expr, + if (regex_search(start_pos, end, match_results, expr, boost::match_default | boost::match_partial)) { if (match_results[0].matched) @@ -270,11 +271,11 @@ std::size_t read_until(SyncReadStream& s, typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = b.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position; + iterator start_pos = begin + search_position; iterator end = iterator::end(buffers); // Look for a match. - std::pair<iterator, bool> result = match_condition(start, end); + std::pair<iterator, bool> result = match_condition(start_pos, end); if (result.second) { // Full match. We're done. @@ -314,7 +315,7 @@ inline std::size_t read_until(SyncReadStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = read_until(s, b, match_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "read_until"); return bytes_transferred; } @@ -326,15 +327,35 @@ namespace detail public: read_until_delim_op(AsyncReadStream& stream, boost::asio::basic_streambuf<Allocator>& streambuf, - char delim, ReadHandler handler) + char delim, ReadHandler& handler) : stream_(stream), streambuf_(streambuf), delim_(delim), search_position_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + read_until_delim_op(const read_until_delim_op& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + delim_(other.delim_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_delim_op(read_until_delim_op&& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + delim_(other.delim_), + search_position_(other.search_position_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -352,11 +373,11 @@ namespace detail typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = streambuf_.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position_; + iterator start_pos = begin + search_position_; iterator end = iterator::end(buffers); // Look for a match. - iterator iter = std::find(start, end, delim_); + iterator iter = std::find(start_pos, end, delim_); if (iter != end) { // Found a match. We're done. @@ -385,7 +406,8 @@ namespace detail break; // Start a new asynchronous read operation to obtain more data. - stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + stream_.async_read_some(streambuf_.prepare(bytes_to_read), + BOOST_ASIO_MOVE_CAST(read_until_delim_op)(*this)); return; default: streambuf_.commit(bytes_transferred); if (ec || bytes_transferred == 0) @@ -432,6 +454,16 @@ namespace detail template <typename Function, typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_until_delim_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_until_delim_op<AsyncReadStream, Allocator, ReadHandler>* this_handler) @@ -439,16 +471,30 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline read_until_delim_op<AsyncReadStream, Allocator, ReadHandler> + make_read_until_delim_op(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + char delim, ReadHandler handler) + { + return read_until_delim_op<AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, handler); + } } // namespace detail template <typename AsyncReadStream, typename Allocator, typename ReadHandler> void async_read_until(AsyncReadStream& s, - boost::asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler) + boost::asio::basic_streambuf<Allocator>& b, char delim, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_until_delim_op< - AsyncReadStream, Allocator, ReadHandler>( - s, b, delim, handler)( - boost::system::error_code(), 0, 1); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_until_delim_op( + s, b, delim, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } namespace detail @@ -459,15 +505,35 @@ namespace detail public: read_until_delim_string_op(AsyncReadStream& stream, boost::asio::basic_streambuf<Allocator>& streambuf, - const std::string& delim, ReadHandler handler) + const std::string& delim, ReadHandler& handler) : stream_(stream), streambuf_(streambuf), delim_(delim), search_position_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + read_until_delim_string_op(const read_until_delim_string_op& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + delim_(other.delim_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_delim_string_op(read_until_delim_string_op&& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + delim_(BOOST_ASIO_MOVE_CAST(std::string)(other.delim_)), + search_position_(other.search_position_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -485,12 +551,12 @@ namespace detail typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = streambuf_.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position_; + iterator start_pos = begin + search_position_; iterator end = iterator::end(buffers); // Look for a match. std::pair<iterator, bool> result = detail::partial_search( - start, end, delim_.begin(), delim_.end()); + start_pos, end, delim_.begin(), delim_.end()); if (result.first != end && result.second) { // Full match. We're done. @@ -529,7 +595,8 @@ namespace detail break; // Start a new asynchronous read operation to obtain more data. - stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + stream_.async_read_some(streambuf_.prepare(bytes_to_read), + BOOST_ASIO_MOVE_CAST(read_until_delim_string_op)(*this)); return; default: streambuf_.commit(bytes_transferred); if (ec || bytes_transferred == 0) @@ -576,6 +643,16 @@ namespace detail template <typename Function, typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_until_delim_string_op<AsyncReadStream, + Allocator, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, + typename Allocator, typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_until_delim_string_op<AsyncReadStream, Allocator, ReadHandler>* this_handler) @@ -583,17 +660,30 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename Allocator, typename ReadHandler> + inline read_until_delim_string_op<AsyncReadStream, Allocator, ReadHandler> + make_read_until_delim_string_op(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + const std::string& delim, ReadHandler handler) + { + return read_until_delim_string_op<AsyncReadStream, Allocator, ReadHandler>( + s, b, delim, handler); + } } // namespace detail template <typename AsyncReadStream, typename Allocator, typename ReadHandler> void async_read_until(AsyncReadStream& s, boost::asio::basic_streambuf<Allocator>& b, const std::string& delim, - ReadHandler handler) + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_until_delim_string_op< - AsyncReadStream, Allocator, ReadHandler>( - s, b, delim, handler)( - boost::system::error_code(), 0, 1); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_until_delim_string_op( + s, b, delim, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } namespace detail @@ -605,15 +695,35 @@ namespace detail public: read_until_expr_op(AsyncReadStream& stream, boost::asio::basic_streambuf<Allocator>& streambuf, - const boost::regex& expr, ReadHandler handler) + const boost::regex& expr, ReadHandler& handler) : stream_(stream), streambuf_(streambuf), expr_(expr), search_position_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + read_until_expr_op(const read_until_expr_op& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + expr_(other.expr_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_expr_op(read_until_expr_op&& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + expr_(other.expr_), + search_position_(other.search_position_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -631,14 +741,14 @@ namespace detail typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = streambuf_.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position_; + iterator start_pos = begin + search_position_; iterator end = iterator::end(buffers); // Look for a match. boost::match_results<iterator, typename std::vector<boost::sub_match<iterator> >::allocator_type> match_results; - bool match = regex_search(start, end, match_results, expr_, + bool match = regex_search(start_pos, end, match_results, expr_, boost::match_default | boost::match_partial); if (match && match_results[0].matched) { @@ -678,7 +788,8 @@ namespace detail break; // Start a new asynchronous read operation to obtain more data. - stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + stream_.async_read_some(streambuf_.prepare(bytes_to_read), + BOOST_ASIO_MOVE_CAST(read_until_expr_op)(*this)); return; default: streambuf_.commit(bytes_transferred); if (ec || bytes_transferred == 0) @@ -727,6 +838,16 @@ namespace detail template <typename Function, typename AsyncReadStream, typename Allocator, typename RegEx, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_until_expr_op<AsyncReadStream, + Allocator, RegEx, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_until_expr_op<AsyncReadStream, Allocator, RegEx, ReadHandler>* this_handler) @@ -734,17 +855,31 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename Allocator, + typename RegEx, typename ReadHandler> + inline read_until_expr_op<AsyncReadStream, Allocator, RegEx, ReadHandler> + make_read_until_expr_op(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + const RegEx& expr, ReadHandler handler) + { + return read_until_expr_op<AsyncReadStream, Allocator, RegEx, ReadHandler>( + s, b, expr, handler); + } } // namespace detail template <typename AsyncReadStream, typename Allocator, typename ReadHandler> void async_read_until(AsyncReadStream& s, boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr, - ReadHandler handler) + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { - detail::read_until_expr_op<AsyncReadStream, - Allocator, boost::regex, ReadHandler>( - s, b, expr, handler)( - boost::system::error_code(), 0, 1); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_until_expr_op( + s, b, expr, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } namespace detail @@ -756,15 +891,35 @@ namespace detail public: read_until_match_op(AsyncReadStream& stream, boost::asio::basic_streambuf<Allocator>& streambuf, - MatchCondition match_condition, ReadHandler handler) + MatchCondition match_condition, ReadHandler& handler) : stream_(stream), streambuf_(streambuf), match_condition_(match_condition), search_position_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + read_until_match_op(const read_until_match_op& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + match_condition_(other.match_condition_), + search_position_(other.search_position_), + handler_(other.handler_) + { + } + + read_until_match_op(read_until_match_op&& other) + : stream_(other.stream_), + streambuf_(other.streambuf_), + match_condition_(other.match_condition_), + search_position_(other.search_position_), + handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -782,11 +937,11 @@ namespace detail typedef boost::asio::buffers_iterator<const_buffers_type> iterator; const_buffers_type buffers = streambuf_.data(); iterator begin = iterator::begin(buffers); - iterator start = begin + search_position_; + iterator start_pos = begin + search_position_; iterator end = iterator::end(buffers); // Look for a match. - std::pair<iterator, bool> result = match_condition_(start, end); + std::pair<iterator, bool> result = match_condition_(start_pos, end); if (result.second) { // Full match. We're done. @@ -825,7 +980,8 @@ namespace detail break; // Start a new asynchronous read operation to obtain more data. - stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this); + stream_.async_read_some(streambuf_.prepare(bytes_to_read), + BOOST_ASIO_MOVE_CAST(read_until_match_op)(*this)); return; default: streambuf_.commit(bytes_transferred); if (ec || bytes_transferred == 0) @@ -874,6 +1030,16 @@ namespace detail template <typename Function, typename AsyncReadStream, typename Allocator, typename MatchCondition, typename ReadHandler> + inline void asio_handler_invoke(Function& function, + read_until_match_op<AsyncReadStream, + Allocator, MatchCondition, ReadHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> inline void asio_handler_invoke(const Function& function, read_until_match_op<AsyncReadStream, Allocator, MatchCondition, ReadHandler>* this_handler) @@ -881,19 +1047,35 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncReadStream, typename Allocator, + typename MatchCondition, typename ReadHandler> + inline read_until_match_op<AsyncReadStream, Allocator, + MatchCondition, ReadHandler> + make_read_until_match_op(AsyncReadStream& s, + boost::asio::basic_streambuf<Allocator>& b, + MatchCondition match_condition, ReadHandler handler) + { + return read_until_match_op<AsyncReadStream, + Allocator, MatchCondition, ReadHandler>( + s, b, match_condition, handler); + } } // namespace detail template <typename AsyncReadStream, typename Allocator, typename MatchCondition, typename ReadHandler> void async_read_until(AsyncReadStream& s, boost::asio::basic_streambuf<Allocator>& b, - MatchCondition match_condition, ReadHandler handler, + MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler, typename boost::enable_if<is_match_condition<MatchCondition> >::type*) { - detail::read_until_match_op< - AsyncReadStream, Allocator, MatchCondition, ReadHandler>( - s, b, match_condition, handler)( - boost::system::error_code(), 0, 1); + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::make_read_until_match_op( + s, b, match_condition, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))( + boost::system::error_code(), 0, 1); } } // namespace asio diff --git a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp index c75f8c2..3066045 100644 --- a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.hpp @@ -2,7 +2,7 @@ // impl/serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp index c665ac8..0344fa5 100644 --- a/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp +++ b/3rdParty/Boost/src/boost/asio/impl/serial_port_base.ipp @@ -2,7 +2,7 @@ // impl/serial_port_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/3rdParty/Boost/src/boost/asio/impl/write.hpp b/3rdParty/Boost/src/boost/asio/impl/write.hpp index ae420bc..61422e4 100644 --- a/3rdParty/Boost/src/boost/asio/impl/write.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/write.hpp @@ -2,7 +2,7 @@ // impl/write.hpp // ~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -17,11 +17,14 @@ #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/array_fwd.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/dependent_type.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -56,10 +59,17 @@ inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers) { boost::system::error_code ec; std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write"); return bytes_transferred; } +template <typename SyncWriteStream, typename ConstBufferSequence> +inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, + boost::system::error_code& ec) +{ + return write(s, buffers, transfer_all(), ec); +} + template <typename SyncWriteStream, typename ConstBufferSequence, typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, @@ -67,7 +77,7 @@ inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, { boost::system::error_code ec; std::size_t bytes_transferred = write(s, buffers, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write"); return bytes_transferred; } @@ -90,10 +100,18 @@ inline std::size_t write(SyncWriteStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = write(s, b, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write"); return bytes_transferred; } +template <typename SyncWriteStream, typename Allocator> +inline std::size_t write(SyncWriteStream& s, + boost::asio::basic_streambuf<Allocator>& b, + boost::system::error_code& ec) +{ + return write(s, b, transfer_all(), ec); +} + template <typename SyncWriteStream, typename Allocator, typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, @@ -102,7 +120,7 @@ inline std::size_t write(SyncWriteStream& s, { boost::system::error_code ec; std::size_t bytes_transferred = write(s, b, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write"); return bytes_transferred; } @@ -117,16 +135,36 @@ namespace detail { public: write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffers_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_op(write_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -136,7 +174,8 @@ namespace detail buffers_.prepare(this->check_for_completion(ec, total_transferred_)); for (;;) { - stream_.async_write_some(buffers_, *this); + stream_.async_write_some(buffers_, + BOOST_ASIO_MOVE_CAST(write_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); @@ -168,16 +207,36 @@ namespace detail write_op(AsyncWriteStream& stream, const boost::asio::mutable_buffers_1& buffers, CompletionCondition completion_condition, - WriteHandler handler) + WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_op(write_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -188,8 +247,9 @@ namespace detail n = this->check_for_completion(ec, total_transferred_); for (;;) { - stream_.async_write_some(boost::asio::buffer( - buffer_ + total_transferred_, n), *this); + stream_.async_write_some( + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(write_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -219,16 +279,36 @@ namespace detail write_op(AsyncWriteStream& stream, const boost::asio::const_buffers_1& buffers, CompletionCondition completion_condition, - WriteHandler handler) + WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), stream_(stream), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) { } + write_op(write_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -239,8 +319,9 @@ namespace detail n = this->check_for_completion(ec, total_transferred_); for (;;) { - stream_.async_write_some(boost::asio::buffer( - buffer_ + total_transferred_, n), *this); + stream_.async_write_some( + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(write_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -260,6 +341,168 @@ namespace detail WriteHandler handler_; }; + template <typename AsyncWriteStream, typename Elem, + typename CompletionCondition, typename WriteHandler> + class write_op<AsyncWriteStream, boost::array<Elem, 2>, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_op(AsyncWriteStream& stream, const boost::array<Elem, 2>& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_op(write_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + boost::array<boost::asio::const_buffer, 2> >::type bufs = {{ + boost::asio::const_buffer(buffers_[0]), + boost::asio::const_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncWriteStream& stream_; + boost::array<Elem, 2> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + +#if defined(BOOST_ASIO_HAS_STD_ARRAY) + + template <typename AsyncWriteStream, typename Elem, + typename CompletionCondition, typename WriteHandler> + class write_op<AsyncWriteStream, std::array<Elem, 2>, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_op(AsyncWriteStream& stream, const std::array<Elem, 2>& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + stream_(stream), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_op(const write_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_op(write_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + stream_(other.stream_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + std::array<boost::asio::const_buffer, 2> >::type bufs = {{ + boost::asio::const_buffer(buffers_[0]), + boost::asio::const_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncWriteStream& stream_; + std::array<Elem, 2> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + +#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) + template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, @@ -283,6 +526,17 @@ namespace detail template <typename Function, typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> + inline void asio_handler_invoke(Function& function, + write_op<AsyncWriteStream, ConstBufferSequence, + CompletionCondition, WriteHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncWriteStream, + typename ConstBufferSequence, typename CompletionCondition, + typename WriteHandler> inline void asio_handler_invoke(const Function& function, write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) @@ -290,43 +544,78 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncWriteStream, typename ConstBufferSequence, + typename CompletionCondition, typename WriteHandler> + inline write_op<AsyncWriteStream, ConstBufferSequence, + CompletionCondition, WriteHandler> + make_write_op(AsyncWriteStream& s, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) + { + return write_op<AsyncWriteStream, ConstBufferSequence, CompletionCondition, + WriteHandler>(s, buffers, completion_condition, handler); + } } // namespace detail template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - detail::write_op<AsyncWriteStream, ConstBufferSequence, - CompletionCondition, WriteHandler>( - s, buffers, completion_condition, 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::make_write_op( + s, buffers, completion_condition, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))( boost::system::error_code(), 0, 1); } template <typename AsyncWriteStream, typename ConstBufferSequence, typename WriteHandler> inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, - WriteHandler handler) + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - async_write(s, buffers, transfer_all(), 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::make_write_op( + s, buffers, transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))( + boost::system::error_code(), 0, 1); } #if !defined(BOOST_NO_IOSTREAM) namespace detail { - template <typename AsyncWriteStream, typename Allocator, - typename WriteHandler> + template <typename Allocator, typename WriteHandler> class write_streambuf_handler { public: write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf, - WriteHandler handler) + WriteHandler& handler) : streambuf_(streambuf), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + write_streambuf_handler(const write_streambuf_handler& other) + : streambuf_(other.streambuf_), + handler_(other.handler_) + { + } + + write_streambuf_handler(write_streambuf_handler&& other) + : streambuf_(other.streambuf_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, const std::size_t bytes_transferred) { @@ -339,53 +628,75 @@ namespace detail WriteHandler handler_; }; - template <typename AsyncWriteStream, typename Allocator, - typename WriteHandler> + template <typename Allocator, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, - write_streambuf_handler<AsyncWriteStream, - Allocator, WriteHandler>* this_handler) + write_streambuf_handler<Allocator, WriteHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } - template <typename AsyncWriteStream, typename Allocator, - typename WriteHandler> + template <typename Allocator, typename WriteHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - write_streambuf_handler<AsyncWriteStream, - Allocator, WriteHandler>* this_handler) + write_streambuf_handler<Allocator, WriteHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } - template <typename Function, typename AsyncWriteStream, typename Allocator, - typename WriteHandler> + template <typename Function, typename Allocator, typename WriteHandler> + inline void asio_handler_invoke(Function& function, + write_streambuf_handler<Allocator, WriteHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename Allocator, typename WriteHandler> inline void asio_handler_invoke(const Function& function, - write_streambuf_handler<AsyncWriteStream, - Allocator, WriteHandler>* this_handler) + write_streambuf_handler<Allocator, WriteHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename Allocator, typename WriteHandler> + inline write_streambuf_handler<Allocator, WriteHandler> + make_write_streambuf_handler( + boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler) + { + return write_streambuf_handler<Allocator, WriteHandler>(b, handler); + } } // namespace detail template <typename AsyncWriteStream, typename Allocator, typename CompletionCondition, typename WriteHandler> inline void async_write(AsyncWriteStream& s, boost::asio::basic_streambuf<Allocator>& b, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, + BOOST_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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + async_write(s, b.data(), completion_condition, - detail::write_streambuf_handler< - AsyncWriteStream, Allocator, WriteHandler>(b, handler)); + detail::make_write_streambuf_handler( + b, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))); } template <typename AsyncWriteStream, typename Allocator, typename WriteHandler> inline void async_write(AsyncWriteStream& s, - boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler) + boost::asio::basic_streambuf<Allocator>& b, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - async_write(s, b, transfer_all(), 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_write(s, b.data(), transfer_all(), + detail::make_write_streambuf_handler( + b, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))); } #endif // !defined(BOOST_NO_IOSTREAM) diff --git a/3rdParty/Boost/src/boost/asio/impl/write_at.hpp b/3rdParty/Boost/src/boost/asio/impl/write_at.hpp index 39dc1af..acba02f 100644 --- a/3rdParty/Boost/src/boost/asio/impl/write_at.hpp +++ b/3rdParty/Boost/src/boost/asio/impl/write_at.hpp @@ -2,7 +2,7 @@ // impl/write_at.hpp // ~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 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) @@ -17,11 +17,14 @@ #include <boost/asio/buffer.hpp> #include <boost/asio/completion_condition.hpp> +#include <boost/asio/detail/array_fwd.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/dependent_type.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -60,10 +63,18 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = write_at( d, offset, buffers, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } +template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence> +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + boost::system::error_code& ec) +{ + return write_at(d, offset, buffers, transfer_all(), ec); +} + template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, @@ -73,7 +84,7 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = write_at( d, offset, buffers, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } @@ -97,10 +108,18 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d, { boost::system::error_code ec; std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } +template <typename SyncRandomAccessWriteDevice, typename Allocator> +inline std::size_t write_at(SyncRandomAccessWriteDevice& d, + boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, + boost::system::error_code& ec) +{ + return write_at(d, offset, b, transfer_all(), ec); +} + template <typename SyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, @@ -110,7 +129,7 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::system::error_code ec; std::size_t bytes_transferred = write_at( d, offset, b, completion_condition, ec); - boost::asio::detail::throw_error(ec); + boost::asio::detail::throw_error(ec, "write_at"); return bytes_transferred; } @@ -126,17 +145,39 @@ namespace detail public: write_at_op(AsyncRandomAccessWriteDevice& device, boost::uint64_t offset, const ConstBufferSequence& buffers, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffers_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) { } + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -147,7 +188,8 @@ namespace detail for (;;) { device_.async_write_some_at( - offset_ + total_transferred_, buffers_, *this); + offset_ + total_transferred_, buffers_, + BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); return; default: total_transferred_ += bytes_transferred; buffers_.consume(bytes_transferred); @@ -180,17 +222,39 @@ namespace detail write_at_op(AsyncRandomAccessWriteDevice& device, boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers, CompletionCondition completion_condition, - WriteHandler handler) + WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -202,7 +266,8 @@ namespace detail for (;;) { device_.async_write_some_at(offset_ + total_transferred_, - boost::asio::buffer(buffer_ + total_transferred_, n), *this); + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -233,17 +298,39 @@ namespace detail write_at_op(AsyncRandomAccessWriteDevice& device, boost::uint64_t offset, const boost::asio::const_buffers_1& buffers, CompletionCondition completion_condition, - WriteHandler handler) + WriteHandler& handler) : detail::base_from_completion_cond< CompletionCondition>(completion_condition), device_(device), offset_(offset), buffer_(buffers), total_transferred_(0), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) { } + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffer_(other.buffer_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred, int start = 0) { @@ -255,7 +342,8 @@ namespace detail for (;;) { device_.async_write_some_at(offset_ + total_transferred_, - boost::asio::buffer(buffer_ + total_transferred_, n), *this); + boost::asio::buffer(buffer_ + total_transferred_, n), + BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); return; default: total_transferred_ += bytes_transferred; if ((!ec && bytes_transferred == 0) @@ -276,6 +364,180 @@ namespace detail WriteHandler handler_; }; + template <typename AsyncRandomAccessWriteDevice, typename Elem, + typename CompletionCondition, typename WriteHandler> + class write_at_op<AsyncRandomAccessWriteDevice, boost::array<Elem, 2>, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_at_op(AsyncRandomAccessWriteDevice& device, + boost::uint64_t offset, const boost::array<Elem, 2>& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + boost::array<boost::asio::const_buffer, 2> >::type bufs = {{ + boost::asio::const_buffer(buffers_[0]), + boost::asio::const_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + device_.async_write_some_at(offset_ + total_transferred_, + bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncRandomAccessWriteDevice& device_; + boost::uint64_t offset_; + boost::array<Elem, 2> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + +#if defined(BOOST_ASIO_HAS_STD_ARRAY) + + template <typename AsyncRandomAccessWriteDevice, typename Elem, + typename CompletionCondition, typename WriteHandler> + class write_at_op<AsyncRandomAccessWriteDevice, std::array<Elem, 2>, + CompletionCondition, WriteHandler> + : detail::base_from_completion_cond<CompletionCondition> + { + public: + write_at_op(AsyncRandomAccessWriteDevice& device, + boost::uint64_t offset, const std::array<Elem, 2>& buffers, + CompletionCondition completion_condition, WriteHandler& handler) + : detail::base_from_completion_cond< + CompletionCondition>(completion_condition), + device_(device), + offset_(offset), + buffers_(buffers), + total_transferred_(0), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_op(const write_at_op& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(other.handler_) + { + } + + write_at_op(write_at_op&& other) + : detail::base_from_completion_cond<CompletionCondition>(other), + device_(other.device_), + offset_(other.offset_), + buffers_(other.buffers_), + total_transferred_(other.total_transferred_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + + void operator()(const boost::system::error_code& ec, + std::size_t bytes_transferred, int start = 0) + { + typename boost::asio::detail::dependent_type<Elem, + std::array<boost::asio::const_buffer, 2> >::type bufs = {{ + boost::asio::const_buffer(buffers_[0]), + boost::asio::const_buffer(buffers_[1]) }}; + std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]); + std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]); + std::size_t n = 0; + switch (start) + { + case 1: + n = this->check_for_completion(ec, total_transferred_); + for (;;) + { + bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n); + bufs[1] = boost::asio::buffer( + bufs[1] + (total_transferred_ < buffer_size0 + ? 0 : total_transferred_ - buffer_size0), + n - boost::asio::buffer_size(bufs[0])); + device_.async_write_some_at(offset_ + total_transferred_, + bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this)); + return; default: + total_transferred_ += bytes_transferred; + if ((!ec && bytes_transferred == 0) + || (n = this->check_for_completion(ec, total_transferred_)) == 0 + || total_transferred_ == buffer_size0 + buffer_size1) + break; + } + + handler_(ec, static_cast<const std::size_t&>(total_transferred_)); + } + } + + //private: + AsyncRandomAccessWriteDevice& device_; + boost::uint64_t offset_; + std::array<Elem, 2> buffers_; + std::size_t total_transferred_; + WriteHandler handler_; + }; + +#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) + template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, @@ -299,6 +561,17 @@ namespace detail template <typename Function, typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> + inline void asio_handler_invoke(Function& function, + write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, + CompletionCondition, WriteHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename AsyncRandomAccessWriteDevice, + typename ConstBufferSequence, typename CompletionCondition, + typename WriteHandler> inline void asio_handler_invoke(const Function& function, write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, CompletionCondition, WriteHandler>* this_handler) @@ -306,17 +579,35 @@ namespace detail boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, + typename CompletionCondition, typename WriteHandler> + inline write_at_op<AsyncRandomAccessWriteDevice, + ConstBufferSequence, CompletionCondition, WriteHandler> + make_write_at_op(AsyncRandomAccessWriteDevice& d, + boost::uint64_t offset, const ConstBufferSequence& buffers, + CompletionCondition completion_condition, WriteHandler handler) + { + return write_at_op<AsyncRandomAccessWriteDevice, + ConstBufferSequence, CompletionCondition, WriteHandler>( + d, offset, buffers, completion_condition, handler); + } } // namespace detail template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, typename WriteHandler> inline void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, const ConstBufferSequence& buffers, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - detail::write_at_op<AsyncRandomAccessWriteDevice, - ConstBufferSequence, CompletionCondition, WriteHandler>( - d, offset, buffers, completion_condition, 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::make_write_at_op( + d, offset, buffers, completion_condition, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))( boost::system::error_code(), 0, 1); } @@ -324,28 +615,48 @@ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename WriteHandler> inline void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, const ConstBufferSequence& buffers, - WriteHandler handler) + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - async_write_at(d, offset, buffers, transfer_all(), 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::make_write_at_op( + d, offset, buffers, transfer_all(), + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))( + boost::system::error_code(), 0, 1); } #if !defined(BOOST_NO_IOSTREAM) namespace detail { - template <typename AsyncRandomAccessWriteDevice, - typename Allocator, typename WriteHandler> + template <typename Allocator, typename WriteHandler> class write_at_streambuf_op { public: write_at_streambuf_op( boost::asio::basic_streambuf<Allocator>& streambuf, - WriteHandler handler) + WriteHandler& handler) : streambuf_(streambuf), - handler_(handler) + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) + write_at_streambuf_op(const write_at_streambuf_op& other) + : streambuf_(other.streambuf_), + handler_(other.handler_) { } + write_at_streambuf_op(write_at_streambuf_op&& other) + : streambuf_(other.streambuf_), + handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_)) + { + } +#endif // defined(BOOST_ASIO_HAS_MOVE) + void operator()(const boost::system::error_code& ec, const std::size_t bytes_transferred) { @@ -358,55 +669,76 @@ namespace detail WriteHandler handler_; }; - template <typename AsyncRandomAccessWriteDevice, typename Allocator, - typename WriteHandler> + template <typename Allocator, typename WriteHandler> inline void* asio_handler_allocate(std::size_t size, - write_at_streambuf_op<AsyncRandomAccessWriteDevice, - Allocator, WriteHandler>* this_handler) + write_at_streambuf_op<Allocator, WriteHandler>* this_handler) { return boost_asio_handler_alloc_helpers::allocate( size, this_handler->handler_); } - template <typename AsyncRandomAccessWriteDevice, typename Allocator, - typename WriteHandler> + template <typename Allocator, typename WriteHandler> inline void asio_handler_deallocate(void* pointer, std::size_t size, - write_at_streambuf_op<AsyncRandomAccessWriteDevice, - Allocator, WriteHandler>* this_handler) + write_at_streambuf_op<Allocator, WriteHandler>* this_handler) { boost_asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); } - template <typename Function, typename AsyncRandomAccessWriteDevice, - typename Allocator, typename WriteHandler> + template <typename Function, typename Allocator, typename WriteHandler> + inline void asio_handler_invoke(Function& function, + write_at_streambuf_op<Allocator, WriteHandler>* this_handler) + { + boost_asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); + } + + template <typename Function, typename Allocator, typename WriteHandler> inline void asio_handler_invoke(const Function& function, - write_at_streambuf_op<AsyncRandomAccessWriteDevice, - Allocator, WriteHandler>* this_handler) + write_at_streambuf_op<Allocator, WriteHandler>* this_handler) { boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); } + + template <typename Allocator, typename WriteHandler> + inline write_at_streambuf_op<Allocator, WriteHandler> + make_write_at_streambuf_op( + boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler) + { + return write_at_streambuf_op<Allocator, WriteHandler>(b, handler); + } } // namespace detail template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition, typename WriteHandler> inline void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, - CompletionCondition completion_condition, WriteHandler handler) + CompletionCondition completion_condition, + BOOST_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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + async_write_at(d, offset, b.data(), completion_condition, - detail::write_at_streambuf_op< - AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler)); + detail::make_write_at_streambuf_op( + b, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))); } template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename WriteHandler> inline void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b, - WriteHandler handler) + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { - async_write_at(d, offset, b, transfer_all(), 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. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + async_write_at(d, offset, b.data(), transfer_all(), + detail::make_write_at_streambuf_op( + b, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))); } #endif // !defined(BOOST_NO_IOSTREAM) |