diff options
Diffstat (limited to '3rdparty/asio/include/asio/impl/buffered_read_stream.hpp')
-rw-r--r-- | 3rdparty/asio/include/asio/impl/buffered_read_stream.hpp | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/3rdparty/asio/include/asio/impl/buffered_read_stream.hpp b/3rdparty/asio/include/asio/impl/buffered_read_stream.hpp new file mode 100644 index 00000000000..a25beeedce0 --- /dev/null +++ b/3rdparty/asio/include/asio/impl/buffered_read_stream.hpp @@ -0,0 +1,498 @@ +// +// impl/buffered_read_stream.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IMPL_BUFFERED_READ_STREAM_HPP +#define ASIO_IMPL_BUFFERED_READ_STREAM_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/associator.hpp" +#include "asio/detail/handler_alloc_helpers.hpp" +#include "asio/detail/handler_cont_helpers.hpp" +#include "asio/detail/handler_invoke_helpers.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/non_const_lvalue.hpp" +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { + +template <typename Stream> +std::size_t buffered_read_stream<Stream>::fill() +{ + detail::buffer_resize_guard<detail::buffered_stream_storage> + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size))); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +template <typename Stream> +std::size_t buffered_read_stream<Stream>::fill(asio::error_code& ec) +{ + detail::buffer_resize_guard<detail::buffered_stream_storage> + resize_guard(storage_); + std::size_t previous_size = storage_.size(); + storage_.resize(storage_.capacity()); + storage_.resize(previous_size + next_layer_.read_some(buffer( + storage_.data() + previous_size, + storage_.size() - previous_size), + ec)); + resize_guard.commit(); + return storage_.size() - previous_size; +} + +namespace detail +{ + template <typename ReadHandler> + class buffered_fill_handler + { + public: + buffered_fill_handler(detail::buffered_stream_storage& storage, + std::size_t previous_size, ReadHandler& handler) + : storage_(storage), + previous_size_(previous_size), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_fill_handler(const buffered_fill_handler& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(other.handler_) + { + } + + buffered_fill_handler(buffered_fill_handler&& other) + : storage_(other.storage_), + previous_size_(other.previous_size_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, + const std::size_t bytes_transferred) + { + storage_.resize(previous_size_ + bytes_transferred); + ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_transferred); + } + + //private: + detail::buffered_stream_storage& storage_; + std::size_t previous_size_; + ReadHandler handler_; + }; + + template <typename ReadHandler> + inline asio_handler_allocate_is_deprecated + asio_handler_allocate(std::size_t size, + buffered_fill_handler<ReadHandler>* this_handler) + { +#if defined(ASIO_NO_DEPRECATED) + asio_handler_alloc_helpers::allocate(size, this_handler->handler_); + return asio_handler_allocate_is_no_longer_used(); +#else // defined(ASIO_NO_DEPRECATED) + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename ReadHandler> + inline asio_handler_deallocate_is_deprecated + asio_handler_deallocate(void* pointer, std::size_t size, + buffered_fill_handler<ReadHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_deallocate_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename ReadHandler> + inline bool asio_handler_is_continuation( + buffered_fill_handler<ReadHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template <typename Function, typename ReadHandler> + inline asio_handler_invoke_is_deprecated + asio_handler_invoke(Function& function, + buffered_fill_handler<ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_invoke_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename Function, typename ReadHandler> + inline asio_handler_invoke_is_deprecated + asio_handler_invoke(const Function& function, + buffered_fill_handler<ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_invoke_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename Stream> + class initiate_async_buffered_fill + { + public: + typedef typename remove_reference< + Stream>::type::lowest_layer_type::executor_type executor_type; + + explicit initiate_async_buffered_fill( + typename remove_reference<Stream>::type& next_layer) + : next_layer_(next_layer) + { + } + + executor_type get_executor() const ASIO_NOEXCEPT + { + return next_layer_.lowest_layer().get_executor(); + } + + template <typename ReadHandler> + void operator()(ASIO_MOVE_ARG(ReadHandler) handler, + buffered_stream_storage* storage) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + non_const_lvalue<ReadHandler> handler2(handler); + std::size_t previous_size = storage->size(); + storage->resize(storage->capacity()); + next_layer_.async_read_some( + buffer( + storage->data() + previous_size, + storage->size() - previous_size), + buffered_fill_handler<typename decay<ReadHandler>::type>( + *storage, previous_size, handler2.value)); + } + + private: + typename remove_reference<Stream>::type& next_layer_; + }; +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template <template <typename, typename> class Associator, + typename ReadHandler, typename DefaultCandidate> +struct associator<Associator, + detail::buffered_fill_handler<ReadHandler>, + DefaultCandidate> + : Associator<ReadHandler, DefaultCandidate> +{ + static typename Associator<ReadHandler, DefaultCandidate>::type get( + const detail::buffered_fill_handler<ReadHandler>& h, + const DefaultCandidate& c = DefaultCandidate()) ASIO_NOEXCEPT + { + return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template <typename Stream> +template < + ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, + std::size_t)) ReadHandler> +ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream<Stream>::async_fill( + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_initiate<ReadHandler, + void (asio::error_code, std::size_t)>( + detail::initiate_async_buffered_fill<Stream>(next_layer_), + handler, &storage_); +} + +template <typename Stream> +template <typename MutableBufferSequence> +std::size_t buffered_read_stream<Stream>::read_some( + const MutableBufferSequence& buffers) +{ + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.empty()) + this->fill(); + + return this->copy(buffers); +} + +template <typename Stream> +template <typename MutableBufferSequence> +std::size_t buffered_read_stream<Stream>::read_some( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + + using asio::buffer_size; + if (buffer_size(buffers) == 0) + return 0; + + if (storage_.empty() && !this->fill(ec)) + return 0; + + return this->copy(buffers); +} + +namespace detail +{ + template <typename MutableBufferSequence, typename ReadHandler> + class buffered_read_some_handler + { + public: + buffered_read_some_handler(detail::buffered_stream_storage& storage, + const MutableBufferSequence& buffers, ReadHandler& handler) + : storage_(storage), + buffers_(buffers), + handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) + { + } + +#if defined(ASIO_HAS_MOVE) + buffered_read_some_handler(const buffered_read_some_handler& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(other.handler_) + { + } + + buffered_read_some_handler(buffered_read_some_handler&& other) + : storage_(other.storage_), + buffers_(other.buffers_), + handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + void operator()(const asio::error_code& ec, std::size_t) + { + if (ec || storage_.empty()) + { + const std::size_t length = 0; + ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, length); + } + else + { + const std::size_t bytes_copied = asio::buffer_copy( + buffers_, storage_.data(), storage_.size()); + storage_.consume(bytes_copied); + ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_copied); + } + } + + //private: + detail::buffered_stream_storage& storage_; + MutableBufferSequence buffers_; + ReadHandler handler_; + }; + + template <typename MutableBufferSequence, typename ReadHandler> + inline asio_handler_allocate_is_deprecated + asio_handler_allocate(std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { +#if defined(ASIO_NO_DEPRECATED) + asio_handler_alloc_helpers::allocate(size, this_handler->handler_); + return asio_handler_allocate_is_no_longer_used(); +#else // defined(ASIO_NO_DEPRECATED) + return asio_handler_alloc_helpers::allocate( + size, this_handler->handler_); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename MutableBufferSequence, typename ReadHandler> + inline asio_handler_deallocate_is_deprecated + asio_handler_deallocate(void* pointer, std::size_t size, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_alloc_helpers::deallocate( + pointer, size, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_deallocate_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename MutableBufferSequence, typename ReadHandler> + inline bool asio_handler_is_continuation( + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + return asio_handler_cont_helpers::is_continuation( + this_handler->handler_); + } + + template <typename Function, typename MutableBufferSequence, + typename ReadHandler> + inline asio_handler_invoke_is_deprecated + asio_handler_invoke(Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_invoke_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename Function, typename MutableBufferSequence, + typename ReadHandler> + inline asio_handler_invoke_is_deprecated + asio_handler_invoke(const Function& function, + buffered_read_some_handler< + MutableBufferSequence, ReadHandler>* this_handler) + { + asio_handler_invoke_helpers::invoke( + function, this_handler->handler_); +#if defined(ASIO_NO_DEPRECATED) + return asio_handler_invoke_is_no_longer_used(); +#endif // defined(ASIO_NO_DEPRECATED) + } + + template <typename Stream> + class initiate_async_buffered_read_some + { + public: + typedef typename remove_reference< + Stream>::type::lowest_layer_type::executor_type executor_type; + + explicit initiate_async_buffered_read_some( + typename remove_reference<Stream>::type& next_layer) + : next_layer_(next_layer) + { + } + + executor_type get_executor() const ASIO_NOEXCEPT + { + return next_layer_.lowest_layer().get_executor(); + } + + template <typename ReadHandler, typename MutableBufferSequence> + void operator()(ASIO_MOVE_ARG(ReadHandler) handler, + buffered_stream_storage* storage, + const MutableBufferSequence& buffers) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + using asio::buffer_size; + non_const_lvalue<ReadHandler> handler2(handler); + if (buffer_size(buffers) == 0 || !storage->empty()) + { + next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0), + buffered_read_some_handler<MutableBufferSequence, + typename decay<ReadHandler>::type>( + *storage, buffers, handler2.value)); + } + else + { + initiate_async_buffered_fill<Stream>(this->next_layer_)( + buffered_read_some_handler<MutableBufferSequence, + typename decay<ReadHandler>::type>( + *storage, buffers, handler2.value), + storage); + } + } + + private: + typename remove_reference<Stream>::type& next_layer_; + }; +} // namespace detail + +#if !defined(GENERATING_DOCUMENTATION) + +template <template <typename, typename> class Associator, + typename MutableBufferSequence, typename ReadHandler, + typename DefaultCandidate> +struct associator<Associator, + detail::buffered_read_some_handler<MutableBufferSequence, ReadHandler>, + DefaultCandidate> + : Associator<ReadHandler, DefaultCandidate> +{ + static typename Associator<ReadHandler, DefaultCandidate>::type get( + const detail::buffered_read_some_handler< + MutableBufferSequence, ReadHandler>& h, + const DefaultCandidate& c = DefaultCandidate()) ASIO_NOEXCEPT + { + return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); + } +}; + +#endif // !defined(GENERATING_DOCUMENTATION) + +template <typename Stream> +template <typename MutableBufferSequence, + ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, + std::size_t)) ReadHandler> +ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) +buffered_read_stream<Stream>::async_read_some( + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) +{ + return async_initiate<ReadHandler, + void (asio::error_code, std::size_t)>( + detail::initiate_async_buffered_read_some<Stream>(next_layer_), + handler, &storage_, buffers); +} + +template <typename Stream> +template <typename MutableBufferSequence> +std::size_t buffered_read_stream<Stream>::peek( + const MutableBufferSequence& buffers) +{ + if (storage_.empty()) + this->fill(); + return this->peek_copy(buffers); +} + +template <typename Stream> +template <typename MutableBufferSequence> +std::size_t buffered_read_stream<Stream>::peek( + const MutableBufferSequence& buffers, asio::error_code& ec) +{ + ec = asio::error_code(); + if (storage_.empty() && !this->fill(ec)) + return 0; + return this->peek_copy(buffers); +} + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IMPL_BUFFERED_READ_STREAM_HPP |