diff options
Diffstat (limited to 'boost/beast/experimental')
21 files changed, 0 insertions, 4798 deletions
diff --git a/boost/beast/experimental/core/detail/flat_stream.hpp b/boost/beast/experimental/core/detail/flat_stream.hpp deleted file mode 100644 index 3a56897b5a..0000000000 --- a/boost/beast/experimental/core/detail/flat_stream.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_DETAIL_FLAT_STREAM_HPP -#define BOOST_BEAST_CORE_DETAIL_FLAT_STREAM_HPP - -#include <boost/asio/buffer.hpp> -#include <cstdlib> -#include <iterator> - -namespace boost { -namespace beast { -namespace detail { - -class flat_stream_base -{ -public: - // Largest buffer size we will flatten. - // 16KB is the upper limit on reasonably sized HTTP messages. - static std::size_t constexpr coalesce_limit = 16 * 1024; - - // calculates the coalesce settings for a buffer sequence - template<class BufferSequence> - static - std::pair<std::size_t, bool> - coalesce(BufferSequence const& buffers, std::size_t limit) - { - std::pair<std::size_t, bool> result{0, false}; - auto first = boost::asio::buffer_sequence_begin(buffers); - auto last = boost::asio::buffer_sequence_end(buffers); - if(first != last) - { - result.first = boost::asio::buffer_size(*first); - if(result.first < limit) - { - auto it = first; - auto prev = first; - while(++it != last) - { - auto const n = - boost::asio::buffer_size(*it); - if(result.first + n > limit) - break; - result.first += n; - prev = it; - } - result.second = prev != first; - } - } - return result; - } -}; - -} // detail -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/detail/impl/timeout_service.ipp b/boost/beast/experimental/core/detail/impl/timeout_service.ipp deleted file mode 100644 index fd1427bda7..0000000000 --- a/boost/beast/experimental/core/detail/impl/timeout_service.ipp +++ /dev/null @@ -1,181 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_DETAIL_IMPL_TIMEOUT_SERVICE_IPP -#define BOOST_BEAST_CORE_DETAIL_IMPL_TIMEOUT_SERVICE_IPP - -namespace boost { -namespace beast { -namespace detail { - -//------------------------------------------------------------------------------ - -inline -timeout_object:: -timeout_object(boost::asio::io_context& ioc) - : svc_(boost::asio::use_service<timeout_service>(ioc)) -{ -} - -//------------------------------------------------------------------------------ - -inline -timeout_service:: -timeout_service(boost::asio::io_context& ctx) - : service_base(ctx) - , strand_(ctx.get_executor()) - , timer_(ctx) -{ -} - -inline -void -timeout_service:: -on_work_started(timeout_object& obj) -{ - std::lock_guard<std::mutex> lock(m_); - BOOST_VERIFY(++obj.outstanding_work_ == 1); - insert(obj, *fresh_); - if(++count_ == 1) - do_async_wait(); -} - -inline -void -timeout_service:: -on_work_complete(timeout_object& obj) -{ - std::lock_guard<std::mutex> lock(m_); - remove(obj); -} - -inline -void -timeout_service:: -on_work_stopped(timeout_object& obj) -{ - std::lock_guard<std::mutex> lock(m_); - BOOST_ASSERT(count_ > 0); - BOOST_VERIFY(--obj.outstanding_work_ == 0); - if(obj.list_ != nullptr) - remove(obj); - if(--count_ == 0) - timer_.cancel(); -} - -inline -void -timeout_service:: -set_option(std::chrono::seconds n) -{ - interval_ = n; -} - -//------------------------------------------------------------------------------ - -// Precondition: caller holds the mutex -inline -void -timeout_service:: -insert(timeout_object& obj, list_type& list) -{ - BOOST_ASSERT(obj.list_ == nullptr); - list.push_back(&obj); // can throw - obj.list_ = &list; - obj.pos_ = list.size(); -} - -// Precondition: caller holds the mutex -inline -void -timeout_service:: -remove(timeout_object& obj) -{ - BOOST_ASSERT(obj.list_ != nullptr); - BOOST_ASSERT( - obj.list_ == stale_ || - obj.list_ == fresh_); - BOOST_ASSERT(obj.list_->size() > 0); - auto& list = *obj.list_; - auto const n = list.size() - 1; - if(obj.pos_ != n) - { - auto other = list[n]; - list[obj.pos_] = other; - other->pos_ = obj.pos_; - } - obj.list_ = nullptr; - list.resize(n); -} - -inline -void -timeout_service:: -do_async_wait() -{ - timer_.expires_after(interval_); - timer_.async_wait( - boost::asio::bind_executor( - strand_, - [this](error_code ec) - { - this->on_timer(ec); - })); -} - -inline -void -timeout_service:: -on_timer(error_code ec) -{ - if(ec == boost::asio::error::operation_aborted) - { - BOOST_ASSERT(fresh_->empty()); - BOOST_ASSERT(stale_->empty()); - return; - } - - { - std::lock_guard<std::mutex> lock(m_); - if(! stale_->empty()) - { - for(auto obj : *stale_) - { - obj->list_ = nullptr; - obj->on_timeout(); - } - stale_->clear(); - } - std::swap(fresh_, stale_); - } - - do_async_wait(); -} - -//------------------------------------------------------------------------------ - -inline -void -timeout_service:: -shutdown() noexcept -{ - boost::asio::post( - boost::asio::bind_executor( - strand_, - [this]() - { - timer_.cancel(); - })); -} - -} // detail -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/detail/service_base.hpp b/boost/beast/experimental/core/detail/service_base.hpp deleted file mode 100644 index 278db3f71d..0000000000 --- a/boost/beast/experimental/core/detail/service_base.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_DETAIL_SERVICE_BASE_HPP -#define BOOST_BEAST_CORE_DETAIL_SERVICE_BASE_HPP - -#include <boost/asio/execution_context.hpp> - -namespace boost { -namespace beast { -namespace detail { - -template<class T> -class service_id : public boost::asio::execution_context::id -{ -}; - -template<class T> -class service_base - : public boost::asio::execution_context::service -{ -protected: - boost::asio::execution_context& ctx_; - -public: - static service_id<T> id; - - explicit - service_base(boost::asio::execution_context& ctx) - : boost::asio::execution_context::service(ctx) - , ctx_(ctx) - { - } -}; - -template<class T> -service_id<T> -service_base<T>::id; - -} // detail -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/detail/timeout_service.hpp b/boost/beast/experimental/core/detail/timeout_service.hpp deleted file mode 100644 index b32cedda00..0000000000 --- a/boost/beast/experimental/core/detail/timeout_service.hpp +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_DETAIL_TIMEOUT_SERVICE_HPP -#define BOOST_BEAST_CORE_DETAIL_TIMEOUT_SERVICE_HPP - -#include <boost/beast/core/error.hpp> -#include <boost/beast/experimental/core/detail/service_base.hpp> -#include <boost/assert.hpp> -#include <boost/core/ignore_unused.hpp> -#include <boost/asio/bind_executor.hpp> -#include <boost/asio/executor.hpp> -#include <boost/asio/io_context.hpp> -#include <boost/asio/post.hpp> -#include <boost/asio/steady_timer.hpp> -#include <boost/asio/strand.hpp> -#include <chrono> -#include <cstdlib> -#include <mutex> -#include <utility> -#include <vector> - -namespace boost { -namespace beast { -namespace detail { - -//------------------------------------------------------------------------------ - -class timeout_service; - -class timeout_object -{ - friend class timeout_service; - - using list_type = std::vector<timeout_object*>; - - timeout_service& svc_; - std::size_t pos_; - list_type* list_ = nullptr; - char outstanding_work_ = 0; - -public: - timeout_object() = delete; - timeout_object(timeout_object&&) = delete; - timeout_object(timeout_object const&) = delete; - timeout_object& operator=(timeout_object&&) = delete; - timeout_object& operator=(timeout_object const&) = delete; - - // VFALCO should be execution_context - explicit - timeout_object(boost::asio::io_context& ioc); - - timeout_service& - service() const - { - return svc_; - } - - virtual void on_timeout() = 0; -}; - -//------------------------------------------------------------------------------ - -class timeout_service - : public service_base<timeout_service> -{ -public: - using key_type = timeout_service; - - // VFALCO Should be execution_context - explicit - timeout_service(boost::asio::io_context& ctx); - - void - on_work_started(timeout_object& obj); - - void - on_work_complete(timeout_object& obj); - - void - on_work_stopped(timeout_object& obj); - - void - set_option(std::chrono::seconds n); - -private: - friend class timeout_object; - - using list_type = std::vector<timeout_object*>; - - void insert(timeout_object& obj, list_type& list); - void remove(timeout_object& obj); - void do_async_wait(); - void on_timer(error_code ec); - - virtual void shutdown() noexcept override; - - boost::asio::strand< - boost::asio::io_context::executor_type> strand_; - - std::mutex m_; - list_type list_[2]; - list_type* fresh_ = &list_[0]; - list_type* stale_ = &list_[1]; - std::size_t count_ = 0; - boost::asio::steady_timer timer_; - std::chrono::seconds interval_{30ul}; -}; - -//------------------------------------------------------------------------------ - -} // detail -} // beast -} // boost - -#include <boost/beast/experimental/core/detail/impl/timeout_service.ipp> - -#endif diff --git a/boost/beast/experimental/core/detail/timeout_work_guard.hpp b/boost/beast/experimental/core/detail/timeout_work_guard.hpp deleted file mode 100644 index 463567ae78..0000000000 --- a/boost/beast/experimental/core/detail/timeout_work_guard.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_DETAIL_TIMEOUT_WORK_GUARD_HPP -#define BOOST_BEAST_CORE_DETAIL_TIMEOUT_WORK_GUARD_HPP - -#include <boost/beast/experimental/core/detail/timeout_service.hpp> -#include <boost/assert.hpp> -#include <boost/core/exchange.hpp> - -namespace boost { -namespace beast { -namespace detail { - -class timeout_work_guard -{ - timeout_object* obj_; - -public: - timeout_work_guard(timeout_work_guard const&) = delete; - timeout_work_guard& operator=(timeout_work_guard&&) = delete; - timeout_work_guard& operator=(timeout_work_guard const&) = delete; - - ~timeout_work_guard() - { - reset(); - } - - timeout_work_guard(timeout_work_guard&& other) - : obj_(boost::exchange(other.obj_, nullptr)) - { - } - - explicit - timeout_work_guard(timeout_object& obj) - : obj_(&obj) - { - obj_->service().on_work_started(*obj_); - } - - bool - owns_work() const - { - return obj_ != nullptr; - } - - void - reset() - { - if(obj_) - obj_->service().on_work_stopped(*obj_); - } - - void - complete() - { - BOOST_ASSERT(obj_ != nullptr); - obj_->service().on_work_complete(*obj_); - obj_ = nullptr; - } -}; - -} // detail -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/flat_stream.hpp b/boost/beast/experimental/core/flat_stream.hpp deleted file mode 100644 index ab22e544fb..0000000000 --- a/boost/beast/experimental/core/flat_stream.hpp +++ /dev/null @@ -1,354 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_FLAT_STREAM_HPP -#define BOOST_BEAST_CORE_FLAT_STREAM_HPP - -#include <boost/beast/core/detail/config.hpp> -#include <boost/beast/core/error.hpp> -#include <boost/beast/core/type_traits.hpp> -#include <boost/beast/experimental/core/detail/flat_stream.hpp> -#include <boost/asio/async_result.hpp> -#include <cstdlib> -#include <utility> - -namespace boost { -namespace beast { - -/** Stream wrapper to improve ssl::stream write performance. - - This wrapper flattens writes for buffer sequences having length - greater than 1 and total size below a predefined amount, using - a dynamic memory allocation. It is primarily designed to overcome - a performance limitation of the current version of `boost::asio::ssl::stream`, - which does not use OpenSSL's scatter/gather interface for its - low-level read some and write some operations. - - @par Example - - To use the @ref flat_stream template with SSL streams, declare - a variable of the correct type. Parameters passed to the constructor - will be forwarded to the next layer's constructor: - - @code - flat_stream<ssl::stream<ip::tcp::socket>> fs{ioc, ctx}; - @endcode - Alternatively you can write - @code - ssl::stream<ip::tcp::socket> ss{ioc, ctx}; - flat_stream<ssl::stream<ip::tcp::socket>&> fs{ss}; - @endcode - - The resulting stream may be passed to any stream algorithms which - operate on synchronous or asynchronous read or write streams, - examples include: - - @li `boost::asio::read`, `boost::asio::async_read` - - @li `boost::asio::write`, `boost::asio::async_write` - - @li `boost::asio::read_until`, `boost::asio::async_read_until` - - The stream may also be used as a template parameter in other - stream wrappers, such as for websocket: - @code - websocket::stream<flat_stream<ssl::stream<ip::tcp::socket>>> ws{ioc, ctx}; - @endcode - - @tparam NextLayer The type representing the next layer, to which - data will be read and written during operations. For synchronous - operations, the type must support the @b SyncStream concept. For - asynchronous operations, the type must support the @b AsyncStream - concept. This type will usually be some variation of - `boost::asio::ssl::stream`. - - @par Concepts - @b AsyncStream - @b SyncStream - - @see - @li https://github.com/boostorg/beast/issues/1108 - @li https://github.com/boostorg/asio/issues/100 - @li https://stackoverflow.com/questions/38198638/openssl-ssl-write-from-multiple-buffers-ssl-writev - @li https://stackoverflow.com/questions/50026167/performance-drop-on-port-from-beast-1-0-0-b66-to-boost-1-67-0-beast -*/ -template<class NextLayer> -class flat_stream -#if ! BOOST_BEAST_DOXYGEN - : private detail::flat_stream_base -#endif -{ - // Largest buffer size we will flatten. - // 16KB is the upper limit on reasonably sized HTTP messages. - static std::size_t constexpr max_size = 16 * 1024; - - template<class, class> class write_op; - - NextLayer stream_; - -public: - /// The type of the next layer. - using next_layer_type = - typename std::remove_reference<NextLayer>::type; - - /// The type of the lowest layer. - using lowest_layer_type = boost::beast::get_lowest_layer<next_layer_type>; - - /// The type of the executor associated with the object. - using executor_type = typename next_layer_type::executor_type; - - flat_stream(flat_stream&&) = default; - flat_stream(flat_stream const&) = default; - flat_stream& operator=(flat_stream&&) = default; - flat_stream& operator=(flat_stream const&) = default; - - /** Destructor - - The treatment of pending operations will be the same as that - of the next layer. - */ - ~flat_stream() = default; - - /** Constructor - - Arguments, if any, are forwarded to the next layer's constructor. - */ - template<class... Args> - explicit - flat_stream(Args&&... args); - - //-------------------------------------------------------------------------- - - /** Get the executor associated with the object. - - This function may be used to obtain the executor object that the - stream uses to dispatch handlers for asynchronous operations. - - @return A copy of the executor that stream will use to dispatch handlers. - */ - executor_type - get_executor() noexcept - { - return stream_.get_executor(); - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer - in a stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type& - next_layer() - { - return stream_; - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer in a - stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type const& - next_layer() const - { - return stream_; - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. - */ - lowest_layer_type& - lowest_layer() - { - return stream_.lowest_layer(); - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. Ownership is not transferred to the caller. - */ - lowest_layer_type const& - lowest_layer() const - { - return stream_.lowest_layer(); - } - - //-------------------------------------------------------------------------- - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @returns The number of bytes read. - - @throws boost::system::system_error Thrown on failure. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers); - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes read. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some( - MutableBufferSequence const& buffers, - error_code& ec); - - /** Start an asynchronous read. - - This function is used to asynchronously read one or more bytes of data from - the stream. The function call always returns immediately. - - @param buffers The buffers into which the data will be read. Although the - buffers object may be copied as necessary, ownership of the underlying - buffers is retained by the caller, which must guarantee that they remain - valid until the handler is called. - - @param handler The handler to be called when the read operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes read. - ); @endcode - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::async_read` if you need - to ensure that the requested amount of data is read before the asynchronous - operation completes. - */ - template< - class MutableBufferSequence, - class ReadHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) - async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @returns The number of bytes written. - - @throws boost::system::system_error Thrown on failure. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some(ConstBufferSequence const& buffers); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes written. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some( - ConstBufferSequence const& buffers, - error_code& ec); - - /** Start an asynchronous write. - - This function is used to asynchronously write one or more bytes of data to - the stream. The function call always returns immediately. - - @param buffers The data to be written to the stream. Although the buffers - object may be copied as necessary, ownership of the underlying buffers is - retained by the caller, which must guarantee that they remain valid until - the handler is called. - - @param handler The handler to be called when the write operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes written. - ); @endcode - - @note The `async_write_some` operation may not transmit all of the data to - the peer. Consider using the function `boost::asio::async_write` if you need - to ensure that all data is written before the asynchronous operation completes. - */ - template< - class ConstBufferSequence, - class WriteHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) - async_write_some( - ConstBufferSequence const& buffers, - WriteHandler&& handler); -}; - -} // beast -} // boost - -#include <boost/beast/experimental/core/impl/flat_stream.ipp> - -#endif diff --git a/boost/beast/experimental/core/impl/flat_stream.ipp b/boost/beast/experimental/core/impl/flat_stream.ipp deleted file mode 100644 index a94622f7cc..0000000000 --- a/boost/beast/experimental/core/impl/flat_stream.ipp +++ /dev/null @@ -1,309 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_IMPL_FLAT_STREAM_IPP -#define BOOST_BEAST_CORE_IMPL_FLAT_STREAM_IPP - -#include <boost/beast/core/buffers_prefix.hpp> -#include <boost/beast/websocket/teardown.hpp> -#include <boost/asio/associated_allocator.hpp> -#include <boost/asio/associated_executor.hpp> -#include <boost/asio/buffer.hpp> -#include <boost/asio/coroutine.hpp> -#include <boost/asio/handler_continuation_hook.hpp> -#include <boost/asio/handler_invoke_hook.hpp> - -namespace boost { -namespace beast { - -template<class NextLayer> -template<class ConstBufferSequence, class Handler> -class flat_stream<NextLayer>::write_op - : public boost::asio::coroutine -{ - using alloc_type = typename -#if defined(BOOST_NO_CXX11_ALLOCATOR) - boost::asio::associated_allocator_t<Handler>::template - rebind<char>::other; -#else - std::allocator_traits<boost::asio::associated_allocator_t<Handler>> - ::template rebind_alloc<char>; -#endif - - struct deleter - { - alloc_type alloc; - std::size_t size = 0; - - explicit - deleter(alloc_type const& alloc_) - : alloc(alloc_) - { - } - - void - operator()(char* p) - { - alloc.deallocate(p, size); - } - }; - - flat_stream<NextLayer>& s_; - ConstBufferSequence b_; - std::unique_ptr<char, deleter> p_; - Handler h_; - -public: - template<class DeducedHandler> - write_op( - flat_stream<NextLayer>& s, - ConstBufferSequence const& b, - DeducedHandler&& h) - : s_(s) - , b_(b) - , p_(nullptr, deleter{ - (boost::asio::get_associated_allocator)(h)}) - , h_(std::forward<DeducedHandler>(h)) - { - } - - using allocator_type = - boost::asio::associated_allocator_t<Handler>; - - allocator_type - get_allocator() const noexcept - { - return (boost::asio::get_associated_allocator)(h_); - } - - using executor_type = boost::asio::associated_executor_t< - Handler, decltype(std::declval<NextLayer&>().get_executor())>; - - executor_type - get_executor() const noexcept - { - return (boost::asio::get_associated_executor)( - h_, s_.get_executor()); - } - - void - operator()( - boost::system::error_code ec, - std::size_t bytes_transferred); - - friend - bool asio_handler_is_continuation(write_op* op) - { - using boost::asio::asio_handler_is_continuation; - return asio_handler_is_continuation( - std::addressof(op->h_)); - } - - template<class Function> - friend - void asio_handler_invoke(Function&& f, write_op* op) - { - using boost::asio::asio_handler_invoke; - asio_handler_invoke(f, std::addressof(op->h_)); - } -}; - -template<class NextLayer> -template<class ConstBufferSequence, class Handler> -void -flat_stream<NextLayer>:: -write_op<ConstBufferSequence, Handler>:: -operator()( - error_code ec, - std::size_t bytes_transferred) -{ - BOOST_ASIO_CORO_REENTER(*this) - { - BOOST_ASIO_CORO_YIELD - { - auto const result = coalesce(b_, coalesce_limit); - if(result.second) - { - p_.get_deleter().size = result.first; - p_.reset(p_.get_deleter().alloc.allocate( - p_.get_deleter().size)); - boost::asio::buffer_copy( - boost::asio::buffer( - p_.get(), p_.get_deleter().size), - b_, result.first); - s_.stream_.async_write_some( - boost::asio::buffer( - p_.get(), p_.get_deleter().size), - std::move(*this)); - } - else - { - s_.stream_.async_write_some( - boost::beast::buffers_prefix(result.first, b_), - std::move(*this)); - } - } - p_.reset(); - h_(ec, bytes_transferred); - } -} - -//------------------------------------------------------------------------------ - -template<class NextLayer> -template<class... Args> -flat_stream<NextLayer>:: -flat_stream(Args&&... args) - : stream_(std::forward<Args>(args)...) -{ -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -flat_stream<NextLayer>:: -read_some(MutableBufferSequence const& buffers) -{ - static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value, - "SyncReadStream requirements not met"); - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - error_code ec; - auto n = read_some(buffers, ec); - if(ec) - BOOST_THROW_EXCEPTION(boost::system::system_error{ec}); - return n; -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -flat_stream<NextLayer>:: -read_some(MutableBufferSequence const& buffers, error_code& ec) -{ - return stream_.read_some(buffers, ec); -} - -template<class NextLayer> -template< - class MutableBufferSequence, - class ReadHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) -flat_stream<NextLayer>:: -async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler) -{ - static_assert(boost::beast::is_async_read_stream<next_layer_type>::value, - "AsyncReadStream requirements not met"); - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence >::value, - "MutableBufferSequence requirements not met"); - return stream_.async_read_some( - buffers, std::forward<ReadHandler>(handler)); -} - -template<class NextLayer> -template<class ConstBufferSequence> -std::size_t -flat_stream<NextLayer>:: -write_some(ConstBufferSequence const& buffers) -{ - static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value, - "SyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - auto const result = coalesce(buffers, coalesce_limit); - if(result.second) - { - std::unique_ptr<char[]> p{new char[result.first]}; - auto const b = boost::asio::buffer(p.get(), result.first); - boost::asio::buffer_copy(b, buffers); - return stream_.write_some(b); - } - return stream_.write_some( - boost::beast::buffers_prefix(result.first, buffers)); -} - -template<class NextLayer> -template<class ConstBufferSequence> -std::size_t -flat_stream<NextLayer>:: -write_some(ConstBufferSequence const& buffers, error_code& ec) -{ - static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value, - "SyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - auto const result = coalesce(buffers, coalesce_limit); - if(result.second) - { - std::unique_ptr<char[]> p{new char[result.first]}; - auto const b = boost::asio::buffer(p.get(), result.first); - boost::asio::buffer_copy(b, buffers); - return stream_.write_some(b, ec); - } - return stream_.write_some( - boost::beast::buffers_prefix(result.first, buffers), ec); -} - -template<class NextLayer> -template< - class ConstBufferSequence, - class WriteHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) -flat_stream<NextLayer>:: -async_write_some( - ConstBufferSequence const& buffers, - WriteHandler&& handler) -{ - static_assert(boost::beast::is_async_write_stream<next_layer_type>::value, - "AsyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - BOOST_BEAST_HANDLER_INIT( - WriteHandler, void(error_code, std::size_t)); - write_op<ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE( - WriteHandler, void(error_code, std::size_t))>{ - *this, buffers, std::move(init.completion_handler)}({}, 0); - return init.result.get(); -} - -template<class NextLayer> -void -teardown( - boost::beast::websocket::role_type role, - flat_stream<NextLayer>& s, - error_code& ec) -{ - using boost::beast::websocket::teardown; - teardown(role, s.next_layer(), ec); -} - -template<class NextLayer, class TeardownHandler> -void -async_teardown( - boost::beast::websocket::role_type role, - flat_stream<NextLayer>& s, - TeardownHandler&& handler) -{ - using boost::beast::websocket::async_teardown; - async_teardown(role, s.next_layer(), std::move(handler)); -} - -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/impl/timeout_service.ipp b/boost/beast/experimental/core/impl/timeout_service.ipp deleted file mode 100644 index 4da0eed115..0000000000 --- a/boost/beast/experimental/core/impl/timeout_service.ipp +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_IMPL_TIMEOUT_SERVICE_HPP -#define BOOST_BEAST_CORE_IMPL_TIMEOUT_SERVICE_HPP - -#include <boost/beast/experimental/core/detail/timeout_service.hpp> - -namespace boost { -namespace beast { - -inline -void -set_timeout_service_options( - boost::asio::io_context& ioc, - std::chrono::seconds interval) -{ - boost::asio::use_service< - detail::timeout_service>(ioc).set_option(interval); -} - -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/impl/timeout_socket.hpp b/boost/beast/experimental/core/impl/timeout_socket.hpp deleted file mode 100644 index 8c5a7d7427..0000000000 --- a/boost/beast/experimental/core/impl/timeout_socket.hpp +++ /dev/null @@ -1,207 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_IMPL_TIMOUT_SOCKET_HPP -#define BOOST_BEAST_CORE_IMPL_TIMOUT_SOCKET_HPP - -#include <boost/beast/core/bind_handler.hpp> -#include <boost/beast/core/type_traits.hpp> -#include <boost/beast/experimental/core/detail/timeout_work_guard.hpp> -#include <boost/asio/executor_work_guard.hpp> -#include <memory> -#include <utility> - -namespace boost { -namespace beast { - -template<class Protocol, class Executor> -template<class Handler> -class basic_timeout_socket<Protocol, Executor>::async_op -{ - Handler h_; - basic_timeout_socket& s_; - detail::timeout_work_guard work_; - -public: - async_op(async_op&&) = default; - async_op(async_op const&) = delete; - - template<class Buffers, class DeducedHandler> - async_op( - Buffers const& b, - DeducedHandler&& h, - basic_timeout_socket& s, - std::true_type) - : h_(std::forward<DeducedHandler>(h)) - , s_(s) - , work_(s.rd_timer_) - { - s_.sock_.async_read_some(b, std::move(*this)); - } - - template<class Buffers, class DeducedHandler> - async_op( - Buffers const& b, - DeducedHandler&& h, - basic_timeout_socket& s, - std::false_type) - : h_(std::forward<DeducedHandler>(h)) - , s_(s) - , work_(s.wr_timer_) - { - s_.sock_.async_write_some(b, std::move(*this)); - } - - using allocator_type = - boost::asio::associated_allocator_t<Handler>; - - allocator_type - get_allocator() const noexcept - { - return (boost::asio::get_associated_allocator)(h_); - } - - using executor_type = - boost::asio::associated_executor_t<Handler, decltype( - std::declval<basic_timeout_socket<Protocol>&>().get_executor())>; - - executor_type - get_executor() const noexcept - { - return (boost::asio::get_associated_executor)( - h_, s_.get_executor()); - } - - friend - bool asio_handler_is_continuation(async_op* op) - { - using boost::asio::asio_handler_is_continuation; - return asio_handler_is_continuation( - std::addressof(op->h_)); - } - - template<class Function> - friend - void asio_handler_invoke(Function&& f, async_op* op) - { - using boost::asio::asio_handler_invoke; - asio_handler_invoke(f, std::addressof(op->h_)); - } - - void - operator()(error_code ec, std::size_t bytes_transferred) - { - if(s_.expired_) - { - BOOST_ASSERT(ec == boost::asio::error::operation_aborted); - ec = boost::asio::error::timed_out; - } - else - { - work_.complete(); - } - h_(ec, bytes_transferred); - } -}; - -//------------------------------------------------------------------------------ - -template<class Protocol, class Executor> -basic_timeout_socket<Protocol, Executor>:: -timer:: -timer(basic_timeout_socket& s) - : detail::timeout_object(s.ex_.context()) - , s_(s) -{ -} - -template<class Protocol, class Executor> -auto -basic_timeout_socket<Protocol, Executor>:: -timer:: -operator=(timer&&) - -> timer& -{ - return *this; -} - -template<class Protocol, class Executor> -void -basic_timeout_socket<Protocol, Executor>:: -timer:: -on_timeout() -{ - boost::asio::post( - s_.ex_, - [this]() - { - s_.expired_ = true; - s_.sock_.cancel(); - }); -} - -//------------------------------------------------------------------------------ - -template<class Protocol, class Executor> -template<class ExecutionContext, class> -basic_timeout_socket<Protocol, Executor>:: -basic_timeout_socket(ExecutionContext& ctx) - : ex_(ctx.get_executor()) - , rd_timer_(*this) - , wr_timer_(*this) - , sock_(ctx) -{ -} - -template<class Protocol, class Executor> -template<class MutableBufferSequence, class ReadHandler> -BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void(boost::system::error_code, std::size_t)) -basic_timeout_socket<Protocol, Executor>:: -async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler) -{ - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - BOOST_BEAST_HANDLER_INIT( - ReadHandler, void(error_code, std::size_t)); - async_op<BOOST_ASIO_HANDLER_TYPE(ReadHandler, - void(error_code, std::size_t))>(buffers, - std::forward<ReadHandler>(handler), *this, - std::true_type{}); - return init.result.get(); -} - -template<class Protocol, class Executor> -template<class ConstBufferSequence, class WriteHandler> -BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void(boost::system::error_code, std::size_t)) -basic_timeout_socket<Protocol, Executor>:: -async_write_some( - ConstBufferSequence const& buffers, - WriteHandler&& handler) -{ - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - BOOST_BEAST_HANDLER_INIT( - WriteHandler, void(error_code, std::size_t)); - async_op<BOOST_ASIO_HANDLER_TYPE(WriteHandler, - void(error_code, std::size_t))>(buffers, - std::forward<WriteHandler>(handler), *this, - std::false_type{}); - return init.result.get(); -} - -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/ssl_stream.hpp b/boost/beast/experimental/core/ssl_stream.hpp deleted file mode 100644 index b61bfbdef4..0000000000 --- a/boost/beast/experimental/core/ssl_stream.hpp +++ /dev/null @@ -1,730 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_SSL_STREAM_HPP -#define BOOST_BEAST_CORE_SSL_STREAM_HPP - -#include <boost/beast/core/detail/config.hpp> - -// This include is necessary to work with `ssl::stream` and `boost::beast::websocket::stream` -#include <boost/beast/websocket/ssl.hpp> - -#include <boost/beast/experimental/core/flat_stream.hpp> -#include <boost/asio/ssl/stream.hpp> -#include <cstddef> -#include <memory> -#include <type_traits> -#include <utility> - -namespace boost { -namespace beast { - -/** Provides stream-oriented functionality using OpenSSL - - The stream class template provides asynchronous and blocking - stream-oriented functionality using SSL. - - @par Thread Safety - @e Distinct @e objects: Safe.@n - @e Shared @e objects: Unsafe. The application must also ensure that all - asynchronous operations are performed within the same implicit or explicit - strand. - - @par Example - To use this template with a `boost::asio::ip::tcp::socket`, you would write: - @code - boost::asio::io_context ioc; - boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23}; - boost::beast::ssl_stream<boost::asio:ip::tcp::socket> sock{ioc, ctx}; - @endcode - - In addition to providing an interface identical to `boost::asio::ssl::stream`, - the wrapper has the following additional properties: - - @li Satisfies @b MoveConstructible - - @li Satisfies @b MoveAssignable - - @li Constructible from a moved socket. - - @li Uses @ref flat_stream internally, as a performance work-around for a - limitation of `boost::asio::ssl::stream` when writing buffer sequences - having length greater than one. - - @par Concepts: - @li AsyncReadStream - @li AsyncWriteStream - @li Stream - @li SyncReadStream - @li SyncWriteStream -*/ -template<class NextLayer> -class ssl_stream - : public boost::asio::ssl::stream_base -{ - using ssl_stream_type = boost::asio::ssl::stream<NextLayer>; - using stream_type = boost::beast::flat_stream<ssl_stream_type>; - - std::unique_ptr<stream_type> p_; - boost::asio::ssl::context* ctx_; - -public: - /// The native handle type of the SSL stream. - using native_handle_type = - typename ssl_stream_type::native_handle_type; - - /// Structure for use with deprecated impl_type. - using impl_struct = typename ssl_stream_type::impl_struct; - - /// The type of the next layer. - using next_layer_type = typename ssl_stream_type::next_layer_type; - - /// The type of the lowest layer. - using lowest_layer_type = typename ssl_stream_type::lowest_layer_type; - - /// The type of the executor associated with the object. - using executor_type = typename stream_type::executor_type; - - /** Construct a stream. - - This constructor creates a stream and initialises the underlying stream - object. - - @param arg The argument to be passed to initialise the underlying stream. - - @param ctx The SSL context to be used for the stream. - */ - template<class Arg> - ssl_stream( - Arg&& arg, - boost::asio::ssl::context& ctx) - : p_(new stream_type{ - std::forward<Arg>(arg), ctx}) - , ctx_(&ctx) - { - } - - /// Move Constructor - ssl_stream(ssl_stream&& other) - : p_(std::move(other.p_)) - , ctx_(other.ctx_) - { - } - - /// Move Assignment - ssl_stream& operator=(ssl_stream&& other) - { - p_ = std::move(other.p_); - ctx_ = other.ctx_; - return *this; - } - - /** Get the executor associated with the object. - - This function may be used to obtain the executor object that the stream - uses to dispatch handlers for asynchronous operations. - - @return A copy of the executor that stream will use to dispatch handlers. - */ - executor_type - get_executor() noexcept - { - return p_->get_executor(); - } - - /** Get the underlying implementation in the native type. - - This function may be used to obtain the underlying implementation of the - context. This is intended to allow access to context functionality that is - not otherwise provided. - - @par Example - The native_handle() function returns a pointer of type @c SSL* that is - suitable for passing to functions such as @c SSL_get_verify_result and - @c SSL_get_peer_certificate: - @code - boost::beast::ssl_stream<boost::asio:ip::tcp::socket> ss{ioc, ctx}; - - // ... establish connection and perform handshake ... - - if (X509* cert = SSL_get_peer_certificate(ss.native_handle())) - { - if (SSL_get_verify_result(ss.native_handle()) == X509_V_OK) - { - // ... - } - } - @endcode - */ - native_handle_type - native_handle() - { - return p_->next_layer().native_handle(); - } - - /** Get a reference to the next layer. - - This function returns a reference to the next layer in a stack of stream - layers. - - @note The next layer is the wrapped stream and not the @ref flat_stream - used in the implementation. - - @return A reference to the next layer in the stack of stream layers. - Ownership is not transferred to the caller. - */ - next_layer_type const& - next_layer() const - { - return p_->next_layer().next_layer(); - } - - /** Get a reference to the next layer. - - This function returns a reference to the next layer in a stack of stream - layers. - - @note The next layer is the wrapped stream and not the @ref flat_stream - used in the implementation. - - @return A reference to the next layer in the stack of stream layers. - Ownership is not transferred to the caller. - */ - next_layer_type& - next_layer() - { - return p_->next_layer().next_layer(); - } - - /** Get a reference to the lowest layer. - - This function returns a reference to the lowest layer in a stack of stream - layers. - - @return A reference to the lowest layer in the stack of stream layers. - Ownership is not transferred to the caller. - */ - lowest_layer_type& - lowest_layer() - { - return p_->lowest_layer(); - } - - /** Get a reference to the lowest layer. - - This function returns a reference to the lowest layer in a stack of stream - layers. - - @return A reference to the lowest layer in the stack of stream layers. - Ownership is not transferred to the caller. - */ - lowest_layer_type const& - lowest_layer() const - { - return p_->lowest_layer(); - } - - /** Set the peer verification mode. - - This function may be used to configure the peer verification mode used by - the stream. The new mode will override the mode inherited from the context. - - @param v A bitmask of peer verification modes. - - @throws boost::system::system_error Thrown on failure. - - @note Calls @c SSL_set_verify. - */ - void - set_verify_mode(boost::asio::ssl::verify_mode v) - { - p_->next_layer().set_verify_mode(v); - } - - /** Set the peer verification mode. - - This function may be used to configure the peer verification mode used by - the stream. The new mode will override the mode inherited from the context. - - @param v A bitmask of peer verification modes. See `verify_mode` for - available values. - - @param ec Set to indicate what error occurred, if any. - - @note Calls @c SSL_set_verify. - */ - boost::system::error_code - set_verify_mode(boost::asio::ssl::verify_mode v, - boost::system::error_code& ec) - { - return p_->next_layer().set_verify_mode(v, ec); - } - - /** Set the peer verification depth. - - This function may be used to configure the maximum verification depth - allowed by the stream. - - @param depth Maximum depth for the certificate chain verification that - shall be allowed. - - @throws boost::system::system_error Thrown on failure. - - @note Calls @c SSL_set_verify_depth. - */ - void - set_verify_depth(int depth) - { - p_->next_layer().set_verify_depth(depth); - } - - /** Set the peer verification depth. - - This function may be used to configure the maximum verification depth - allowed by the stream. - - @param depth Maximum depth for the certificate chain verification that - shall be allowed. - - @param ec Set to indicate what error occurred, if any. - - @note Calls @c SSL_set_verify_depth. - */ - boost::system::error_code - set_verify_depth( - int depth, boost::system::error_code& ec) - { - return p_->next_layer().set_verify_depth(depth, ec); - } - - /** Set the callback used to verify peer certificates. - - This function is used to specify a callback function that will be called - by the implementation when it needs to verify a peer certificate. - - @param callback The function object to be used for verifying a certificate. - The function signature of the handler must be: - @code bool verify_callback( - bool preverified, // True if the certificate passed pre-verification. - verify_context& ctx // The peer certificate and other context. - ); @endcode - The return value of the callback is true if the certificate has passed - verification, false otherwise. - - @throws boost::system::system_error Thrown on failure. - - @note Calls @c SSL_set_verify. - */ - template<class VerifyCallback> - void - set_verify_callback(VerifyCallback callback) - { - p_->next_layer().set_verify_callback(callback); - } - - /** Set the callback used to verify peer certificates. - - This function is used to specify a callback function that will be called - by the implementation when it needs to verify a peer certificate. - - @param callback The function object to be used for verifying a certificate. - The function signature of the handler must be: - @code bool verify_callback( - bool preverified, // True if the certificate passed pre-verification. - boost::asio::verify_context& ctx // The peer certificate and other context. - ); @endcode - The return value of the callback is true if the certificate has passed - verification, false otherwise. - - @param ec Set to indicate what error occurred, if any. - - @note Calls @c SSL_set_verify. - */ - template<class VerifyCallback> - boost::system::error_code - set_verify_callback(VerifyCallback callback, - boost::system::error_code& ec) - { - return p_->next_layer().set_verify_callback(callback, ec); - } - - /** Perform SSL handshaking. - - This function is used to perform SSL handshaking on the stream. The - function call will block until handshaking is complete or an error occurs. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @throws boost::system::system_error Thrown on failure. - */ - void - handshake(handshake_type type) - { - p_->next_layer().handshake(type); - } - - /** Perform SSL handshaking. - - This function is used to perform SSL handshaking on the stream. The - function call will block until handshaking is complete or an error occurs. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code - handshake(handshake_type type, - boost::system::error_code& ec) - { - return p_->next_layer().handshake(type, ec); - } - - /** Perform SSL handshaking. - - This function is used to perform SSL handshaking on the stream. The - function call will block until handshaking is complete or an error occurs. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @param buffers The buffered data to be reused for the handshake. - - @throws boost::system::system_error Thrown on failure. - */ - template<class ConstBufferSequence> - void - handshake( - handshake_type type, ConstBufferSequence const& buffers) - { - p_->next_layer().handshake(type, buffers); - } - - /** Perform SSL handshaking. - - This function is used to perform SSL handshaking on the stream. The - function call will block until handshaking is complete or an error occurs. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @param buffers The buffered data to be reused for the handshake. - - @param ec Set to indicate what error occurred, if any. - */ - template<class ConstBufferSequence> - boost::system::error_code - handshake(handshake_type type, - ConstBufferSequence const& buffers, - boost::system::error_code& ec) - { - return p_->next_layer().handshake(type, buffers, ec); - } - - /** Start an asynchronous SSL handshake. - - This function is used to asynchronously perform an SSL handshake on the - stream. This function call always returns immediately. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @param handler The handler to be called when the handshake operation - completes. Copies will be made of the handler as required. The equivalent - function signature of the handler must be: - @code void handler( - const boost::system::error_code& error // Result of operation. - ); @endcode - */ - template<class HandshakeHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, - void(boost::system::error_code)) - async_handshake(handshake_type type, - BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) - { - return p_->next_layer().async_handshake(type, - BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)); - } - - /** Start an asynchronous SSL handshake. - - This function is used to asynchronously perform an SSL handshake on the - stream. This function call always returns immediately. - - @param type The type of handshaking to be performed, i.e. as a client or as - a server. - - @param buffers The buffered data to be reused for the handshake. Although - the buffers object may be copied as necessary, ownership of the underlying - buffers is retained by the caller, which must guarantee that they remain - valid until the handler is called. - - @param handler The handler to be called when the handshake operation - completes. Copies will be made of the handler as required. The equivalent - function signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Amount of buffers used in handshake. - ); @endcode - */ - template<class ConstBufferSequence, class BufferedHandshakeHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, - void (boost::system::error_code, std::size_t)) - async_handshake(handshake_type type, ConstBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) - { - return p_->next_layer().async_handshake(type, buffers, - BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)); - } - - /** Shut down SSL on the stream. - - This function is used to shut down SSL on the stream. The function call - will block until SSL has been shut down or an error occurs. - - @throws boost::system::system_error Thrown on failure. - */ - void - shutdown() - { - p_->next_layer().shutdown(); - } - - /** Shut down SSL on the stream. - - This function is used to shut down SSL on the stream. The function call - will block until SSL has been shut down or an error occurs. - - @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code - shutdown(boost::system::error_code& ec) - { - return p_->next_layer().shutdown(ec); - } - - /** Asynchronously shut down SSL on the stream. - - This function is used to asynchronously shut down SSL on the stream. This - function call always returns immediately. - - @param handler The handler to be called when the handshake operation - completes. Copies will be made of the handler as required. The equivalent - function signature of the handler must be: - @code void handler( - const boost::system::error_code& error // Result of operation. - ); @endcode - */ - template<class ShutdownHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler, - void (boost::system::error_code)) - async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) - { - return p_->next_layer().async_shutdown( - BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)); - } - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @returns The number of bytes written. - - @throws boost::system::system_error Thrown on failure. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the `boost::asio::write` function if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some(ConstBufferSequence const& buffers) - { - return p_->write_some(buffers); - } - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written to the stream. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes written. Returns 0 if an error occurred. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the `boost::asio::write` function if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some(ConstBufferSequence const& buffers, - boost::system::error_code& ec) - { - return p_->write_some(buffers, ec); - } - - /** Start an asynchronous write. - - This function is used to asynchronously write one or more bytes of data to - the stream. The function call always returns immediately. - - @param buffers The data to be written to the stream. Although the buffers - object may be copied as necessary, ownership of the underlying buffers is - retained by the caller, which must guarantee that they remain valid until - the handler is called. - - @param handler The handler to be called when the write operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes written. - ); @endcode - - @note The `async_write_some` operation may not transmit all of the data to - the peer. Consider using the `boost::asio::async_write` function if you - need to ensure that all data is written before the asynchronous operation - completes. - */ - template<class ConstBufferSequence, class WriteHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_write_some(ConstBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return p_->async_write_some(buffers, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @returns The number of bytes read. - - @throws boost::system::system_error Thrown on failure. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the `boost::asio::read` function if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers) - { - return p_->read_some(buffers); - } - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes read. Returns 0 if an error occurred. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the `boost::asio::read` function if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers, - boost::system::error_code& ec) - { - return p_->read_some(buffers, ec); - } - - /** Start an asynchronous read. - - This function is used to asynchronously read one or more bytes of data from - the stream. The function call always returns immediately. - - @param buffers The buffers into which the data will be read. Although the - buffers object may be copied as necessary, ownership of the underlying - buffers is retained by the caller, which must guarantee that they remain - valid until the handler is called. - - @param handler The handler to be called when the read operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes read. - ); @endcode - - @note The `async_read_some` operation may not read all of the requested - number of bytes. Consider using the `boost::asio::async_read` function - if you need to ensure that the requested amount of data is read before - the asynchronous operation completes. - */ - template<class MutableBufferSequence, class ReadHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void(boost::system::error_code, std::size_t)) - async_read_some(MutableBufferSequence const& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return p_->async_read_some(buffers, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } -}; - -// These hooks are used to inform boost::beast::websocket::stream on -// how to tear down the connection as part of the WebSocket -// protocol specifications -#if ! BOOST_BEAST_DOXYGEN -template<class SyncStream> -void -teardown( - boost::beast::websocket::role_type role, - ssl_stream<SyncStream>& stream, - boost::system::error_code& ec) -{ - // Just forward it to the wrapped stream - using boost::beast::websocket::teardown; - teardown(role, stream.next_layer(), ec); -} - -template<class AsyncStream, class TeardownHandler> -void -async_teardown( - boost::beast::websocket::role_type role, - ssl_stream<AsyncStream>& stream, - TeardownHandler&& handler) -{ - // Just forward it to the wrapped stream - using boost::beast::websocket::async_teardown; - async_teardown(role, - stream.next_layer(), std::forward<TeardownHandler>(handler)); -} -#endif - -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/core/timeout_service.hpp b/boost/beast/experimental/core/timeout_service.hpp deleted file mode 100644 index 2a5da2b887..0000000000 --- a/boost/beast/experimental/core/timeout_service.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_TIMEOUT_SERVICE_HPP -#define BOOST_BEAST_CORE_TIMEOUT_SERVICE_HPP - -//#include <boost/asio/execution_context.hpp> -#include <boost/asio/io_context.hpp> -#include <chrono> - -namespace boost { -namespace beast { - -/** Set timeout service options in an execution context. - - This changes the time interval for all timeouts associated - with the execution context. The option must be set before any - timeout objects are constructed. - - @param ctx The execution context. - - @param interval The approximate amount of time until a timeout occurs. -*/ -void -set_timeout_service_options( - boost::asio::io_context& ctx, // VFALCO should be execution_context - std::chrono::seconds interval); - -} // beast -} // boost - -#include <boost/beast/experimental/core/impl/timeout_service.ipp> - -#endif diff --git a/boost/beast/experimental/core/timeout_socket.hpp b/boost/beast/experimental/core/timeout_socket.hpp deleted file mode 100644 index b2c2a22ea5..0000000000 --- a/boost/beast/experimental/core/timeout_socket.hpp +++ /dev/null @@ -1,240 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_TIMEOUT_SOCKET_HPP -#define BOOST_BEAST_CORE_TIMEOUT_SOCKET_HPP - -#include <boost/beast/core/detail/config.hpp> -#include <boost/beast/core/error.hpp> -#include <boost/beast/core/type_traits.hpp> -#include <boost/beast/experimental/core/detail/timeout_service.hpp> -#include <boost/asio/async_result.hpp> -#include <boost/asio/basic_stream_socket.hpp> -#include <boost/asio/executor.hpp> -#include <chrono> - -namespace boost { -namespace asio { -namespace ip { -class tcp; -} // ip -} // asio -} // boost - -namespace boost { -namespace beast { - -/** A socket wrapper which automatically times out on asynchronous reads. - - This wraps a normal stream socket and implements a simple and efficient - timeout for asynchronous read operations. - - @note Meets the requirements of @b AsyncReadStream and @b AsyncWriteStream -*/ -template< - class Protocol, - class Executor = boost::asio::executor -> -class basic_timeout_socket -{ - template<class> class async_op; - - class timer : public detail::timeout_object - { - basic_timeout_socket& s_; - - public: - explicit timer(basic_timeout_socket& s); - timer& operator=(timer&& other); - void on_timeout() override; - }; - - Executor ex_; // must come first - timer rd_timer_; - timer wr_timer_; - boost::asio::basic_stream_socket<Protocol> sock_; - bool expired_ = false; - -public: - /// The type of the next layer. - using next_layer_type = boost::asio::basic_stream_socket<Protocol>; - - /// The type of the lowest layer. - using lowest_layer_type = get_lowest_layer<next_layer_type>; - - /// The protocol used by the stream. - using protocol_type = Protocol; - - /// The type of the executor associated with the object. - using executor_type = Executor; - - // VFALCO we only support default-construction - // of the contained socket for now. - // This constructor needs a protocol parameter. - // - /** Constructor - */ - template<class ExecutionContext -#if ! BOOST_BEAST_DOXYGEN - , class = typename std::enable_if< - std::is_convertible< - ExecutionContext&, - boost::asio::execution_context&>::value && - std::is_constructible< - executor_type, - typename ExecutionContext::executor_type>::value - >::type -#endif - > - explicit - basic_timeout_socket(ExecutionContext& ctx); - - //-------------------------------------------------------------------------- - - /** Get the executor associated with the object. - - This function may be used to obtain the executor object that the - stream uses to dispatch handlers for asynchronous operations. - - @return A copy of the executor that stream will use to dispatch handlers. - */ - executor_type - get_executor() const noexcept - { - return ex_; - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer - in a stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type& - next_layer() - { - return sock_; - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer in a - stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type const& - next_layer() const - { - return sock_; - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. - */ - lowest_layer_type& - lowest_layer() - { - return sock_.lowest_layer(); - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. Ownership is not transferred to the caller. - */ - lowest_layer_type const& - lowest_layer() const - { - return sock_.lowest_layer(); - } - - //-------------------------------------------------------------------------- - - /** Start an asynchronous read. - - This function is used to asynchronously read data from the stream socket. - The function call always returns immediately. - - @param buffers One or more buffers into which the data will be read. - Although the buffers object may be copied as necessary, ownership of the - underlying memory blocks is retained by the caller, which must guarantee - that they remain valid until the handler is called. - - @param handler The handler to be called when the read operation completes. - Copies will be made of the handler as required. The function signature of - the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes read. - ); @endcode - Regardless of whether the asynchronous operation completes immediately or - not, the handler will not be invoked from within this function. Invocation - of the handler will be performed in a manner equivalent to using - boost::asio::io_context::post(). - */ - template<class MutableBufferSequence, class ReadHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void(boost::system::error_code, std::size_t)) - async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler); - - /** Start an asynchronous write. - - This function is used to asynchronously write data to the stream socket. - The function call always returns immediately. - - @param buffers One or more data buffers to be written to the socket. - Although the buffers object may be copied as necessary, ownership of the - underlying memory blocks is retained by the caller, which must guarantee - that they remain valid until the handler is called. - - @param handler The handler to be called when the write operation completes. - Copies will be made of the handler as required. The function signature of - the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes written. - ); @endcode - Regardless of whether the asynchronous operation completes immediately or - not, the handler will not be invoked from within this function. Invocation - of the handler will be performed in a manner equivalent to using - boost::asio::io_context::post(). - */ - template<class ConstBufferSequence, class WriteHandler> - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void(boost::system::error_code, std::size_t)) - async_write_some( - ConstBufferSequence const& buffers, - WriteHandler&& handler); -}; - -/// A TCP/IP socket wrapper which has a built-in asynchronous timeout -using timeout_socket = basic_timeout_socket< - boost::asio::ip::tcp, - boost::asio::io_context::executor_type>; - -} // beast -} // boost - -#include <boost/beast/experimental/core/impl/timeout_socket.hpp> - -#endif diff --git a/boost/beast/experimental/http/icy_stream.hpp b/boost/beast/experimental/http/icy_stream.hpp deleted file mode 100644 index b597b244ba..0000000000 --- a/boost/beast/experimental/http/icy_stream.hpp +++ /dev/null @@ -1,345 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_HTTP_ICY_STREAM_HPP -#define BOOST_BEAST_HTTP_ICY_STREAM_HPP - -#include <boost/beast/core/detail/config.hpp> -#include <boost/beast/core/error.hpp> -#include <boost/beast/core/type_traits.hpp> -#include <boost/asio/async_result.hpp> -#include <type_traits> - -namespace boost { -namespace beast { -namespace http { - -/** Stream wrapper to process Shoutcast HTTP responses - - This wrapper replaces the word "ICY" in the first - HTTP response received on the connection, with "HTTP/1.1". - This allows the Beast parser to be used with Shoutcast - servers, which send a non-standard HTTP message as the - response. - - For asynchronous operations, the application must ensure - that they are are all performed within the same implicit - or explicit strand. - - @par Thread Safety - @e Distinct @e objects: Safe.@n - @e Shared @e objects: Unsafe. - The application must also ensure that all asynchronous - operations are performed within the same implicit or explicit strand. - - @par Example - - To use the @ref stream template with an `ip::tcp::socket`, - you would write: - - @code - http::icy_stream<ip::tcp::socket> is{io_context}; - @endcode - Alternatively, you can write: - @code - ip::tcp::socket sock{io_context}; - http::icy_stream<ip::tcp::socket&> is{sock}; - @endcode - - @tparam NextLayer The type representing the next layer, to which - data will be read and written during operations. For synchronous - operations, the type must support the @b SyncStream concept. - For asynchronous operations, the type must support the - @b AsyncStream concept. - - @note A stream object must not be moved or destroyed while there - are pending asynchronous operations associated with it. - - @par Concepts - @b AsyncStream, - @b SyncStream -*/ -template<class NextLayer> -class icy_stream -{ - template<class, class> class read_op; - - NextLayer stream_; - bool detect_ = true; - unsigned char copy_ = 0; - char buf_[8]; - - static - boost::asio::const_buffer - version() - { - return {"HTTP/1.1", 8}; - } - -public: - /// The type of the next layer. - using next_layer_type = - typename std::remove_reference<NextLayer>::type; - - /// The type of the lowest layer. - using lowest_layer_type = boost::beast::get_lowest_layer<next_layer_type>; - - /// The type of the executor associated with the object. - using executor_type = typename next_layer_type::executor_type; - - icy_stream(icy_stream&&) = default; - icy_stream(icy_stream const&) = default; - icy_stream& operator=(icy_stream&&) = default; - icy_stream& operator=(icy_stream const&) = default; - - /** Destructor - - The treatment of pending operations will be the same as that - of the next layer. - */ - ~icy_stream() = default; - - /** Constructor - - Arguments, if any, are forwarded to the next layer's constructor. - */ - template<class... Args> - explicit - icy_stream(Args&&... args); - - //-------------------------------------------------------------------------- - - /** Get the executor associated with the object. - - This function may be used to obtain the executor object that the - stream uses to dispatch handlers for asynchronous operations. - - @return A copy of the executor that stream will use to dispatch handlers. - */ - executor_type - get_executor() noexcept - { - return stream_.get_executor(); - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer - in a stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type& - next_layer() - { - return stream_; - } - - /** Get a reference to the next layer - - This function returns a reference to the next layer in a - stack of stream layers. - - @return A reference to the next layer in the stack of - stream layers. - */ - next_layer_type const& - next_layer() const - { - return stream_; - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. - */ - lowest_layer_type& - lowest_layer() - { - return stream_.lowest_layer(); - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. Ownership is not transferred to the caller. - */ - lowest_layer_type const& - lowest_layer() const - { - return stream_.lowest_layer(); - } - - //-------------------------------------------------------------------------- - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @returns The number of bytes read. - - @throws boost::system::system_error Thrown on failure. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers); - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes read. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some( - MutableBufferSequence const& buffers, - error_code& ec); - - /** Start an asynchronous read. - - This function is used to asynchronously read one or more bytes of data from - the stream. The function call always returns immediately. - - @param buffers The buffers into which the data will be read. Although the - buffers object may be copied as necessary, ownership of the underlying - buffers is retained by the caller, which must guarantee that they remain - valid until the handler is called. - - @param handler The handler to be called when the read operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes read. - ); @endcode - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::async_read` if you need - to ensure that the requested amount of data is read before the asynchronous - operation completes. - */ - template< - class MutableBufferSequence, - class ReadHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) - async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @returns The number of bytes written. - - @throws boost::system::system_error Thrown on failure. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some(ConstBufferSequence const& buffers); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes written. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some( - ConstBufferSequence const& buffers, - error_code& ec); - - /** Start an asynchronous write. - - This function is used to asynchronously write one or more bytes of data to - the stream. The function call always returns immediately. - - @param buffers The data to be written to the stream. Although the buffers - object may be copied as necessary, ownership of the underlying buffers is - retained by the caller, which must guarantee that they remain valid until - the handler is called. - - @param handler The handler to be called when the write operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes written. - ); @endcode - - @note The `async_write_some` operation may not transmit all of the data to - the peer. Consider using the function `boost::asio::async_write` if you need - to ensure that all data is written before the asynchronous operation completes. - */ - template< - class ConstBufferSequence, - class WriteHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) - async_write_some( - ConstBufferSequence const& buffers, - WriteHandler&& handler); -}; - -} // http -} // beast -} // boost - -#include <boost/beast/experimental/http/impl/icy_stream.ipp> - -#endif diff --git a/boost/beast/experimental/http/impl/icy_stream.ipp b/boost/beast/experimental/http/impl/icy_stream.ipp deleted file mode 100644 index c9fa3a845c..0000000000 --- a/boost/beast/experimental/http/impl/icy_stream.ipp +++ /dev/null @@ -1,633 +0,0 @@ -// -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_CORE_IMPL_ICY_STREAM_IPP -#define BOOST_BEAST_CORE_IMPL_ICY_STREAM_IPP - -#include <boost/beast/core/bind_handler.hpp> -#include <boost/beast/core/buffers_adapter.hpp> -#include <boost/beast/core/buffers_prefix.hpp> -#include <boost/beast/core/buffers_suffix.hpp> -#include <boost/beast/core/detail/buffers_ref.hpp> -#include <boost/beast/core/handler_ptr.hpp> -#include <boost/asio/associated_allocator.hpp> -#include <boost/asio/associated_executor.hpp> -#include <boost/asio/buffer.hpp> -#include <boost/asio/buffers_iterator.hpp> -#include <boost/asio/coroutine.hpp> -#include <boost/asio/handler_continuation_hook.hpp> -#include <boost/asio/handler_invoke_hook.hpp> -#include <boost/asio/post.hpp> -#include <boost/asio/read.hpp> -#include <boost/asio/read_until.hpp> -#include <boost/assert.hpp> -#include <boost/throw_exception.hpp> -#include <algorithm> -#include <memory> -#include <utility> - -namespace boost { -namespace beast { -namespace http { - -namespace detail { - -template<class DynamicBuffer> -class dynamic_buffer_ref -{ - DynamicBuffer& b_; - -public: - using const_buffers_type = - typename DynamicBuffer::const_buffers_type; - - using mutable_buffers_type = - typename DynamicBuffer::mutable_buffers_type; - - dynamic_buffer_ref(dynamic_buffer_ref&&) = default; - - explicit - dynamic_buffer_ref(DynamicBuffer& b) - : b_(b) - { - } - - std::size_t - size() const - { - return b_.size(); - } - - std::size_t - max_size() const - { - return b_.max_size(); - } - - std::size_t - capacity() const - { - return b_.capacity(); - } - - const_buffers_type - data() const - { - return b_.data(); - } - - mutable_buffers_type - prepare(std::size_t n) - { - return b_.prepare(n); - } - - void - commit(std::size_t n) - { - b_.commit(n); - } - - void - consume(std::size_t n) - { - b_.consume(n); - } -}; - -template<class DynamicBuffer> -typename std::enable_if< - boost::asio::is_dynamic_buffer<DynamicBuffer>::value, - dynamic_buffer_ref<DynamicBuffer>>::type -ref(DynamicBuffer& b) -{ - return dynamic_buffer_ref<DynamicBuffer>(b); -} - -template<class MutableBuffers, class ConstBuffers> -void -buffer_shift(MutableBuffers const& out, ConstBuffers const& in) -{ - using boost::asio::buffer_size; - auto in_pos = boost::asio::buffer_sequence_end(in); - auto out_pos = boost::asio::buffer_sequence_end(out); - auto const in_begin = boost::asio::buffer_sequence_begin(in); - auto const out_begin = boost::asio::buffer_sequence_begin(out); - BOOST_ASSERT(buffer_size(in) == buffer_size(out)); - if(in_pos == in_begin || out_pos == out_begin) - return; - boost::asio::const_buffer cb{*--in_pos}; - boost::asio::mutable_buffer mb{*--out_pos}; - for(;;) - { - if(mb.size() >= cb.size()) - { - std::memmove( - static_cast<char*>( - mb.data()) + mb.size() - cb.size(), - cb.data(), - cb.size()); - mb = boost::asio::mutable_buffer{ - mb.data(), mb.size() - cb.size()}; - if(in_pos == in_begin) - break; - cb = *--in_pos; - } - else - { - std::memmove( - mb.data(), - static_cast<char const*>( - cb.data()) + cb.size() - mb.size(), - mb.size()); - cb = boost::asio::const_buffer{ - cb.data(), cb.size() - mb.size()}; - if(out_pos == out_begin) - break; - mb = *--out_pos; - } - } -} - -template<class FwdIt> -class match_icy -{ - bool& match_; - -public: - using result_type = std::pair<FwdIt, bool>; - explicit - match_icy(bool& b) - : match_(b) - { - } - - result_type - operator()(FwdIt first, FwdIt last) const - { - auto it = first; - if(it == last) - return {first, false}; - if(*it != 'I') - return {last, true}; - if(++it == last) - return {first, false}; - if(*it != 'C') - return {last, true}; - if(++it == last) - return {first, false}; - if(*it != 'Y') - return {last, true}; - match_ = true; - return {last, true}; - }; -}; - -} // detail - -template<class NextLayer> -template<class MutableBufferSequence, class Handler> -class icy_stream<NextLayer>::read_op - : public boost::asio::coroutine -{ - using alloc_type = typename -#if defined(BOOST_NO_CXX11_ALLOCATOR) - boost::asio::associated_allocator_t<Handler>::template - rebind<char>::other; -#else - std::allocator_traits<boost::asio::associated_allocator_t<Handler>> - ::template rebind_alloc<char>; -#endif - - struct data - { - icy_stream<NextLayer>& s; - buffers_adapter<MutableBufferSequence> b; - bool match = false; - - data( - Handler const&, - icy_stream<NextLayer>& s_, - MutableBufferSequence const& b_) - : s(s_) - , b(b_) - { - } - }; - - handler_ptr<data, Handler> d_; - -public: - read_op(read_op&&) = default; - read_op(read_op const&) = delete; - - template<class DeducedHandler, class... Args> - read_op( - DeducedHandler&& h, - icy_stream<NextLayer>& s, - MutableBufferSequence const& b) - : d_(std::forward<DeducedHandler>(h), s, b) - { - } - - using allocator_type = - boost::asio::associated_allocator_t<Handler>; - - allocator_type - get_allocator() const noexcept - { - return (boost::asio::get_associated_allocator)(d_.handler()); - } - - using executor_type = boost::asio::associated_executor_t< - Handler, decltype(std::declval<NextLayer&>().get_executor())>; - - executor_type - get_executor() const noexcept - { - return (boost::asio::get_associated_executor)( - d_.handler(), d_->s.get_executor()); - } - - void - operator()( - boost::system::error_code ec, - std::size_t bytes_transferred); - - template<class Function> - friend - void asio_handler_invoke(Function&& f, read_op* op) - { - using boost::asio::asio_handler_invoke; - asio_handler_invoke(f, std::addressof(op->d_.handler())); - } -}; - -template<class NextLayer> -template<class MutableBufferSequence, class Handler> -void -icy_stream<NextLayer>:: -read_op<MutableBufferSequence, Handler>:: -operator()( - error_code ec, - std::size_t bytes_transferred) -{ - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - using iterator = boost::asio::buffers_iterator< - typename detail::dynamic_buffer_ref< - buffers_adapter<MutableBufferSequence>>::const_buffers_type>; - auto& d = *d_; - BOOST_ASIO_CORO_REENTER(*this) - { - if(d.b.max_size() == 0) - { - BOOST_ASIO_CORO_YIELD - boost::asio::post(d.s.get_executor(), - bind_handler(std::move(*this), ec, 0)); - goto upcall; - } - if(! d.s.detect_) - { - if(d.s.copy_ > 0) - { - auto const n = buffer_copy( - d.b.prepare(std::min<std::size_t>( - d.s.copy_, d.b.max_size())), - boost::asio::buffer(d.s.buf_)); - d.b.commit(n); - d.s.copy_ = static_cast<unsigned char>( - d.s.copy_ - n); - if(d.s.copy_ > 0) - std::memmove( - d.s.buf_, - &d.s.buf_[n], - d.s.copy_); - } - if(d.b.size() < d.b.max_size()) - { - BOOST_ASIO_CORO_YIELD - d.s.next_layer().async_read_some( - d.b.prepare(d.b.max_size() - d.b.size()), - std::move(*this)); - d.b.commit(bytes_transferred); - } - bytes_transferred = d.b.size(); - goto upcall; - } - - d.s.detect_ = false; - if(d.b.max_size() < 8) - { - BOOST_ASIO_CORO_YIELD - boost::asio::async_read( - d.s.next_layer(), - boost::asio::buffer(d.s.buf_, 3), - std::move(*this)); - if(ec) - goto upcall; - auto n = bytes_transferred; - BOOST_ASSERT(n == 3); - if( - d.s.buf_[0] != 'I' || - d.s.buf_[1] != 'C' || - d.s.buf_[2] != 'Y') - { - buffer_copy( - d.b.value(), - boost::asio::buffer(d.s.buf_, n)); - if(d.b.max_size() < 3) - { - d.s.copy_ = static_cast<unsigned char>( - 3 - d.b.max_size()); - std::memmove( - d.s.buf_, - &d.s.buf_[d.b.max_size()], - d.s.copy_); - - } - bytes_transferred = (std::min)( - n, d.b.max_size()); - goto upcall; - } - d.s.copy_ = static_cast<unsigned char>( - buffer_copy( - boost::asio::buffer(d.s.buf_), - icy_stream::version() + d.b.max_size())); - bytes_transferred = buffer_copy( - d.b.value(), - icy_stream::version()); - goto upcall; - } - - BOOST_ASIO_CORO_YIELD - boost::asio::async_read_until( - d.s.next_layer(), - detail::ref(d.b), - detail::match_icy<iterator>(d.match), - std::move(*this)); - if(ec) - goto upcall; - { - auto n = bytes_transferred; - BOOST_ASSERT(n == d.b.size()); - if(! d.match) - goto upcall; - if(d.b.size() + 5 > d.b.max_size()) - { - d.s.copy_ = static_cast<unsigned char>( - n + 5 - d.b.max_size()); - std::copy( - boost::asio::buffers_begin(d.b.value()) + n - d.s.copy_, - boost::asio::buffers_begin(d.b.value()) + n, - d.s.buf_); - n = d.b.max_size() - 5; - } - { - buffers_suffix<beast::detail::buffers_ref< - MutableBufferSequence>> dest( - boost::in_place_init, d.b.value()); - dest.consume(5); - detail::buffer_shift( - buffers_prefix(n, dest), - buffers_prefix(n, d.b.value())); - buffer_copy(d.b.value(), icy_stream::version()); - n += 5; - bytes_transferred = n; - } - } - upcall: - d_.invoke(ec, bytes_transferred); - } -} - -//------------------------------------------------------------------------------ - -template<class NextLayer> -template<class... Args> -icy_stream<NextLayer>:: -icy_stream(Args&&... args) - : stream_(std::forward<Args>(args)...) -{ -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -icy_stream<NextLayer>:: -read_some(MutableBufferSequence const& buffers) -{ - static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value, - "SyncReadStream requirements not met"); - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - error_code ec; - auto n = read_some(buffers, ec); - if(ec) - BOOST_THROW_EXCEPTION(boost::system::system_error{ec}); - return n; -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -icy_stream<NextLayer>:: -read_some(MutableBufferSequence const& buffers, error_code& ec) -{ - static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value, - "SyncReadStream requirements not met"); - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - using iterator = boost::asio::buffers_iterator< - typename detail::dynamic_buffer_ref< - buffers_adapter<MutableBufferSequence>>::const_buffers_type>; - buffers_adapter<MutableBufferSequence> b(buffers); - if(b.max_size() == 0) - { - ec.assign(0, ec.category()); - return 0; - } - if(! detect_) - { - if(copy_ > 0) - { - auto const n = buffer_copy( - b.prepare(std::min<std::size_t>( - copy_, b.max_size())), - boost::asio::buffer(buf_)); - b.commit(n); - copy_ = static_cast<unsigned char>( - copy_ - n); - if(copy_ > 0) - std::memmove( - buf_, - &buf_[n], - copy_); - } - if(b.size() < b.max_size()) - b.commit(stream_.read_some( - b.prepare(b.max_size() - b.size()), ec)); - return b.size(); - } - - detect_ = false; - if(b.max_size() < 8) - { - auto n = boost::asio::read( - stream_, - boost::asio::buffer(buf_, 3), - ec); - if(ec) - return 0; - BOOST_ASSERT(n == 3); - if( - buf_[0] != 'I' || - buf_[1] != 'C' || - buf_[2] != 'Y') - { - buffer_copy( - buffers, - boost::asio::buffer(buf_, n)); - if(b.max_size() < 3) - { - copy_ = static_cast<unsigned char>( - 3 - b.max_size()); - std::memmove( - buf_, - &buf_[b.max_size()], - copy_); - - } - return (std::min)(n, b.max_size()); - } - copy_ = static_cast<unsigned char>( - buffer_copy( - boost::asio::buffer(buf_), - version() + b.max_size())); - return buffer_copy( - buffers, - version()); - } - - bool match = false; - auto n = boost::asio::read_until( - stream_, - detail::ref(b), - detail::match_icy<iterator>(match), - ec); - if(ec) - return n; - BOOST_ASSERT(n == b.size()); - if(! match) - return n; - if(b.size() + 5 > b.max_size()) - { - copy_ = static_cast<unsigned char>( - n + 5 - b.max_size()); - std::copy( - boost::asio::buffers_begin(buffers) + n - copy_, - boost::asio::buffers_begin(buffers) + n, - buf_); - n = b.max_size() - 5; - } - buffers_suffix<beast::detail::buffers_ref< - MutableBufferSequence>> dest( - boost::in_place_init, buffers); - dest.consume(5); - detail::buffer_shift( - buffers_prefix(n, dest), - buffers_prefix(n, buffers)); - buffer_copy(buffers, version()); - n += 5; - return n; -} - -template<class NextLayer> -template< - class MutableBufferSequence, - class ReadHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) -icy_stream<NextLayer>:: -async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler) -{ - static_assert(boost::beast::is_async_read_stream<next_layer_type>::value, - "AsyncReadStream requirements not met"); - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence >::value, - "MutableBufferSequence requirements not met"); - BOOST_BEAST_HANDLER_INIT( - ReadHandler, void(error_code, std::size_t)); - read_op< - MutableBufferSequence, - BOOST_ASIO_HANDLER_TYPE( - ReadHandler, void(error_code, std::size_t))>{ - std::move(init.completion_handler), *this, buffers}( - {}, 0); - return init.result.get(); -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -icy_stream<NextLayer>:: -write_some(MutableBufferSequence const& buffers) -{ - static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value, - "SyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - return stream_.write_some(buffers); -} - -template<class NextLayer> -template<class MutableBufferSequence> -std::size_t -icy_stream<NextLayer>:: -write_some(MutableBufferSequence const& buffers, error_code& ec) -{ - static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value, - "SyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - return stream_.write_some(buffers, ec); -} - -template<class NextLayer> -template< - class MutableBufferSequence, - class WriteHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) -icy_stream<NextLayer>:: -async_write_some( - MutableBufferSequence const& buffers, - WriteHandler&& handler) -{ - static_assert(boost::beast::is_async_write_stream<next_layer_type>::value, - "AsyncWriteStream requirements not met"); - static_assert(boost::asio::is_const_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - return stream_.async_write_some(buffers, std::forward<WriteHandler>(handler)); -} - -} // http -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/test/detail/error.hpp b/boost/beast/experimental/test/detail/error.hpp deleted file mode 100644 index d8ffbc13be..0000000000 --- a/boost/beast/experimental/test/detail/error.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_DETAIL_ERROR_HPP -#define BOOST_BEAST_TEST_DETAIL_ERROR_HPP - -#include <boost/beast/core/error.hpp> -#include <boost/beast/core/string.hpp> - -namespace boost { - -namespace beast { -namespace test { -enum class error; -} // test -} // beast - -namespace system { -template<> -struct is_error_code_enum<beast::test::error> -{ - static bool const value = true; -}; - -} // system - -namespace beast { -namespace test { -namespace detail { - -class error_codes : public error_category -{ -public: - const char* - name() const noexcept override; - - std::string - message(int ev) const override; - - error_condition - default_error_condition(int ev) const noexcept override; -}; - -} // detail - -error_code -make_error_code(error e); - -} // test -} // beast - -} // boost - -#endif diff --git a/boost/beast/experimental/test/error.hpp b/boost/beast/experimental/test/error.hpp deleted file mode 100644 index 99ac6a9d38..0000000000 --- a/boost/beast/experimental/test/error.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_ERROR_HPP -#define BOOST_BEAST_TEST_ERROR_HPP - -#include <boost/beast/core/error.hpp> -#include <boost/beast/experimental/test/detail/error.hpp> - -namespace boost { -namespace beast { -namespace test { - -/// Error codes returned from unit testing algorithms -enum class error -{ - /** The test stream generated a simulated testing error - - This error is returned by the test @ref stream when it - generates a simulated error. - */ - test_failure = 1 -}; - -} // test -} // beast -} // boost - -#include <boost/beast/experimental/test/impl/error.ipp> - -#endif diff --git a/boost/beast/experimental/test/fail_count.hpp b/boost/beast/experimental/test/fail_count.hpp deleted file mode 100644 index 98317ad537..0000000000 --- a/boost/beast/experimental/test/fail_count.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_FAIL_COUNT_HPP -#define BOOST_BEAST_TEST_FAIL_COUNT_HPP - -#include <boost/beast/core/error.hpp> -#include <boost/beast/experimental/test/error.hpp> -#include <boost/throw_exception.hpp> - -namespace boost { -namespace beast { -namespace test { - -/** A countdown to simulated failure - - On the Nth operation, the class will fail with the specified - error code, or the default error code of @ref error::test_failure. - - Instances of this class may be used to build objects which - are specifically designed to aid in writing unit tests, for - interfaces which can throw exceptions or return `error_code` - values representing failure. -*/ -class fail_count -{ - std::size_t n_; - std::size_t i_ = 0; - error_code ec_; - -public: - fail_count(fail_count&&) = default; - - /** Construct a counter - - @param n The 0-based index of the operation to fail on or after - @param ev An optional error code to use when generating a simulated failure - */ - explicit - fail_count( - std::size_t n, - error_code ev = make_error_code(error::test_failure)); - - /// Throw an exception on the Nth failure - void - fail(); - - /// Set an error code on the Nth failure - bool - fail(error_code& ec); -}; - -} // test -} // beast -} // boost - -#include <boost/beast/experimental/test/impl/fail_count.ipp> - -#endif diff --git a/boost/beast/experimental/test/impl/error.ipp b/boost/beast/experimental/test/impl/error.ipp deleted file mode 100644 index 285947dffd..0000000000 --- a/boost/beast/experimental/test/impl/error.ipp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_IMPL_ERROR_IPP -#define BOOST_BEAST_TEST_IMPL_ERROR_IPP - -namespace boost { -namespace beast { -namespace test { - -namespace detail { - -inline -const char* -error_codes:: -name() const noexcept -{ - return "boost.beast.test"; -} - -inline -std::string -error_codes:: -message(int ev) const -{ - switch(static_cast<error>(ev)) - { - default: - case error::test_failure: return "The test stream generated a simulated error"; - } -} - -inline -error_condition -error_codes:: -default_error_condition(int ev) const noexcept -{ - return error_condition{ev, *this}; -} - -} // detail - -inline -error_code -make_error_code(error e) -{ - static detail::error_codes const cat{}; - return error_code{static_cast< - std::underlying_type<error>::type>(e), cat}; -} - -} // test -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/test/impl/fail_count.ipp b/boost/beast/experimental/test/impl/fail_count.ipp deleted file mode 100644 index 34e4cfa681..0000000000 --- a/boost/beast/experimental/test/impl/fail_count.ipp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_IMPL_FAIL_COUNT_IPP -#define BOOST_BEAST_TEST_IMPL_FAIL_COUNT_IPP - -#include <boost/beast/core/error.hpp> -#include <boost/beast/experimental/test/error.hpp> -#include <boost/throw_exception.hpp> - -namespace boost { -namespace beast { -namespace test { - -inline -fail_count:: -fail_count( - std::size_t n, - error_code ev) - : n_(n) - , ec_(ev) -{ -} - -inline -void -fail_count:: -fail() -{ - if(i_ < n_) - ++i_; - if(i_ == n_) - BOOST_THROW_EXCEPTION(system_error{ec_}); -} - -inline -bool -fail_count:: -fail(error_code& ec) -{ - if(i_ < n_) - ++i_; - if(i_ == n_) - { - ec = ec_; - return true; - } - ec.assign(0, ec.category()); - return false; -} - -} // test -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/test/impl/stream.ipp b/boost/beast/experimental/test/impl/stream.ipp deleted file mode 100644 index db963ba0af..0000000000 --- a/boost/beast/experimental/test/impl/stream.ipp +++ /dev/null @@ -1,580 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_IMPL_STREAM_IPP -#define BOOST_BEAST_TEST_IMPL_STREAM_IPP - -#include <boost/beast/core/buffers_prefix.hpp> - -namespace boost { -namespace beast { -namespace test { - -inline -stream:: -~stream() -{ - { - std::unique_lock<std::mutex> lock{in_->m}; - in_->op.reset(); - } - auto out = out_.lock(); - if(out) - { - std::unique_lock<std::mutex> lock{out->m}; - if(out->code == status::ok) - { - out->code = status::reset; - out->on_write(); - } - } -} - -inline -stream:: -stream(stream&& other) -{ - auto in = std::make_shared<state>( - other.in_->ioc, other.in_->fc); - in_ = std::move(other.in_); - out_ = std::move(other.out_); - other.in_ = in; -} - -inline -stream& -stream:: -operator=(stream&& other) -{ - auto in = std::make_shared<state>( - other.in_->ioc, other.in_->fc); - in_ = std::move(other.in_); - out_ = std::move(other.out_); - other.in_ = in; - return *this; -} - -inline -stream:: -stream(boost::asio::io_context& ioc) - : in_(std::make_shared<state>(ioc, nullptr)) -{ -} - -inline -stream:: -stream( - boost::asio::io_context& ioc, - fail_count& fc) - : in_(std::make_shared<state>(ioc, &fc)) -{ -} - -inline -stream:: -stream( - boost::asio::io_context& ioc, - string_view s) - : in_(std::make_shared<state>(ioc, nullptr)) -{ - using boost::asio::buffer; - using boost::asio::buffer_copy; - in_->b.commit(buffer_copy( - in_->b.prepare(s.size()), - buffer(s.data(), s.size()))); -} - -inline -stream:: -stream( - boost::asio::io_context& ioc, - fail_count& fc, - string_view s) - : in_(std::make_shared<state>(ioc, &fc)) -{ - using boost::asio::buffer; - using boost::asio::buffer_copy; - in_->b.commit(buffer_copy( - in_->b.prepare(s.size()), - buffer(s.data(), s.size()))); -} - -inline -void -stream:: -connect(stream& remote) -{ - BOOST_ASSERT(! out_.lock()); - BOOST_ASSERT(! remote.out_.lock()); - out_ = remote.in_; - remote.out_ = in_; -} -inline -string_view -stream:: -str() const -{ - auto const bs = in_->b.data(); - if(boost::asio::buffer_size(bs) == 0) - return {}; - auto const b = buffers_front(bs); - return {static_cast<char const*>(b.data()), b.size()}; -} - -inline -void -stream:: -append(string_view s) -{ - using boost::asio::buffer; - using boost::asio::buffer_copy; - std::lock_guard<std::mutex> lock{in_->m}; - in_->b.commit(buffer_copy( - in_->b.prepare(s.size()), - buffer(s.data(), s.size()))); -} - -inline -void -stream:: -clear() -{ - std::lock_guard<std::mutex> lock{in_->m}; - in_->b.consume(in_->b.size()); -} - -inline -void -stream:: -close() -{ - BOOST_ASSERT(! in_->op); - auto out = out_.lock(); - if(! out) - return; - std::lock_guard<std::mutex> lock{out->m}; - if(out->code == status::ok) - { - out->code = status::eof; - out->on_write(); - } -} - -inline -void -stream:: -close_remote() -{ - std::lock_guard<std::mutex> lock{in_->m}; - if(in_->code == status::ok) - { - in_->code = status::eof; - in_->on_write(); - } -} - -template<class MutableBufferSequence> -std::size_t -stream:: -read_some(MutableBufferSequence const& buffers) -{ - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - error_code ec; - auto const n = read_some(buffers, ec); - if(ec) - BOOST_THROW_EXCEPTION(system_error{ec}); - return n; -} - -template<class MutableBufferSequence> -std::size_t -stream:: -read_some(MutableBufferSequence const& buffers, - error_code& ec) -{ - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - if(in_->fc && in_->fc->fail(ec)) - return 0; - if(buffer_size(buffers) == 0) - { - ec.clear(); - return 0; - } - std::unique_lock<std::mutex> lock{in_->m}; - BOOST_ASSERT(! in_->op); - in_->cv.wait(lock, - [&]() - { - return - in_->b.size() > 0 || - in_->code != status::ok; - }); - std::size_t bytes_transferred; - if(in_->b.size() > 0) - { - ec.assign(0, ec.category()); - bytes_transferred = buffer_copy( - buffers, in_->b.data(), in_->read_max); - in_->b.consume(bytes_transferred); - } - else - { - BOOST_ASSERT(in_->code != status::ok); - bytes_transferred = 0; - if(in_->code == status::eof) - ec = boost::asio::error::eof; - else if(in_->code == status::reset) - ec = boost::asio::error::connection_reset; - } - ++in_->nread; - return bytes_transferred; -} - -template<class MutableBufferSequence, class ReadHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) -stream:: -async_read_some( - MutableBufferSequence const& buffers, - ReadHandler&& handler) -{ - static_assert(boost::asio::is_mutable_buffer_sequence< - MutableBufferSequence>::value, - "MutableBufferSequence requirements not met"); - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - BOOST_BEAST_HANDLER_INIT( - ReadHandler, void(error_code, std::size_t)); - if(in_->fc) - { - error_code ec; - if(in_->fc->fail(ec)) - return boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - ec, - 0)); - } - { - std::unique_lock<std::mutex> lock{in_->m}; - BOOST_ASSERT(! in_->op); - if(buffer_size(buffers) == 0 || - buffer_size(in_->b.data()) > 0) - { - auto const bytes_transferred = buffer_copy( - buffers, in_->b.data(), in_->read_max); - in_->b.consume(bytes_transferred); - lock.unlock(); - ++in_->nread; - boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - error_code{}, - bytes_transferred)); - } - else if(in_->code != status::ok) - { - lock.unlock(); - ++in_->nread; - error_code ec; - if(in_->code == status::eof) - ec = boost::asio::error::eof; - else if(in_->code == status::reset) - ec = boost::asio::error::connection_reset; - boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - ec, - 0)); - } - else - { - in_->op.reset(new read_op<BOOST_ASIO_HANDLER_TYPE( - ReadHandler, void(error_code, std::size_t)), - MutableBufferSequence>{*in_, buffers, - std::move(init.completion_handler)}); - } - } - return init.result.get(); -} - -template<class ConstBufferSequence> -std::size_t -stream:: -write_some(ConstBufferSequence const& buffers) -{ - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - error_code ec; - auto const bytes_transferred = - write_some(buffers, ec); - if(ec) - BOOST_THROW_EXCEPTION(system_error{ec}); - return bytes_transferred; -} - -template<class ConstBufferSequence> -std::size_t -stream:: -write_some( - ConstBufferSequence const& buffers, error_code& ec) -{ - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - auto out = out_.lock(); - if(! out) - { - ec = boost::asio::error::connection_reset; - return 0; - } - BOOST_ASSERT(out->code == status::ok); - if(in_->fc && in_->fc->fail(ec)) - return 0; - auto const n = (std::min)( - buffer_size(buffers), in_->write_max); - std::unique_lock<std::mutex> lock{out->m}; - auto const bytes_transferred = - buffer_copy(out->b.prepare(n), buffers); - out->b.commit(bytes_transferred); - out->on_write(); - lock.unlock(); - ++in_->nwrite; - ec.assign(0, ec.category()); - return bytes_transferred; -} - -template<class ConstBufferSequence, class WriteHandler> -BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) -stream:: -async_write_some(ConstBufferSequence const& buffers, - WriteHandler&& handler) -{ - static_assert(boost::asio::is_const_buffer_sequence< - ConstBufferSequence>::value, - "ConstBufferSequence requirements not met"); - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - BOOST_BEAST_HANDLER_INIT( - WriteHandler, void(error_code, std::size_t)); - auto out = out_.lock(); - if(! out) - return boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - boost::asio::error::connection_reset, - 0)); - BOOST_ASSERT(out->code == status::ok); - if(in_->fc) - { - error_code ec; - if(in_->fc->fail(ec)) - return boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - ec, - 0)); - } - auto const n = - (std::min)(buffer_size(buffers), in_->write_max); - std::unique_lock<std::mutex> lock{out->m}; - auto const bytes_transferred = - buffer_copy(out->b.prepare(n), buffers); - out->b.commit(bytes_transferred); - out->on_write(); - lock.unlock(); - ++in_->nwrite; - boost::asio::post( - in_->ioc.get_executor(), - bind_handler( - std::move(init.completion_handler), - error_code{}, - bytes_transferred)); - return init.result.get(); -} - -inline -void -teardown( -websocket::role_type, -stream& s, -boost::system::error_code& ec) -{ - if( s.in_->fc && - s.in_->fc->fail(ec)) - return; - - s.close(); - - if( s.in_->fc && - s.in_->fc->fail(ec)) - ec = boost::asio::error::eof; - else - ec.assign(0, ec.category()); -} - -template<class TeardownHandler> -inline -void -async_teardown( -websocket::role_type, -stream& s, -TeardownHandler&& handler) -{ - error_code ec; - if( s.in_->fc && - s.in_->fc->fail(ec)) - return boost::asio::post( - s.get_executor(), - bind_handler(std::move(handler), ec)); - s.close(); - if( s.in_->fc && - s.in_->fc->fail(ec)) - ec = boost::asio::error::eof; - else - ec.assign(0, ec.category()); - - boost::asio::post( - s.get_executor(), - bind_handler(std::move(handler), ec)); -} - -//------------------------------------------------------------------------------ - -template<class Handler, class Buffers> -class stream::read_op : public stream::read_op_base -{ - class lambda - { - state& s_; - Buffers b_; - Handler h_; - boost::asio::executor_work_guard< - boost::asio::io_context::executor_type> work_; - - public: - lambda(lambda&&) = default; - lambda(lambda const&) = default; - - template<class DeducedHandler> - lambda(state& s, Buffers const& b, DeducedHandler&& h) - : s_(s) - , b_(b) - , h_(std::forward<DeducedHandler>(h)) - , work_(s_.ioc.get_executor()) - { - } - - void - post() - { - boost::asio::post( - s_.ioc.get_executor(), - std::move(*this)); - work_.reset(); - } - - void - operator()() - { - using boost::asio::buffer_copy; - using boost::asio::buffer_size; - std::unique_lock<std::mutex> lock{s_.m}; - BOOST_ASSERT(! s_.op); - if(s_.b.size() > 0) - { - auto const bytes_transferred = buffer_copy( - b_, s_.b.data(), s_.read_max); - s_.b.consume(bytes_transferred); - auto& s = s_; - Handler h{std::move(h_)}; - lock.unlock(); - ++s.nread; - boost::asio::post( - s.ioc.get_executor(), - bind_handler( - std::move(h), - error_code{}, - bytes_transferred)); - } - else - { - BOOST_ASSERT(s_.code != status::ok); - auto& s = s_; - Handler h{std::move(h_)}; - lock.unlock(); - ++s.nread; - error_code ec; - if(s.code == status::eof) - ec = boost::asio::error::eof; - else if(s.code == status::reset) - ec = boost::asio::error::connection_reset; - boost::asio::post( - s.ioc.get_executor(), - bind_handler(std::move(h), ec, 0)); - } - } - }; - - lambda fn_; - -public: - template<class DeducedHandler> - read_op(state& s, Buffers const& b, DeducedHandler&& h) - : fn_(s, b, std::forward<DeducedHandler>(h)) - { - } - - void - operator()() override - { - fn_.post(); - } -}; - -inline -stream -connect(stream& to) -{ - stream from{to.get_executor().context()}; - from.connect(to); - return from; -} - -template<class Arg1, class... ArgN> -stream -connect(stream& to, Arg1&& arg1, ArgN&&... argn) -{ - stream from{ - std::forward<Arg1>(arg1), - std::forward<ArgN>(argn)...}; - from.connect(to); - return from; -} - -} // test -} // beast -} // boost - -#endif diff --git a/boost/beast/experimental/test/stream.hpp b/boost/beast/experimental/test/stream.hpp deleted file mode 100644 index 17f8c55af5..0000000000 --- a/boost/beast/experimental/test/stream.hpp +++ /dev/null @@ -1,551 +0,0 @@ -// -// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail 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) -// -// Official repository: https://github.com/boostorg/beast -// - -#ifndef BOOST_BEAST_TEST_STREAM_HPP -#define BOOST_BEAST_TEST_STREAM_HPP - -#include <boost/beast/core/bind_handler.hpp> -#include <boost/beast/core/flat_buffer.hpp> -#include <boost/beast/core/string.hpp> -#include <boost/beast/core/type_traits.hpp> -#include <boost/beast/websocket/teardown.hpp> -#include <boost/beast/experimental/test/fail_count.hpp> -#include <boost/asio/async_result.hpp> -#include <boost/asio/buffer.hpp> -#include <boost/asio/executor_work_guard.hpp> -#include <boost/asio/io_context.hpp> -#include <boost/asio/post.hpp> -#include <boost/assert.hpp> -#include <boost/optional.hpp> -#include <boost/throw_exception.hpp> -#include <condition_variable> -#include <limits> -#include <memory> -#include <mutex> -#include <utility> - -namespace boost { -namespace beast { -namespace test { - -/** A two-way socket useful for unit testing - - An instance of this class simulates a traditional socket, - while also providing features useful for unit testing. - Each endpoint maintains an independent buffer called - the input area. Writes from one endpoint append data - to the peer's pending input area. When an endpoint performs - a read and data is present in the input area, the data is - delivered to the blocking or asynchronous operation. Otherwise - the operation is blocked or deferred until data is made - available, or until the endpoints become disconnected. - - These streams may be used anywhere an algorithm accepts a - reference to a synchronous or asynchronous read or write - stream. It is possible to use a test stream in a call to - `boost::asio::read_until`, or in a call to - @ref boost::beast::http::async_write for example. - - As with Boost.Asio I/O objects, a @ref stream constructs - with a reference to the `boost::asio::io_context` to use for - handling asynchronous I/O. For asynchronous operations, the - stream follows the same rules as a traditional asio socket - with respect to how completion handlers for asynchronous - operations are performed. - - To facilitate testing, these streams support some additional - features: - - @li The input area, represented by a @ref flat_buffer, may - be directly accessed by the caller to inspect the contents - before or after the remote endpoint writes data. This allows - a unit test to verify that the received data matches. - - @li Data may be manually appended to the input area. This data - will delivered in the next call to - @ref stream::read_some or @ref stream::async_read_some. - This allows predefined test vectors to be set up for testing - read algorithms. - - @li The stream may be constructed with a fail count. The - stream will eventually fail with a predefined error after a - certain number of operations, where the number of operations - is controlled by the test. When a test loops over a range of - operation counts, it is possible to exercise every possible - point of failure in the algorithm being tested. When used - correctly the technique allows the tests to reach a high - percentage of code coverage. - - @par Thread Safety - @e Distinct @e objects: Safe.@n - @e Shared @e objects: Unsafe. - The application must also ensure that all asynchronous - operations are performed within the same implicit or explicit strand. - - @par Concepts - @li @b SyncReadStream - @li @b SyncWriteStream - @li @b AsyncReadStream - @li @b AsyncWriteStream -*/ -class stream -{ - struct read_op_base - { - virtual ~read_op_base() = default; - virtual void operator()() = 0; - }; - - template<class Handler, class Buffers> - class read_op; - - enum class status - { - ok, - eof, - reset - }; - - struct state - { - friend class stream; - - std::mutex m; - flat_buffer b; - std::condition_variable cv; - std::unique_ptr<read_op_base> op; - boost::asio::io_context& ioc; - status code = status::ok; - fail_count* fc = nullptr; - std::size_t nread = 0; - std::size_t nwrite = 0; - std::size_t read_max = - (std::numeric_limits<std::size_t>::max)(); - std::size_t write_max = - (std::numeric_limits<std::size_t>::max)(); - - ~state() - { - BOOST_ASSERT(! op); - } - - explicit - state( - boost::asio::io_context& ioc_, - fail_count* fc_) - : ioc(ioc_) - , fc(fc_) - { - } - - void - on_write() - { - if(op) - { - std::unique_ptr<read_op_base> op_ = std::move(op); - op_->operator()(); - } - else - { - cv.notify_all(); - } - } - }; - - std::shared_ptr<state> in_; - std::weak_ptr<state> out_; - -public: - using buffer_type = flat_buffer; - - /// The type of the lowest layer. - using lowest_layer_type = stream; - - /** Destructor - - If an asynchronous read operation is pending, it will - simply be discarded with no notification to the completion - handler. - - If a connection is established while the stream is destroyed, - the peer will see the error `boost::asio::error::connection_reset` - when performing any reads or writes. - */ - ~stream(); - - /** Move Constructor - - Moving the stream while asynchronous operations are pending - results in undefined behavior. - */ - stream(stream&& other); - - /** Move Assignment - - Moving the stream while asynchronous operations are pending - results in undefined behavior. - */ - stream& - operator=(stream&& other); - - /** Construct a stream - - The stream will be created in a disconnected state. - - @param ioc The `io_context` object that the stream will use to - dispatch handlers for any asynchronous operations. - */ - explicit - stream(boost::asio::io_context& ioc); - - /** Construct a stream - - The stream will be created in a disconnected state. - - @param ioc The `io_context` object that the stream will use to - dispatch handlers for any asynchronous operations. - - @param fc The @ref fail_count to associate with the stream. - Each I/O operation performed on the stream will increment the - fail count. When the fail count reaches its internal limit, - a simulated failure error will be raised. - */ - stream( - boost::asio::io_context& ioc, - fail_count& fc); - - /** Construct a stream - - The stream will be created in a disconnected state. - - @param ioc The `io_context` object that the stream will use to - dispatch handlers for any asynchronous operations. - - @param s A string which will be appended to the input area, not - including the null terminator. - */ - stream( - boost::asio::io_context& ioc, - string_view s); - - /** Construct a stream - - The stream will be created in a disconnected state. - - @param ioc The `io_context` object that the stream will use to - dispatch handlers for any asynchronous operations. - - @param fc The @ref fail_count to associate with the stream. - Each I/O operation performed on the stream will increment the - fail count. When the fail count reaches its internal limit, - a simulated failure error will be raised. - - @param s A string which will be appended to the input area, not - including the null terminator. - */ - stream( - boost::asio::io_context& ioc, - fail_count& fc, - string_view s); - - /// Establish a connection - void - connect(stream& remote); - - /// The type of the executor associated with the object. - using executor_type = - boost::asio::io_context::executor_type; - - /// Return the executor associated with the object. - boost::asio::io_context::executor_type - get_executor() noexcept - { - return in_->ioc.get_executor(); - }; - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. - */ - lowest_layer_type& - lowest_layer() - { - return *this; - } - - /** Get a reference to the lowest layer - - This function returns a reference to the lowest layer - in a stack of stream layers. - - @return A reference to the lowest layer in the stack of - stream layers. Ownership is not transferred to the caller. - */ - lowest_layer_type const& - lowest_layer() const - { - return *this; - } - - /// Set the maximum number of bytes returned by read_some - void - read_size(std::size_t n) - { - in_->read_max = n; - } - - /// Set the maximum number of bytes returned by write_some - void - write_size(std::size_t n) - { - in_->write_max = n; - } - - /// Direct input buffer access - buffer_type& - buffer() - { - return in_->b; - } - - /// Returns a string view representing the pending input data - string_view - str() const; - - /// Appends a string to the pending input data - void - append(string_view s); - - /// Clear the pending input area - void - clear(); - - /// Return the number of reads - std::size_t - nread() const - { - return in_->nread; - } - - /// Return the number of writes - std::size_t - nwrite() const - { - return in_->nwrite; - } - - /** Close the stream. - - The other end of the connection will see - `error::eof` after reading all the remaining data. - */ - void - close(); - - /** Close the other end of the stream. - - This end of the connection will see - `error::eof` after reading all the remaining data. - */ - void - close_remote(); - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @returns The number of bytes read. - - @throws boost::system::system_error Thrown on failure. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers); - - /** Read some data from the stream. - - This function is used to read data from the stream. The function call will - block until one or more bytes of data has been read successfully, or until - an error occurs. - - @param buffers The buffers into which the data will be read. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes read. - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::read` if you need to ensure - that the requested amount of data is read before the blocking operation - completes. - */ - template<class MutableBufferSequence> - std::size_t - read_some(MutableBufferSequence const& buffers, - error_code& ec); - - /** Start an asynchronous read. - - This function is used to asynchronously read one or more bytes of data from - the stream. The function call always returns immediately. - - @param buffers The buffers into which the data will be read. Although the - buffers object may be copied as necessary, ownership of the underlying - buffers is retained by the caller, which must guarantee that they remain - valid until the handler is called. - - @param handler The handler to be called when the read operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes read. - ); @endcode - - @note The `read_some` operation may not read all of the requested number of - bytes. Consider using the function `boost::asio::async_read` if you need - to ensure that the requested amount of data is read before the asynchronous - operation completes. - */ - template<class MutableBufferSequence, class ReadHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - ReadHandler, void(error_code, std::size_t)) - async_read_some(MutableBufferSequence const& buffers, - ReadHandler&& handler); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @returns The number of bytes written. - - @throws boost::system::system_error Thrown on failure. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some(ConstBufferSequence const& buffers); - - /** Write some data to the stream. - - This function is used to write data on the stream. The function call will - block until one or more bytes of data has been written successfully, or - until an error occurs. - - @param buffers The data to be written. - - @param ec Set to indicate what error occurred, if any. - - @returns The number of bytes written. - - @note The `write_some` operation may not transmit all of the data to the - peer. Consider using the function `boost::asio::write` if you need to - ensure that all data is written before the blocking operation completes. - */ - template<class ConstBufferSequence> - std::size_t - write_some( - ConstBufferSequence const& buffers, error_code& ec); - - /** Start an asynchronous write. - - This function is used to asynchronously write one or more bytes of data to - the stream. The function call always returns immediately. - - @param buffers The data to be written to the stream. Although the buffers - object may be copied as necessary, ownership of the underlying buffers is - retained by the caller, which must guarantee that they remain valid until - the handler is called. - - @param handler The handler to be called when the write operation completes. - Copies will be made of the handler as required. The equivalent function - signature of the handler must be: - @code void handler( - const boost::system::error_code& error, // Result of operation. - std::size_t bytes_transferred // Number of bytes written. - ); @endcode - - @note The `async_write_some` operation may not transmit all of the data to - the peer. Consider using the function `boost::asio::async_write` if you need - to ensure that all data is written before the asynchronous operation completes. - */ - template<class ConstBufferSequence, class WriteHandler> - BOOST_ASIO_INITFN_RESULT_TYPE( - WriteHandler, void(error_code, std::size_t)) - async_write_some(ConstBufferSequence const& buffers, - WriteHandler&& handler); - -#if ! BOOST_BEAST_DOXYGEN - friend - void - teardown( - websocket::role_type, - stream& s, - boost::system::error_code& ec); - - template<class TeardownHandler> - friend - void - async_teardown( - websocket::role_type role, - stream& s, - TeardownHandler&& handler); -#endif -}; - -#if BOOST_BEAST_DOXYGEN -/** Return a new stream connected to the given stream - - @param to The stream to connect to. - - @param args Optional arguments forwarded to the new stream's constructor. - - @return The new, connected stream. -*/ -template<class... Args> -stream -connect(stream& to, Args&&... args); - -#else -stream -connect(stream& to); - -template<class Arg1, class... ArgN> -stream -connect(stream& to, Arg1&& arg1, ArgN&&... argn); -#endif - -} // test -} // beast -} // boost - -#include <boost/beast/experimental/test/impl/stream.ipp> - -#endif |