diff options
Diffstat (limited to 'lib/asio/windows')
-rw-r--r-- | lib/asio/windows/basic_handle.hpp | 273 | ||||
-rw-r--r-- | lib/asio/windows/basic_object_handle.hpp | 182 | ||||
-rw-r--r-- | lib/asio/windows/basic_random_access_handle.hpp | 376 | ||||
-rw-r--r-- | lib/asio/windows/basic_stream_handle.hpp | 359 | ||||
-rw-r--r-- | lib/asio/windows/object_handle.hpp | 381 | ||||
-rw-r--r-- | lib/asio/windows/object_handle_service.hpp | 183 | ||||
-rw-r--r-- | lib/asio/windows/overlapped_handle.hpp | 331 | ||||
-rw-r--r-- | lib/asio/windows/overlapped_ptr.hpp | 116 | ||||
-rw-r--r-- | lib/asio/windows/random_access_handle.hpp | 378 | ||||
-rw-r--r-- | lib/asio/windows/random_access_handle_service.hpp | 214 | ||||
-rw-r--r-- | lib/asio/windows/stream_handle.hpp | 362 | ||||
-rw-r--r-- | lib/asio/windows/stream_handle_service.hpp | 210 |
12 files changed, 3365 insertions, 0 deletions
diff --git a/lib/asio/windows/basic_handle.hpp b/lib/asio/windows/basic_handle.hpp new file mode 100644 index 0000000..f7c9d0d --- /dev/null +++ b/lib/asio/windows/basic_handle.hpp @@ -0,0 +1,273 @@ +// +// windows/basic_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides Windows handle functionality. +/** + * The windows::basic_handle class template provides the ability to wrap a + * Windows handle. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename HandleService> +class basic_handle + : public basic_io_object<HandleService> +{ +public: + /// The native representation of a handle. + typedef typename HandleService::native_handle_type native_handle_type; + + /// A basic_handle is always the lowest layer. + typedef basic_handle<HandleService> lowest_layer_type; + + /// Construct a basic_handle without opening it. + /** + * This constructor creates a handle without opening it. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_handle(asio::io_context& io_context) + : basic_io_object<HandleService>(io_context) + { + } + + /// Construct a basic_handle on an existing native handle. + /** + * This constructor creates a handle object to hold an existing native handle. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + basic_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_io_object<HandleService>(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_handle from another. + /** + * This constructor moves a handle from one object to another. + * + * @param other The other basic_handle object from which the move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_handle(io_context&) constructor. + */ + basic_handle(basic_handle&& other) + : basic_io_object<HandleService>( + ASIO_MOVE_CAST(basic_handle)(other)) + { + } + + /// Move-assign a basic_handle from another. + /** + * This assignment operator moves a handle from one object to another. + * + * @param other The other basic_handle object from which the move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_handle(io_context&) constructor. + */ + basic_handle& operator=(basic_handle&& other) + { + basic_io_object<HandleService>::operator=( + ASIO_MOVE_CAST(basic_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since a basic_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since a basic_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle functionality + * that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + ~basic_handle() + { + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_HANDLE_HPP diff --git a/lib/asio/windows/basic_object_handle.hpp b/lib/asio/windows/basic_object_handle.hpp new file mode 100644 index 0000000..4b29684 --- /dev/null +++ b/lib/asio/windows/basic_object_handle.hpp @@ -0,0 +1,182 @@ +// +// windows/basic_object_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/object_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides object-oriented handle functionality. +/** + * The windows::basic_object_handle class template provides asynchronous and + * blocking object-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename ObjectHandleService = object_handle_service> +class basic_object_handle + : public basic_handle<ObjectHandleService> +{ +public: + /// The native representation of a handle. + typedef typename ObjectHandleService::native_handle_type native_handle_type; + + /// Construct a basic_object_handle without opening it. + /** + * This constructor creates an object handle without opening it. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_object_handle(asio::io_context& io_context) + : basic_handle<ObjectHandleService>(io_context) + { + } + + /// Construct a basic_object_handle on an existing native handle. + /** + * This constructor creates an object handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_object_handle(asio::io_context& io_context, + const native_handle_type& native_handle) + : basic_handle<ObjectHandleService>(io_context, native_handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_object_handle from another. + /** + * This constructor moves an object handle from one object to another. + * + * @param other The other basic_object_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_object_handle(io_context&) constructor. + */ + basic_object_handle(basic_object_handle&& other) + : basic_handle<ObjectHandleService>( + ASIO_MOVE_CAST(basic_object_handle)(other)) + { + } + + /// Move-assign a basic_object_handle from another. + /** + * This assignment operator moves an object handle from one object to another. + * + * @param other The other basic_object_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_object_handle(io_context&) constructor. + */ + basic_object_handle& operator=(basic_object_handle&& other) + { + basic_handle<ObjectHandleService>::operator=( + ASIO_MOVE_CAST(basic_object_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the object handle. + /** + * This function is be used to initiate an asynchronous wait against the + * object handle. It always returns immediately. + * + * @param handler The handler to be called when the object handle is set to + * the signalled state. Copies will be made of the handler as required. The + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @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 + * asio::io_context::post(). + */ + template <typename WaitHandler> + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(ASIO_MOVE_ARG(WaitHandler) handler) + { + return this->get_service().async_wait(this->get_implementation(), + ASIO_MOVE_CAST(WaitHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP diff --git a/lib/asio/windows/basic_random_access_handle.hpp b/lib/asio/windows/basic_random_access_handle.hpp new file mode 100644 index 0000000..4226977 --- /dev/null +++ b/lib/asio/windows/basic_random_access_handle.hpp @@ -0,0 +1,376 @@ +// +// windows/basic_random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include <cstddef> +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/random_access_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides random-access handle functionality. +/** + * The windows::basic_random_access_handle class template provides asynchronous + * and blocking random-access handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename RandomAccessHandleService = random_access_handle_service> +class basic_random_access_handle + : public basic_handle<RandomAccessHandleService> +{ +public: + /// The native representation of a handle. + typedef typename RandomAccessHandleService::native_handle_type + native_handle_type; + + /// Construct a basic_random_access_handle without opening it. + /** + * This constructor creates a random-access handle without opening it. The + * handle needs to be opened before data can be written to or read from it. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + */ + explicit basic_random_access_handle(asio::io_context& io_context) + : basic_handle<RandomAccessHandleService>(io_context) + { + } + + /// Construct a basic_random_access_handle on an existing native handle. + /** + * This constructor creates a random-access handle object to hold an existing + * native handle. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_random_access_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_handle<RandomAccessHandleService>(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_random_access_handle from another. + /** + * This constructor moves a random-access handle from one object to another. + * + * @param other The other basic_random_access_handle object from which the + * move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_random_access_handle(io_context&) + * constructor. + */ + basic_random_access_handle(basic_random_access_handle&& other) + : basic_handle<RandomAccessHandleService>( + ASIO_MOVE_CAST(basic_random_access_handle)(other)) + { + } + + /// Move-assign a basic_random_access_handle from another. + /** + * This assignment operator moves a random-access handle from one object to + * another. + * + * @param other The other basic_random_access_handle object from which the + * move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_random_access_handle(io_context&) + * constructor. + */ + basic_random_access_handle& operator=(basic_random_access_handle&& other) + { + basic_handle<RandomAccessHandleService>::operator=( + ASIO_MOVE_CAST(basic_random_access_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some_at operation may not write all of the data. Consider + * using the @ref write_at function if you need to ensure that all data is + * written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence> + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "write_some_at"); + return s; + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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 @ref write_at function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + /** + * This function is used to asynchronously write data to the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write_at function if you need to ensure that + * all data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some_at(this->get_implementation(), + offset, buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence> + std::size_t read_some_at(uint64_t offset, + const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "read_some_at"); + return s; + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more 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 @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + /** + * This function is used to asynchronously read data from the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be read. + * + * @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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read_at function if you need to ensure that + * the requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some_at(this->get_implementation(), + offset, buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP diff --git a/lib/asio/windows/basic_stream_handle.hpp b/lib/asio/windows/basic_stream_handle.hpp new file mode 100644 index 0000000..3bfce68 --- /dev/null +++ b/lib/asio/windows/basic_stream_handle.hpp @@ -0,0 +1,359 @@ +// +// windows/basic_stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include <cstddef> +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/windows/basic_handle.hpp" +#include "asio/windows/stream_handle_service.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides stream-oriented handle functionality. +/** + * The windows::basic_stream_handle class template provides asynchronous and + * blocking stream-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template <typename StreamHandleService = stream_handle_service> +class basic_stream_handle + : public basic_handle<StreamHandleService> +{ +public: + /// The native representation of a handle. + typedef typename StreamHandleService::native_handle_type native_handle_type; + + /// Construct a basic_stream_handle without opening it. + /** + * This constructor creates a stream handle without opening it. The handle + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit basic_stream_handle(asio::io_context& io_context) + : basic_handle<StreamHandleService>(io_context) + { + } + + /// Construct a basic_stream_handle on an existing native handle. + /** + * This constructor creates a stream handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + basic_stream_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_handle<StreamHandleService>(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_stream_handle from another. + /** + * This constructor moves a stream handle from one object to another. + * + * @param other The other basic_stream_handle object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_handle(io_context&) constructor. + */ + basic_stream_handle(basic_stream_handle&& other) + : basic_handle<StreamHandleService>( + ASIO_MOVE_CAST(basic_stream_handle)(other)) + { + } + + /// Move-assign a basic_stream_handle from another. + /** + * This assignment operator moves a stream handle from one object to + * another. + * + * @param other The other basic_stream_handle object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_handle(io_context&) constructor. + */ + basic_stream_handle& operator=(basic_stream_handle&& other) + { + basic_handle<StreamHandleService>::operator=( + ASIO_MOVE_CAST(basic_stream_handle)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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 @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_write_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more 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 @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + return this->get_service().async_read_some(this->get_implementation(), + buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP diff --git a/lib/asio/windows/object_handle.hpp b/lib/asio/windows/object_handle.hpp new file mode 100644 index 0000000..581b568 --- /dev/null +++ b/lib/asio/windows/object_handle.hpp @@ -0,0 +1,381 @@ +// +// windows/object_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_OBJECT_HANDLE_HPP +#define ASIO_WINDOWS_OBJECT_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/win_object_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_HAS_MOVE) +# include <utility> +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_object_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#define ASIO_SVC_T asio::detail::win_object_handle_service + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of an object handle. +typedef basic_object_handle<> object_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides object-oriented handle functionality. +/** + * The windows::object_handle class provides asynchronous and blocking + * object-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class object_handle + : ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T> +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a handle. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// An object_handle is always the lowest layer. + typedef object_handle lowest_layer_type; + + /// Construct an object_handle without opening it. + /** + * This constructor creates an object handle without opening it. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit object_handle(asio::io_context& io_context) + : basic_io_object<ASIO_SVC_T>(io_context) + { + } + + /// Construct an object_handle on an existing native handle. + /** + * This constructor creates an object handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the object handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param native_handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + object_handle(asio::io_context& io_context, + const native_handle_type& native_handle) + : basic_io_object<ASIO_SVC_T>(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), native_handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct an object_handle from another. + /** + * This constructor moves an object handle from one object to another. + * + * @param other The other object_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c object_handle(io_context&) constructor. + */ + object_handle(object_handle&& other) + : basic_io_object<ASIO_SVC_T>(std::move(other)) + { + } + + /// Move-assign an object_handle from another. + /** + * This assignment operator moves an object handle from one object to another. + * + * @param other The other object_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c object_handle(io_context&) constructor. + */ + object_handle& operator=(object_handle&& other) + { + basic_io_object<ASIO_SVC_T>::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_context() + { + return basic_io_object<ASIO_SVC_T>::get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_service() + { + return basic_io_object<ASIO_SVC_T>::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object<ASIO_SVC_T>::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since an object_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since an object_handle cannot contain any further layers, it simply + * returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle functionality + * that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @throws asio::system_error Thrown on failure. + */ + void wait() + { + asio::error_code ec; + this->get_service().wait(this->get_implementation(), ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Perform a blocking wait on the object handle. + /** + * This function is used to wait for the object handle to be set to the + * signalled state. This function blocks and does not return until the object + * handle has been set to the signalled state. + * + * @param ec Set to indicate what error occurred, if any. + */ + void wait(asio::error_code& ec) + { + this->get_service().wait(this->get_implementation(), ec); + } + + /// Start an asynchronous wait on the object handle. + /** + * This function is be used to initiate an asynchronous wait against the + * object handle. It always returns immediately. + * + * @param handler The handler to be called when the object handle is set to + * the signalled state. Copies will be made of the handler as required. The + * function signature of the handler must be: + * @code void handler( + * const asio::error_code& error // Result of operation. + * ); @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 + * asio::io_context::post(). + */ + template <typename WaitHandler> + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(ASIO_MOVE_ARG(WaitHandler) handler) + { + asio::async_completion<WaitHandler, + void (asio::error_code)> init(handler); + + this->get_service().async_wait(this->get_implementation(), + init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_SVC_T + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_OBJECT_HANDLE_HPP diff --git a/lib/asio/windows/object_handle_service.hpp b/lib/asio/windows/object_handle_service.hpp new file mode 100644 index 0000000..95436d7 --- /dev/null +++ b/lib/asio/windows/object_handle_service.hpp @@ -0,0 +1,183 @@ +// +// windows/object_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2011 Boris Schaeling (boris@highscore.de) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/async_result.hpp" +#include "asio/detail/win_object_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for an object handle. +class object_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base<object_handle_service> +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_object_handle_service service_impl_type; + +public: + /// The type of an object handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new object handle service for the specified io_context. + explicit object_handle_service(asio::io_context& io_context) + : asio::detail::service_base<object_handle_service>(io_context), + service_impl_(io_context) + { + } + + /// Construct a new object handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new object handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another object handle implementation. + void move_assign(implementation_type& impl, + object_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy an object handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to an object handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close an object handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + // Wait for a signaled state. + void wait(implementation_type& impl, asio::error_code& ec) + { + service_impl_.wait(impl, ec); + } + + /// Start an asynchronous wait. + template <typename WaitHandler> + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(implementation_type& impl, + ASIO_MOVE_ARG(WaitHandler) handler) + { + asio::async_completion<WaitHandler, + void (asio::error_code)> init(handler); + + service_impl_.async_wait(impl, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP diff --git a/lib/asio/windows/overlapped_handle.hpp b/lib/asio/windows/overlapped_handle.hpp new file mode 100644 index 0000000..3d479ba --- /dev/null +++ b/lib/asio/windows/overlapped_handle.hpp @@ -0,0 +1,331 @@ +// +// windows/overlapped_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP +#define ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include <cstddef> +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#if defined(ASIO_HAS_MOVE) +# include <utility> +#endif // defined(ASIO_HAS_MOVE) + +#define ASIO_SVC_T asio::detail::win_iocp_handle_service + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Provides Windows handle functionality for objects that support +/// overlapped I/O. +/** + * The windows::overlapped_handle class provides the ability to wrap a Windows + * handle. The underlying object referred to by the handle must support + * overlapped I/O. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class overlapped_handle + : ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T> +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The native representation of a handle. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef ASIO_SVC_T::native_handle_type native_handle_type; +#endif + + /// An overlapped_handle is always the lowest layer. + typedef overlapped_handle lowest_layer_type; + + /// Construct an overlapped_handle without opening it. + /** + * This constructor creates a handle without opening it. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit overlapped_handle(asio::io_context& io_context) + : basic_io_object<ASIO_SVC_T>(io_context) + { + } + + /// Construct an overlapped_handle on an existing native handle. + /** + * This constructor creates a handle object to hold an existing native handle. + * + * @param io_context The io_context object that the handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + overlapped_handle(asio::io_context& io_context, + const native_handle_type& handle) + : basic_io_object<ASIO_SVC_T>(io_context) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct an overlapped_handle from another. + /** + * This constructor moves a handle from one object to another. + * + * @param other The other overlapped_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c overlapped_handle(io_context&) constructor. + */ + overlapped_handle(overlapped_handle&& other) + : basic_io_object<ASIO_SVC_T>(std::move(other)) + { + } + + /// Move-assign an overlapped_handle from another. + /** + * This assignment operator moves a handle from one object to another. + * + * @param other The other overlapped_handle object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c overlapped_handle(io_context&) constructor. + */ + overlapped_handle& operator=(overlapped_handle&& other) + { + basic_io_object<ASIO_SVC_T>::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_context() + { + return basic_io_object<ASIO_SVC_T>::get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_service() + { + return basic_io_object<ASIO_SVC_T>::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object<ASIO_SVC_T>::get_executor(); + } + + /// Get a reference to the lowest layer. + /** + * This function returns a reference to the lowest layer in a stack of + * layers. Since an overlapped_handle cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A reference to the lowest layer in the stack of layers. Ownership + * is not transferred to the caller. + */ + lowest_layer_type& lowest_layer() + { + return *this; + } + + /// Get a const reference to the lowest layer. + /** + * This function returns a const reference to the lowest layer in a stack of + * layers. Since an overlapped_handle cannot contain any further layers, it + * simply returns a reference to itself. + * + * @return A const reference to the lowest layer in the stack of layers. + * Ownership is not transferred to the caller. + */ + const lowest_layer_type& lowest_layer() const + { + return *this; + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @throws asio::system_error Thrown on failure. + */ + void assign(const native_handle_type& handle) + { + asio::error_code ec; + this->get_service().assign(this->get_implementation(), handle, ec); + asio::detail::throw_error(ec, "assign"); + } + + /// Assign an existing native handle to the handle. + /* + * This function opens the handle to hold an existing native handle. + * + * @param handle A native handle. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID assign(const native_handle_type& handle, + asio::error_code& ec) + { + this->get_service().assign(this->get_implementation(), handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void close() + { + asio::error_code ec; + this->get_service().close(this->get_implementation(), ec); + asio::detail::throw_error(ec, "close"); + } + + /// Close the handle. + /** + * This function is used to close the handle. Any asynchronous read or write + * operations will be cancelled immediately, and will complete with the + * asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID close(asio::error_code& ec) + { + this->get_service().close(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle representation. + /** + * This function may be used to obtain the underlying representation of the + * handle. This is intended to allow access to native handle functionality + * that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @throws asio::system_error Thrown on failure. + */ + void cancel() + { + asio::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the handle. + /** + * This function causes all outstanding asynchronous read or write operations + * to finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) + { + this->get_service().cancel(this->get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + +protected: + /// Protected destructor to prevent deletion through this type. + /** + * This function destroys the handle, cancelling any outstanding asynchronous + * wait operations associated with the handle as if by calling @c cancel. + */ + ~overlapped_handle() + { + } +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#undef ASIO_SVC_T + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP diff --git a/lib/asio/windows/overlapped_ptr.hpp b/lib/asio/windows/overlapped_ptr.hpp new file mode 100644 index 0000000..ce0b2a4 --- /dev/null +++ b/lib/asio/windows/overlapped_ptr.hpp @@ -0,0 +1,116 @@ +// +// windows/overlapped_ptr.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_OVERLAPPED_PTR_HPP +#define ASIO_WINDOWS_OVERLAPPED_PTR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \ + || defined(GENERATING_DOCUMENTATION) + +#include "asio/detail/noncopyable.hpp" +#include "asio/detail/win_iocp_overlapped_ptr.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O. +/** + * A special-purpose smart pointer used to wrap an application handler so that + * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class overlapped_ptr + : private noncopyable +{ +public: + /// Construct an empty overlapped_ptr. + overlapped_ptr() + : impl_() + { + } + + /// Construct an overlapped_ptr to contain the specified handler. + template <typename Handler> + explicit overlapped_ptr(asio::io_context& io_context, + ASIO_MOVE_ARG(Handler) handler) + : impl_(io_context, ASIO_MOVE_CAST(Handler)(handler)) + { + } + + /// Destructor automatically frees the OVERLAPPED object unless released. + ~overlapped_ptr() + { + } + + /// Reset to empty. + void reset() + { + impl_.reset(); + } + + /// Reset to contain the specified handler, freeing any current OVERLAPPED + /// object. + template <typename Handler> + void reset(asio::io_context& io_context, + ASIO_MOVE_ARG(Handler) handler) + { + impl_.reset(io_context, ASIO_MOVE_CAST(Handler)(handler)); + } + + /// Get the contained OVERLAPPED object. + OVERLAPPED* get() + { + return impl_.get(); + } + + /// Get the contained OVERLAPPED object. + const OVERLAPPED* get() const + { + return impl_.get(); + } + + /// Release ownership of the OVERLAPPED object. + OVERLAPPED* release() + { + return impl_.release(); + } + + /// Post completion notification for overlapped operation. Releases ownership. + void complete(const asio::error_code& ec, + std::size_t bytes_transferred) + { + impl_.complete(ec, bytes_transferred); + } + +private: + detail::win_iocp_overlapped_ptr impl_; +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP diff --git a/lib/asio/windows/random_access_handle.hpp b/lib/asio/windows/random_access_handle.hpp new file mode 100644 index 0000000..301d5f8 --- /dev/null +++ b/lib/asio/windows/random_access_handle.hpp @@ -0,0 +1,378 @@ +// +// windows/random_access_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/windows/overlapped_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_random_access_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a random-access handle. +typedef basic_random_access_handle<> random_access_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides random-access handle functionality. +/** + * The windows::random_access_handle class provides asynchronous and + * blocking random-access handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class random_access_handle + : public overlapped_handle +{ +public: + /// Construct a random_access_handle without opening it. + /** + * This constructor creates a random-access handle without opening it. The + * handle needs to be opened before data can be written to or read from it. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + */ + explicit random_access_handle(asio::io_context& io_context) + : overlapped_handle(io_context) + { + } + + /// Construct a random_access_handle on an existing native handle. + /** + * This constructor creates a random-access handle object to hold an existing + * native handle. + * + * @param io_context The io_context object that the random-access handle will + * use to dispatch handlers for any asynchronous operations performed on the + * handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + random_access_handle(asio::io_context& io_context, + const native_handle_type& handle) + : overlapped_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a random_access_handle from another. + /** + * This constructor moves a random-access handle from one object to another. + * + * @param other The other random_access_handle object from which the + * move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c random_access_handle(io_context&) + * constructor. + */ + random_access_handle(random_access_handle&& other) + : overlapped_handle(std::move(other)) + { + } + + /// Move-assign a random_access_handle from another. + /** + * This assignment operator moves a random-access handle from one object to + * another. + * + * @param other The other random_access_handle object from which the + * move will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c random_access_handle(io_context&) + * constructor. + */ + random_access_handle& operator=(random_access_handle&& other) + { + overlapped_handle::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some_at operation may not write all of the data. Consider + * using the @ref write_at function if you need to ensure that all data is + * written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence> + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "write_some_at"); + return s; + } + + /// Write some data to the handle at the specified offset. + /** + * This function is used to write data to the random-access handle. The + * function call will block until one or more bytes of the data has been + * written successfully, or until an error occurs. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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 @ref write_at function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().write_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + /** + * This function is used to asynchronously write data to the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be written. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write_at function if you need to ensure that + * all data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(uint64_t offset, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion<WriteHandler, + void (asio::error_code, std::size_t)> init(handler); + + this->get_service().async_write_some_at(this->get_implementation(), + offset, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some_at(42, asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence> + std::size_t read_some_at(uint64_t offset, + const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + asio::detail::throw_error(ec, "read_some_at"); + return s; + } + + /// Read some data from the handle at the specified offset. + /** + * This function is used to read data from the random-access handle. The + * function call will block until one or more bytes of data has been read + * successfully, or until an error occurs. + * + * @param offset The offset at which the data will be read. + * + * @param buffers One or more 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 @ref read_at function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return this->get_service().read_some_at( + this->get_implementation(), offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + /** + * This function is used to asynchronously read data from the random-access + * handle. The function call always returns immediately. + * + * @param offset The offset at which the data will be read. + * + * @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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read_at function if you need to ensure that + * the requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some_at(42, asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(uint64_t offset, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion<ReadHandler, + void (asio::error_code, std::size_t)> init(handler); + + this->get_service().async_read_some_at(this->get_implementation(), + offset, buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP diff --git a/lib/asio/windows/random_access_handle_service.hpp b/lib/asio/windows/random_access_handle_service.hpp new file mode 100644 index 0000000..ebccf3e --- /dev/null +++ b/lib/asio/windows/random_access_handle_service.hpp @@ -0,0 +1,214 @@ +// +// windows/random_access_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include <cstddef> +#include "asio/async_result.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for a random-access handle. +class random_access_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base<random_access_handle_service> +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a random-access handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new random-access handle service for the specified io_context. + explicit random_access_handle_service(asio::io_context& io_context) + : asio::detail::service_base< + random_access_handle_service>(io_context), + service_impl_(io_context) + { + } + + /// Construct a new random-access handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new random-access handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another random-access handle implementation. + void move_assign(implementation_type& impl, + random_access_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a random-access handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a random-access handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a random-access handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data at the specified offset. + template <typename ConstBufferSequence> + std::size_t write_some_at(implementation_type& impl, uint64_t offset, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous write at the specified offset. + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some_at(implementation_type& impl, + uint64_t offset, const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + asio::async_completion<WriteHandler, + void (asio::error_code, std::size_t)> init(handler); + + service_impl_.async_write_some_at(impl, + offset, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the specified offset. + template <typename MutableBufferSequence> + std::size_t read_some_at(implementation_type& impl, uint64_t offset, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some_at(impl, offset, buffers, ec); + } + + /// Start an asynchronous read at the specified offset. + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some_at(implementation_type& impl, + uint64_t offset, const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + asio::async_completion<ReadHandler, + void (asio::error_code, std::size_t)> init(handler); + + service_impl_.async_read_some_at(impl, + offset, buffers, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP diff --git a/lib/asio/windows/stream_handle.hpp b/lib/asio/windows/stream_handle.hpp new file mode 100644 index 0000000..8f0a21b --- /dev/null +++ b/lib/asio/windows/stream_handle.hpp @@ -0,0 +1,362 @@ +// +// windows/stream_handle.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_STREAM_HANDLE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/windows/overlapped_handle.hpp" + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/windows/basic_stream_handle.hpp" +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +#if defined(ASIO_ENABLE_OLD_SERVICES) +// Typedef for the typical usage of a stream-oriented handle. +typedef basic_stream_handle<> stream_handle; +#else // defined(ASIO_ENABLE_OLD_SERVICES) +/// Provides stream-oriented handle functionality. +/** + * The windows::stream_handle class provides asynchronous and blocking + * stream-oriented handle functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +class stream_handle + : public overlapped_handle +{ +public: + /// Construct a stream_handle without opening it. + /** + * This constructor creates a stream handle without opening it. The handle + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + */ + explicit stream_handle(asio::io_context& io_context) + : overlapped_handle(io_context) + { + } + + /// Construct a stream_handle on an existing native handle. + /** + * This constructor creates a stream handle object to hold an existing native + * handle. + * + * @param io_context The io_context object that the stream handle will use to + * dispatch handlers for any asynchronous operations performed on the handle. + * + * @param handle The new underlying handle implementation. + * + * @throws asio::system_error Thrown on failure. + */ + stream_handle(asio::io_context& io_context, + const native_handle_type& handle) + : overlapped_handle(io_context, handle) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a stream_handle from another. + /** + * This constructor moves a stream handle from one object to another. + * + * @param other The other stream_handle object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c stream_handle(io_context&) constructor. + */ + stream_handle(stream_handle&& other) + : overlapped_handle(std::move(other)) + { + } + + /// Move-assign a stream_handle from another. + /** + * This assignment operator moves a stream handle from one object to + * another. + * + * @param other The other stream_handle object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c stream_handle(io_context&) constructor. + */ + stream_handle& operator=(stream_handle&& other) + { + overlapped_handle::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @returns The number of bytes written. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.write_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().write_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the handle. + /** + * This function is used to write data to the stream handle. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the handle. + * + * @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 @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template <typename ConstBufferSequence> + std::size_t write_some(const ConstBufferSequence& buffers, + asio::error_code& ec) + { + return this->get_service().write_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream handle. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_write_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + asio::async_completion<WriteHandler, + void (asio::error_code, std::size_t)> init(handler); + + this->get_service().async_write_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws asio::system_error Thrown on failure. An error code of + * asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.read_some(asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers) + { + asio::error_code ec; + std::size_t s = this->get_service().read_some( + this->get_implementation(), buffers, ec); + asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the handle. + /** + * This function is used to read data from the stream handle. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more 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 @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template <typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence& buffers, + asio::error_code& ec) + { + return this->get_service().read_some( + this->get_implementation(), buffers, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream handle. + * 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 asio::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 + * asio::io_context::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * handle.async_read_some(asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + asio::async_completion<ReadHandler, + void (asio::error_code, std::size_t)> init(handler); + + this->get_service().async_read_some( + this->get_implementation(), buffers, init.completion_handler); + + return init.result.get(); + } +}; +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_WINDOWS_STREAM_HANDLE_HPP diff --git a/lib/asio/windows/stream_handle_service.hpp b/lib/asio/windows/stream_handle_service.hpp new file mode 100644 index 0000000..1c665d5 --- /dev/null +++ b/lib/asio/windows/stream_handle_service.hpp @@ -0,0 +1,210 @@ +// +// windows/stream_handle_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP +#define ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \ + || defined(GENERATING_DOCUMENTATION) + +#include <cstddef> +#include "asio/async_result.hpp" +#include "asio/detail/win_iocp_handle_service.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace windows { + +/// Default service implementation for a stream handle. +class stream_handle_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base<stream_handle_service> +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + +private: + // The type of the platform-specific implementation. + typedef detail::win_iocp_handle_service service_impl_type; + +public: + /// The type of a stream handle implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef service_impl_type::implementation_type implementation_type; +#endif + + /// The native handle type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new stream handle service for the specified io_context. + explicit stream_handle_service(asio::io_context& io_context) + : asio::detail::service_base<stream_handle_service>(io_context), + service_impl_(io_context) + { + } + + /// Construct a new stream handle implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new stream handle implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another stream handle implementation. + void move_assign(implementation_type& impl, + stream_handle_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a stream handle implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Assign an existing native handle to a stream handle. + ASIO_SYNC_OP_VOID assign(implementation_type& impl, + const native_handle_type& handle, asio::error_code& ec) + { + service_impl_.assign(impl, handle, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Determine whether the handle is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream handle implementation. + ASIO_SYNC_OP_VOID close(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.close(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Get the native handle implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the handle. + ASIO_SYNC_OP_VOID cancel(implementation_type& impl, + asio::error_code& ec) + { + service_impl_.cancel(impl, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Write the given data to the stream. + template <typename ConstBufferSequence> + std::size_t write_some(implementation_type& impl, + const ConstBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.write_some(impl, buffers, ec); + } + + /// Start an asynchronous write. + template <typename ConstBufferSequence, typename WriteHandler> + ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (asio::error_code, std::size_t)) + async_write_some(implementation_type& impl, + const ConstBufferSequence& buffers, + ASIO_MOVE_ARG(WriteHandler) handler) + { + asio::async_completion<WriteHandler, + void (asio::error_code, std::size_t)> init(handler); + + service_impl_.async_write_some(impl, buffers, init.completion_handler); + + return init.result.get(); + } + + /// Read some data from the stream. + template <typename MutableBufferSequence> + std::size_t read_some(implementation_type& impl, + const MutableBufferSequence& buffers, asio::error_code& ec) + { + return service_impl_.read_some(impl, buffers, ec); + } + + /// Start an asynchronous read. + template <typename MutableBufferSequence, typename ReadHandler> + ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (asio::error_code, std::size_t)) + async_read_some(implementation_type& impl, + const MutableBufferSequence& buffers, + ASIO_MOVE_ARG(ReadHandler) handler) + { + asio::async_completion<ReadHandler, + void (asio::error_code, std::size_t)> init(handler); + + service_impl_.async_read_some(impl, buffers, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace windows +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) + // || defined(GENERATING_DOCUMENTATION) + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP |