Add generic socket protocols and converting move constructors. Four new protocol classes have been added: - asio::generic::datagram_protocol - asio::generic::raw_protocol - asio::generic::seq_packet_protocol - asio::generic::stream_protocol These classes implement the Protocol type requirements, but allow the user to specify the address family (e.g. AF_INET) and protocol type (e.g. IPPROTO_TCP) at runtime. A new endpoint class template, asio::generic::basic_endpoint, has been added to support these new protocol classes. This endpoint can hold any other endpoint type, provided its native representation fits into a sockaddr_storage object. When using C++11, it is now possible to perform move construction from a socket (or acceptor) object to convert to the more generic protocol's socket (or acceptor) type. If the protocol conversion is valid: Protocol1 p1 = ...; Protocol2 p2(p1); then the corresponding socket conversion is allowed: Protocol1::socket socket1(io_service); ... Protocol2::socket socket2(std::move(socket1)); For example, one possible conversion is from a TCP socket to a generic stream-oriented socket: asio::ip::tcp::socket socket1(io_service); ... asio::generic::stream_protocol::socket socket2(std::move(socket1)); The conversion is also available for move-assignment. Note that these conversions are not limited to the newly added generic protocol classes. User-defined protocols may take advantage of this feature by similarly ensuring the conversion from Protocol1 to Protocol2 is valid, as above. As a convenience, the socket acceptor's accept() and async_accept() functions have been changed so that they can directly accept into a different protocol's socket type, provided the protocol conversion is valid. For example, the following is now possible: asio::ip::tcp::acceptor acceptor(io_service); ... asio::generic::stream_protocol::socket socket1(io_service); acceptor.accept(socket1);
diff --git a/asio/boostify.pl b/asio/boostify.pl index 03b3649..1beadd0 100755 --- a/asio/boostify.pl +++ b/asio/boostify.pl
@@ -332,6 +332,9 @@ "include/asio", "include/asio/detail", "include/asio/detail/impl", + "include/asio/generic", + "include/asio/generic/detail", + "include/asio/generic/detail/impl", "include/asio/impl", "include/asio/ip", "include/asio/ip/impl", @@ -389,6 +392,7 @@ my @dirs = ( "src/tests/unit", "src/tests/unit/archetypes", + "src/tests/unit/generic", "src/tests/unit/ip", "src/tests/unit/local", "src/tests/unit/posix",
diff --git a/asio/include/Makefile.am b/asio/include/Makefile.am index e573d6f..fa32331 100644 --- a/asio/include/Makefile.am +++ b/asio/include/Makefile.am
@@ -238,6 +238,13 @@ asio/detail/wrapped_handler.hpp \ asio/error_code.hpp \ asio/error.hpp \ + asio/generic/basic_endpoint.hpp \ + asio/generic/datagram_protocol.hpp \ + asio/generic/detail/endpoint.hpp \ + asio/generic/detail/impl/endpoint.ipp \ + asio/generic/raw_protocol.hpp \ + asio/generic/seq_packet_protocol.hpp \ + asio/generic/stream_protocol.hpp \ asio/handler_alloc_hook.hpp \ asio/handler_continuation_hook.hpp \ asio/handler_invoke_hook.hpp \
diff --git a/asio/include/asio.hpp b/asio/include/asio.hpp index 0664728..02cd1d5 100644 --- a/asio/include/asio.hpp +++ b/asio/include/asio.hpp
@@ -45,6 +45,11 @@ #include "asio/deadline_timer.hpp" #include "asio/error.hpp" #include "asio/error_code.hpp" +#include "asio/generic/basic_endpoint.hpp" +#include "asio/generic/datagram_protocol.hpp" +#include "asio/generic/raw_protocol.hpp" +#include "asio/generic/seq_packet_protocol.hpp" +#include "asio/generic/stream_protocol.hpp" #include "asio/handler_alloc_hook.hpp" #include "asio/handler_continuation_hook.hpp" #include "asio/handler_invoke_hook.hpp"
diff --git a/asio/include/asio/basic_datagram_socket.hpp b/asio/include/asio/basic_datagram_socket.hpp index 75005f8..6d9b4b6 100644 --- a/asio/include/asio/basic_datagram_socket.hpp +++ b/asio/include/asio/basic_datagram_socket.hpp
@@ -21,6 +21,7 @@ #include "asio/datagram_socket_service.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/detail/push_options.hpp" @@ -165,6 +166,50 @@ ASIO_MOVE_CAST(basic_datagram_socket)(other)); return *this; } + + /// Move-construct a basic_datagram_socket from a socket of another protocol + /// type. + /** + * This constructor moves a datagram socket from one object to another. + * + * @param other The other basic_datagram_socket 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_datagram_socket(io_service&) constructor. + */ + template <typename Protocol1, typename DatagramSocketService1> + basic_datagram_socket( + basic_datagram_socket<Protocol1, DatagramSocketService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_socket<Protocol, DatagramSocketService>( + ASIO_MOVE_CAST2(basic_datagram_socket< + Protocol1, DatagramSocketService1>)(other)) + { + } + + /// Move-assign a basic_datagram_socket from a socket of another protocol + /// type. + /** + * This assignment operator moves a datagram socket from one object to + * another. + * + * @param other The other basic_datagram_socket 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_datagram_socket(io_service&) constructor. + */ + template <typename Protocol1, typename DatagramSocketService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_datagram_socket>::type& operator=( + basic_datagram_socket<Protocol1, DatagramSocketService1>&& other) + { + basic_socket<Protocol, DatagramSocketService>::operator=( + ASIO_MOVE_CAST2(basic_datagram_socket< + Protocol1, DatagramSocketService1>)(other)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Send some data on a connected socket.
diff --git a/asio/include/asio/basic_raw_socket.hpp b/asio/include/asio/basic_raw_socket.hpp index db144c6..33c1530 100644 --- a/asio/include/asio/basic_raw_socket.hpp +++ b/asio/include/asio/basic_raw_socket.hpp
@@ -20,6 +20,7 @@ #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/raw_socket_service.hpp" @@ -164,6 +165,46 @@ ASIO_MOVE_CAST(basic_raw_socket)(other)); return *this; } + + /// Move-construct a basic_raw_socket from a socket of another protocol type. + /** + * This constructor moves a raw socket from one object to another. + * + * @param other The other basic_raw_socket 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_raw_socket(io_service&) constructor. + */ + template <typename Protocol1, typename RawSocketService1> + basic_raw_socket(basic_raw_socket<Protocol1, RawSocketService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_socket<Protocol, RawSocketService>( + ASIO_MOVE_CAST2(basic_raw_socket< + Protocol1, RawSocketService1>)(other)) + { + } + + /// Move-assign a basic_raw_socket from a socket of another protocol type. + /** + * This assignment operator moves a raw socket from one object to another. + * + * @param other The other basic_raw_socket 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_raw_socket(io_service&) constructor. + */ + template <typename Protocol1, typename RawSocketService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_raw_socket>::type& operator=( + basic_raw_socket<Protocol1, RawSocketService1>&& other) + { + basic_socket<Protocol, RawSocketService>::operator=( + ASIO_MOVE_CAST2(basic_raw_socket< + Protocol1, RawSocketService1>)(other)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Send some data on a connected socket.
diff --git a/asio/include/asio/basic_seq_packet_socket.hpp b/asio/include/asio/basic_seq_packet_socket.hpp index 17f1bad..74d3976 100644 --- a/asio/include/asio/basic_seq_packet_socket.hpp +++ b/asio/include/asio/basic_seq_packet_socket.hpp
@@ -170,6 +170,51 @@ ASIO_MOVE_CAST(basic_seq_packet_socket)(other)); return *this; } + + /// Move-construct a basic_seq_packet_socket from a socket of another protocol + /// type. + /** + * This constructor moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_socket 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_seq_packet_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SeqPacketSocketService1> + basic_seq_packet_socket( + basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_socket<Protocol, SeqPacketSocketService>( + ASIO_MOVE_CAST2(basic_seq_packet_socket< + Protocol1, SeqPacketSocketService1>)(other)) + { + } + + /// Move-assign a basic_seq_packet_socket from a socket of another protocol + /// type. + /** + * This assignment operator moves a sequenced packet socket from one object to + * another. + * + * @param other The other basic_seq_packet_socket 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_seq_packet_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SeqPacketSocketService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_seq_packet_socket>::type& operator=( + basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other) + { + basic_socket<Protocol, SeqPacketSocketService>::operator=( + ASIO_MOVE_CAST2(basic_seq_packet_socket< + Protocol1, SeqPacketSocketService1>)(other)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Send some data on the socket.
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp index 3407e76..64f55b4 100644 --- a/asio/include/asio/basic_socket.hpp +++ b/asio/include/asio/basic_socket.hpp
@@ -20,6 +20,7 @@ #include "asio/basic_io_object.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/socket_base.hpp" @@ -173,6 +174,51 @@ ASIO_MOVE_CAST(basic_socket)(other)); return *this; } + + // All sockets have access to each other's implementations. + template <typename Protocol1, typename SocketService1> + friend class basic_socket; + + /// Move-construct a basic_socket from a socket of another protocol type. + /** + * This constructor moves a socket from one object to another. + * + * @param other The other basic_socket 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SocketService1> + basic_socket(basic_socket<Protocol1, SocketService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_io_object<SocketService>(other.get_io_service()) + { + this->get_service().template converting_move_construct<Protocol1>( + this->get_implementation(), other.get_implementation()); + } + + /// Move-assign a basic_socket from a socket of another protocol type. + /** + * This assignment operator moves a socket from one object to another. + * + * @param other The other basic_socket 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SocketService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_socket>::type& operator=( + basic_socket<Protocol1, SocketService1>&& other) + { + basic_socket tmp(ASIO_MOVE_CAST2(basic_socket< + Protocol1, SocketService1>)(other)); + basic_io_object<SocketService>::operator=( + ASIO_MOVE_CAST(basic_socket)(tmp)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get a reference to the lowest layer.
diff --git a/asio/include/asio/basic_socket_acceptor.hpp b/asio/include/asio/basic_socket_acceptor.hpp index d8a395a..5606c51 100644 --- a/asio/include/asio/basic_socket_acceptor.hpp +++ b/asio/include/asio/basic_socket_acceptor.hpp
@@ -20,6 +20,7 @@ #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/socket_acceptor_service.hpp" #include "asio/socket_base.hpp" @@ -210,6 +211,54 @@ ASIO_MOVE_CAST(basic_socket_acceptor)(other)); return *this; } + + // All socket acceptors have access to each other's implementations. + template <typename Protocol1, typename SocketAcceptorService1> + friend class basic_socket_acceptor; + + /// Move-construct a basic_socket_acceptor from an acceptor of another + /// protocol type. + /** + * This constructor moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SocketAcceptorService1> + basic_socket_acceptor( + basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_io_object<SocketAcceptorService>(other.get_io_service()) + { + this->get_service().template converting_move_construct<Protocol1>( + this->get_implementation(), other.get_implementation()); + } + + /// Move-assign a basic_socket_acceptor from an acceptor of another protocol + /// type. + /** + * This assignment operator moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename SocketAcceptorService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_socket_acceptor>::type& operator=( + basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other) + { + basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor< + Protocol1, SocketAcceptorService1>)(other)); + basic_io_object<SocketAcceptorService>::operator=( + ASIO_MOVE_CAST(basic_socket_acceptor)(tmp)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Open the acceptor using the specified protocol. @@ -870,11 +919,13 @@ * acceptor.accept(socket); * @endcode */ - template <typename SocketService> - void accept(basic_socket<protocol_type, SocketService>& peer) + template <typename Protocol1, typename SocketService> + void accept(basic_socket<Protocol1, SocketService>& peer, + typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) { asio::error_code ec; - this->get_service().accept(this->get_implementation(), peer, 0, ec); + this->get_service().accept(this->get_implementation(), + peer, static_cast<endpoint_type*>(0), ec); asio::detail::throw_error(ec, "accept"); } @@ -901,12 +952,14 @@ * } * @endcode */ - template <typename SocketService> + template <typename Protocol1, typename SocketService> asio::error_code accept( - basic_socket<protocol_type, SocketService>& peer, - asio::error_code& ec) + basic_socket<Protocol1, SocketService>& peer, + asio::error_code& ec, + typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) { - return this->get_service().accept(this->get_implementation(), peer, 0, ec); + return this->get_service().accept(this->get_implementation(), + peer, static_cast<endpoint_type*>(0), ec); } /// Start an asynchronous accept. @@ -947,18 +1000,20 @@ * acceptor.async_accept(socket, accept_handler); * @endcode */ - template <typename SocketService, typename AcceptHandler> + template <typename Protocol1, typename SocketService, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (asio::error_code)) - async_accept(basic_socket<protocol_type, SocketService>& peer, - ASIO_MOVE_ARG(AcceptHandler) handler) + async_accept(basic_socket<Protocol1, SocketService>& peer, + ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) { // If you get an error on the following line it means that your handler does // not meet the documented type requirements for a AcceptHandler. ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; return this->get_service().async_accept(this->get_implementation(), - peer, 0, ASIO_MOVE_CAST(AcceptHandler)(handler)); + peer, static_cast<endpoint_type*>(0), + ASIO_MOVE_CAST(AcceptHandler)(handler)); } /// Accept a new connection and obtain the endpoint of the peer
diff --git a/asio/include/asio/basic_stream_socket.hpp b/asio/include/asio/basic_stream_socket.hpp index b370ddd..eaa86e6 100644 --- a/asio/include/asio/basic_stream_socket.hpp +++ b/asio/include/asio/basic_stream_socket.hpp
@@ -166,6 +166,48 @@ ASIO_MOVE_CAST(basic_stream_socket)(other)); return *this; } + + /// Move-construct a basic_stream_socket from a socket of another protocol + /// type. + /** + * This constructor moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename StreamSocketService1> + basic_stream_socket( + basic_stream_socket<Protocol1, StreamSocketService1>&& other, + typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) + : basic_socket<Protocol, StreamSocketService>( + ASIO_MOVE_CAST2(basic_stream_socket< + Protocol1, StreamSocketService1>)(other)) + { + } + + /// Move-assign a basic_stream_socket from a socket of another protocol type. + /** + * This assignment operator moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket 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_socket(io_service&) constructor. + */ + template <typename Protocol1, typename StreamSocketService1> + typename enable_if<is_convertible<Protocol1, Protocol>::value, + basic_stream_socket>::type& operator=( + basic_stream_socket<Protocol1, StreamSocketService1>&& other) + { + basic_socket<Protocol, StreamSocketService>::operator=( + ASIO_MOVE_CAST2(basic_stream_socket< + Protocol1, StreamSocketService1>)(other)); + return *this; + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Send some data on the socket.
diff --git a/asio/include/asio/datagram_socket_service.hpp b/asio/include/asio/datagram_socket_service.hpp index 2c35c79..eb8ac5e 100644 --- a/asio/include/asio/datagram_socket_service.hpp +++ b/asio/include/asio/datagram_socket_service.hpp
@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include <cstddef> #include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/io_service.hpp" @@ -111,6 +112,19 @@ { service_impl_.move_assign(impl, other_service.service_impl_, other_impl); } + + /// Move-construct a new datagram socket implementation from another protocol + /// type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename datagram_socket_service< + Protocol1>::implementation_type& other_impl, + typename enable_if<is_convertible< + Protocol1, Protocol>::value>::type* = 0) + { + service_impl_.template converting_move_construct<Protocol1>( + impl, other_impl); + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroy a datagram socket implementation.
diff --git a/asio/include/asio/detail/config.hpp b/asio/include/asio/detail/config.hpp index ccc74bc..3b08aac 100644 --- a/asio/include/asio/detail/config.hpp +++ b/asio/include/asio/detail/config.hpp
@@ -106,6 +106,7 @@ #if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) # define ASIO_MOVE_ARG(type) type&& # define ASIO_MOVE_CAST(type) static_cast<type&&> +# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&> #endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST) // If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible @@ -130,7 +131,8 @@ # define ASIO_MOVE_ARG(type) type # endif # define ASIO_MOVE_CAST(type) static_cast<const type&> -#endif // !defined_ASIO_MOVE_CAST +# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&> +#endif // !defined(ASIO_MOVE_CAST) // Support variadic templates on compilers known to allow it. #if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
diff --git a/asio/include/asio/detail/reactive_socket_service.hpp b/asio/include/asio/detail/reactive_socket_service.hpp index 4ef4b3f..bcce254 100644 --- a/asio/include/asio/detail/reactive_socket_service.hpp +++ b/asio/include/asio/detail/reactive_socket_service.hpp
@@ -98,6 +98,18 @@ other_impl.protocol_ = endpoint_type().protocol(); } + // Move-construct a new socket implementation from another protocol type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename reactive_socket_service< + Protocol1>::implementation_type& other_impl) + { + this->base_move_construct(impl, other_impl); + + impl.protocol_ = protocol_type(other_impl.protocol_); + other_impl.protocol_ = typename Protocol1::endpoint().protocol(); + } + // Open a new socket implementation. asio::error_code open(implementation_type& impl, const protocol_type& protocol, asio::error_code& ec)
diff --git a/asio/include/asio/generic/basic_endpoint.hpp b/asio/include/asio/generic/basic_endpoint.hpp new file mode 100644 index 0000000..77452b4 --- /dev/null +++ b/asio/include/asio/generic/basic_endpoint.hpp
@@ -0,0 +1,193 @@ +// +// generic/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_BASIC_ENDPOINT_HPP +#define ASIO_GENERIC_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/generic/detail/endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Describes an endpoint for any socket type. +/** + * The asio::generic::basic_endpoint class template describes an endpoint + * that may be associated with any socket type. + * + * @note The socket types sockaddr type must be able to fit into a + * @c sockaddr_storage structure. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template <typename Protocol> +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef Protocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + { + } + + /// Construct an endpoint from the specified socket address. + basic_endpoint(const void* socket_address, + std::size_t socket_address_size, int socket_protocol = 0) + : impl_(socket_address, socket_address_size, socket_protocol) + { + } + + /// Construct an endpoint from the specific endpoint type. + template <typename Endpoint> + basic_endpoint(const Endpoint& endpoint) + : impl_(endpoint.data(), endpoint.size(), endpoint.protocol().protocol()) + { + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : impl_(other.impl_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_endpoint(basic_endpoint&& other) + : impl_(other.impl_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another endpoint. + basic_endpoint& operator=(basic_endpoint&& other) + { + impl_ = other.impl_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + return protocol_type(impl_.family(), impl_.protocol()); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return impl_.size(); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t new_size) + { + impl_.resize(new_size); + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return impl_.capacity(); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return e1.impl_ == e2.impl_; + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return !(e1.impl_ == e2.impl_); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return e1.impl_ < e2.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return !(e2 < e1); + } + + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint<Protocol>& e1, + const basic_endpoint<Protocol>& e2) + { + return !(e1 < e2); + } + +private: + // The underlying generic endpoint. + asio::generic::detail::endpoint impl_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_BASIC_ENDPOINT_HPP
diff --git a/asio/include/asio/generic/datagram_protocol.hpp b/asio/include/asio/generic/datagram_protocol.hpp new file mode 100644 index 0000000..6370bc6 --- /dev/null +++ b/asio/include/asio/generic/datagram_protocol.hpp
@@ -0,0 +1,123 @@ +// +// generic/datagram_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP +#define ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <typeinfo> +#include "asio/basic_datagram_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic datagram-oriented socket. +/** + * The asio::generic::datagram_protocol class contains flags necessary + * for datagram-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code datagram_protocol p(AF_INET, IPPROTO_UDP); @endcode + * Constructing from a specific protocol type: + * @code datagram_protocol p(asio::ip::udp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class datagram_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + datagram_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not datagram-oriented. + */ + template <typename Protocol> + datagram_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_DGRAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const datagram_protocol& p1, + const datagram_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const datagram_protocol& p1, + const datagram_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint<datagram_protocol> endpoint; + + /// The generic socket type. + typedef basic_datagram_socket<datagram_protocol> socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/detail/endpoint.hpp b/asio/include/asio/generic/detail/endpoint.hpp new file mode 100644 index 0000000..b9415ae --- /dev/null +++ b/asio/include/asio/generic/detail/endpoint.hpp
@@ -0,0 +1,133 @@ +// +// generic/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_DETAIL_ENDPOINT_HPP +#define ASIO_GENERIC_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <cstddef> +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { +namespace detail { + +// Helper class for implementing a generic socket endpoint. +class endpoint +{ +public: + // Default constructor. + ASIO_DECL endpoint(); + + // Construct an endpoint from the specified raw bytes. + ASIO_DECL endpoint(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_), + size_(other.size_), + protocol_(other.protocol_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + size_ = other.size_; + protocol_ = other.protocol_; + return *this; + } + + // Get the address family associated with the endpoint. + int family() const + { + return data_.base.sa_family; + } + + // Get the socket protocol associated with the endpoint. + int protocol() const + { + return protocol_; + } + + // Get the underlying endpoint in the native type. + asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return size_; + } + + // Set the underlying size of the endpoint in the native type. + ASIO_DECL void resize(std::size_t size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(asio::detail::sockaddr_storage_type); + } + + // Compare two endpoints for equality. + ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + +private: + // The underlying socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_storage_type generic; + } data_; + + // The length of the socket address stored in the endpoint. + std::size_t size_; + + // The socket protocol associated with the endpoint. + int protocol_; + + // Initialise with a specified memory. + ASIO_DECL void init(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol); +}; + +} // namespace detail +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/generic/detail/impl/endpoint.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_GENERIC_DETAIL_ENDPOINT_HPP
diff --git a/asio/include/asio/generic/detail/impl/endpoint.ipp b/asio/include/asio/generic/detail/impl/endpoint.ipp new file mode 100644 index 0000000..8399d95 --- /dev/null +++ b/asio/include/asio/generic/detail/impl/endpoint.ipp
@@ -0,0 +1,109 @@ +// +// generic/detail/impl/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP +#define ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <cstring> +#include <typeinfo> +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/error.hpp" +#include "asio/generic/detail/endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { +namespace detail { + +endpoint::endpoint() +{ + init(0, 0, 0); +} + +endpoint::endpoint(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol) +{ + init(sock_addr, sock_addr_size, sock_protocol); +} + +void endpoint::resize(std::size_t new_size) +{ + if (new_size > sizeof(asio::detail::sockaddr_storage_type)) + { + asio::error_code ec(asio::error::invalid_argument); + asio::detail::throw_error(ec); + } + else + { + size_ = new_size; + protocol_ = 0; + } +} + +bool operator==(const endpoint& e1, const endpoint& e2) +{ + using namespace std; // For memcmp. + return e1.size() == e2.size() && memcmp(e1.data(), e2.data(), e1.size()) == 0; +} + +bool operator<(const endpoint& e1, const endpoint& e2) +{ + if (e1.protocol() < e2.protocol()) + return true; + + if (e1.protocol() > e2.protocol()) + return false; + + using namespace std; // For memcmp. + std::size_t compare_size = e1.size() < e2.size() ? e1.size() : e2.size(); + int compare_result = memcmp(e1.data(), e2.data(), compare_size); + + if (compare_result < 0) + return true; + + if (compare_result > 0) + return false; + + return e1.size() < e2.size(); +} + +void endpoint::init(const void* sock_addr, + std::size_t sock_addr_size, int sock_protocol) +{ + if (sock_addr_size > sizeof(asio::detail::sockaddr_storage_type)) + { + asio::error_code ec(asio::error::invalid_argument); + asio::detail::throw_error(ec); + } + + using namespace std; // For memset and memcpy. + memset(&data_.generic, 0, sizeof(asio::detail::sockaddr_storage_type)); + memcpy(&data_.generic, sock_addr, sock_addr_size); + + size_ = sock_addr_size; + protocol_ = sock_protocol; +} + +} // namespace detail +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP
diff --git a/asio/include/asio/generic/raw_protocol.hpp b/asio/include/asio/generic/raw_protocol.hpp new file mode 100644 index 0000000..e054a7f --- /dev/null +++ b/asio/include/asio/generic/raw_protocol.hpp
@@ -0,0 +1,121 @@ +// +// generic/raw_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_RAW_PROTOCOL_HPP +#define ASIO_GENERIC_RAW_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <typeinfo> +#include "asio/basic_raw_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic raw socket. +/** + * The asio::generic::raw_protocol class contains flags necessary for + * raw sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code raw_protocol p(AF_INET, IPPROTO_ICMP); @endcode + * Constructing from a specific protocol type: + * @code raw_protocol p(asio::ip::icmp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class raw_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + raw_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not raw-oriented. + */ + template <typename Protocol> + raw_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_RAW; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const raw_protocol& p1, const raw_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const raw_protocol& p1, const raw_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint<raw_protocol> endpoint; + + /// The generic socket type. + typedef basic_raw_socket<raw_protocol> socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_RAW_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/seq_packet_protocol.hpp b/asio/include/asio/generic/seq_packet_protocol.hpp new file mode 100644 index 0000000..fdd068d --- /dev/null +++ b/asio/include/asio/generic/seq_packet_protocol.hpp
@@ -0,0 +1,122 @@ +// +// generic/seq_packet_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP +#define ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <typeinfo> +#include "asio/basic_seq_packet_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic sequenced packet socket. +/** + * The asio::generic::seq_packet_protocol class contains flags necessary + * for seq_packet-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code seq_packet_protocol p(AF_INET, IPPROTO_SCTP); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class seq_packet_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + seq_packet_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not based around + * sequenced packets. + */ + template <typename Protocol> + seq_packet_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_SEQPACKET; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const seq_packet_protocol& p1, + const seq_packet_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const seq_packet_protocol& p1, + const seq_packet_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint<seq_packet_protocol> endpoint; + + /// The generic socket type. + typedef basic_seq_packet_socket<seq_packet_protocol> socket; + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/stream_protocol.hpp b/asio/include/asio/generic/stream_protocol.hpp new file mode 100644 index 0000000..369071c --- /dev/null +++ b/asio/include/asio/generic/stream_protocol.hpp
@@ -0,0 +1,127 @@ +// +// generic/stream_protocol.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_GENERIC_STREAM_PROTOCOL_HPP +#define ASIO_GENERIC_STREAM_PROTOCOL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#include <typeinfo> +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/generic/basic_endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace generic { + +/// Encapsulates the flags needed for a generic stream-oriented socket. +/** + * The asio::generic::stream_protocol class contains flags necessary for + * stream-oriented sockets of any address family and protocol. + * + * @par Examples + * Constructing using a native address family and socket protocol: + * @code stream_protocol p(AF_INET, IPPROTO_TCP); @endcode + * Constructing from a specific protocol type: + * @code stream_protocol p(asio::ip::tcp::v4()); @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class stream_protocol +{ +public: + /// Construct a protocol object for a specific address family and protocol. + stream_protocol(int address_family, int socket_protocol) + : family_(address_family), + protocol_(socket_protocol) + { + } + + /// Construct a generic protocol object from a specific protocol. + /** + * @throws @c bad_cast Thrown if the source protocol is not stream-oriented. + */ + template <typename Protocol> + stream_protocol(const Protocol& source_protocol) + : family_(source_protocol.family()), + protocol_(source_protocol.protocol()) + { + if (source_protocol.type() != type()) + { + std::bad_cast ex; + asio::detail::throw_exception(ex); + } + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_STREAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// Compare two protocols for equality. + friend bool operator==(const stream_protocol& p1, const stream_protocol& p2) + { + return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const stream_protocol& p1, const stream_protocol& p2) + { + return !(p1 == p2); + } + + /// The type of an endpoint. + typedef basic_endpoint<stream_protocol> endpoint; + + /// The generic socket type. + typedef basic_stream_socket<stream_protocol> socket; + +#if !defined(ASIO_NO_IOSTREAM) + /// The generic socket iostream type. + typedef basic_socket_iostream<stream_protocol> iostream; +#endif // !defined(ASIO_NO_IOSTREAM) + +private: + int family_; + int protocol_; +}; + +} // namespace generic +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_GENERIC_STREAM_PROTOCOL_HPP
diff --git a/asio/include/asio/impl/src.hpp b/asio/include/asio/impl/src.hpp index 7dd7c6b..1b3df96 100644 --- a/asio/include/asio/impl/src.hpp +++ b/asio/include/asio/impl/src.hpp
@@ -60,6 +60,7 @@ #include "asio/detail/impl/win_thread.ipp" #include "asio/detail/impl/win_tss_ptr.ipp" #include "asio/detail/impl/winsock_init.ipp" +#include "asio/generic/detail/impl/endpoint.ipp" #include "asio/ip/impl/address.ipp" #include "asio/ip/impl/address_v4.ipp" #include "asio/ip/impl/address_v6.ipp"
diff --git a/asio/include/asio/raw_socket_service.hpp b/asio/include/asio/raw_socket_service.hpp index 4a79f25..0dd63d5 100644 --- a/asio/include/asio/raw_socket_service.hpp +++ b/asio/include/asio/raw_socket_service.hpp
@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include <cstddef> #include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/io_service.hpp" @@ -111,6 +112,19 @@ { service_impl_.move_assign(impl, other_service.service_impl_, other_impl); } + + /// Move-construct a new raw socket implementation from another protocol + /// type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename raw_socket_service< + Protocol1>::implementation_type& other_impl, + typename enable_if<is_convertible< + Protocol1, Protocol>::value>::type* = 0) + { + service_impl_.template converting_move_construct<Protocol1>( + impl, other_impl); + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroy a raw socket implementation.
diff --git a/asio/include/asio/seq_packet_socket_service.hpp b/asio/include/asio/seq_packet_socket_service.hpp index 6f62c51..955a234 100644 --- a/asio/include/asio/seq_packet_socket_service.hpp +++ b/asio/include/asio/seq_packet_socket_service.hpp
@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include <cstddef> #include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/io_service.hpp" @@ -113,6 +114,19 @@ { service_impl_.move_assign(impl, other_service.service_impl_, other_impl); } + + /// Move-construct a new sequenced packet socket implementation from another + /// protocol type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename seq_packet_socket_service< + Protocol1>::implementation_type& other_impl, + typename enable_if<is_convertible< + Protocol1, Protocol>::value>::type* = 0) + { + service_impl_.template converting_move_construct<Protocol1>( + impl, other_impl); + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroy a sequenced packet socket implementation.
diff --git a/asio/include/asio/socket_acceptor_service.hpp b/asio/include/asio/socket_acceptor_service.hpp index 39e9587..d07fa52 100644 --- a/asio/include/asio/socket_acceptor_service.hpp +++ b/asio/include/asio/socket_acceptor_service.hpp
@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include "asio/basic_socket.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/io_service.hpp" @@ -110,6 +111,19 @@ { service_impl_.move_assign(impl, other_service.service_impl_, other_impl); } + + /// Move-construct a new socket acceptor implementation from another protocol + /// type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename socket_acceptor_service< + Protocol1>::implementation_type& other_impl, + typename enable_if<is_convertible< + Protocol1, Protocol>::value>::type* = 0) + { + service_impl_.template converting_move_construct<Protocol1>( + impl, other_impl); + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroy a socket acceptor implementation. @@ -238,22 +252,24 @@ } /// Accept a new connection. - template <typename SocketService> + template <typename Protocol1, typename SocketService> asio::error_code accept(implementation_type& impl, - basic_socket<protocol_type, SocketService>& peer, - endpoint_type* peer_endpoint, asio::error_code& ec) + basic_socket<Protocol1, SocketService>& peer, + endpoint_type* peer_endpoint, asio::error_code& ec, + typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) { return service_impl_.accept(impl, peer, peer_endpoint, ec); } /// Start an asynchronous accept. - template <typename SocketService, typename AcceptHandler> + template <typename Protocol1, typename SocketService, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (asio::error_code)) async_accept(implementation_type& impl, - basic_socket<protocol_type, SocketService>& peer, + basic_socket<Protocol1, SocketService>& peer, endpoint_type* peer_endpoint, - ASIO_MOVE_ARG(AcceptHandler) handler) + ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) { detail::async_result_init< AcceptHandler, void (asio::error_code)> init(
diff --git a/asio/include/asio/stream_socket_service.hpp b/asio/include/asio/stream_socket_service.hpp index 3fc3d21..e94e731 100644 --- a/asio/include/asio/stream_socket_service.hpp +++ b/asio/include/asio/stream_socket_service.hpp
@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include <cstddef> #include "asio/async_result.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" #include "asio/io_service.hpp" @@ -111,6 +112,19 @@ { service_impl_.move_assign(impl, other_service.service_impl_, other_impl); } + + /// Move-construct a new stream socket implementation from another protocol + /// type. + template <typename Protocol1> + void converting_move_construct(implementation_type& impl, + typename stream_socket_service< + Protocol1>::implementation_type& other_impl, + typename enable_if<is_convertible< + Protocol1, Protocol>::value>::type* = 0) + { + service_impl_.template converting_move_construct<Protocol1>( + impl, other_impl); + } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroy a stream socket implementation.
diff --git a/asio/src/Makefile.mgw b/asio/src/Makefile.mgw index 655e79d..015da58 100644 --- a/asio/src/Makefile.mgw +++ b/asio/src/Makefile.mgw
@@ -36,6 +36,11 @@ tests/unit/deadline_timer_service.exe \ tests/unit/deadline_timer.exe \ tests/unit/error.exe \ + tests/unit/generic/basic_endpoint.exe \ + tests/unit/generic/datagram_protocol.exe \ + tests/unit/generic/raw_protocol.exe \ + tests/unit/generic/seq_packet_protocol.exe \ + tests/unit/generic/stream_protocol.exe \ tests/unit/high_resolution_timer.exe \ tests/unit/io_service.exe \ tests/unit/ip/address.exe \
diff --git a/asio/src/Makefile.msc b/asio/src/Makefile.msc index 04cb776..ca491a1 100644 --- a/asio/src/Makefile.msc +++ b/asio/src/Makefile.msc
@@ -106,6 +106,11 @@ tests\unit\deadline_timer_service.exe \ tests\unit\deadline_timer.exe \ tests\unit\error.exe \ + tests\unit\generic\basic_endpoint.exe \ + tests\unit\generic\datagram_protocol.exe \ + tests\unit\generic\raw_protocol.exe \ + tests\unit\generic\seq_packet_protocol.exe \ + tests\unit\generic\stream_protocol.exe \ tests\unit\high_resolution_timer.exe \ tests\unit\io_service.exe \ tests\unit\ip\address.exe \ @@ -261,6 +266,9 @@ {tests\unit}.cpp{tests\unit}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref +{tests\unit\generic}.cpp{tests\unit\generic}.exe: + cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref + {tests\unit\ip}.cpp{tests\unit\ip}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref
diff --git a/asio/src/doc/reference.xsl b/asio/src/doc/reference.xsl index 640e35f..24c6f03 100644 --- a/asio/src/doc/reference.xsl +++ b/asio/src/doc/reference.xsl
@@ -1443,6 +1443,9 @@ <xsl:when test="declname = 'Context_Service'"> <xsl:value-of select="declname"/> </xsl:when> + <xsl:when test="declname = 'DatagramSocketService1'"> + <xsl:value-of select="concat('``[link asio.reference.DatagramSocketService ', declname, ']``')"/> + </xsl:when> <xsl:when test="declname = 'Elem'"> <xsl:value-of select="declname"/> </xsl:when> @@ -1470,12 +1473,24 @@ <xsl:when test="declname = 'PointerToPodType'"> <xsl:value-of select="declname"/> </xsl:when> + <xsl:when test="declname = 'Protocol1'"> + <xsl:value-of select="concat('``[link asio.reference.Protocol ', declname, ']``')"/> + </xsl:when> + <xsl:when test="declname = 'RawSocketService1'"> + <xsl:value-of select="concat('``[link asio.reference.RawSocketService ', declname, ']``')"/> + </xsl:when> + <xsl:when test="declname = 'SeqPacketSocketService1'"> + <xsl:value-of select="concat('``[link asio.reference.SeqPacketSocketService ', declname, ']``')"/> + </xsl:when> <xsl:when test="declname = 'SocketService1' or declname = 'SocketService2'"> <xsl:value-of select="concat('``[link asio.reference.SocketService ', declname, ']``')"/> </xsl:when> <xsl:when test="declname = 'Stream'"> <xsl:value-of select="declname"/> </xsl:when> + <xsl:when test="declname = 'StreamSocketService1'"> + <xsl:value-of select="concat('``[link asio.reference.StreamSocketService ', declname, ']``')"/> + </xsl:when> <xsl:when test="declname = 'T'"> <xsl:value-of select="declname"/> </xsl:when>
diff --git a/asio/src/tests/Makefile.am b/asio/src/tests/Makefile.am index 0aeedef..f3d601e 100644 --- a/asio/src/tests/Makefile.am +++ b/asio/src/tests/Makefile.am
@@ -32,6 +32,11 @@ unit/deadline_timer_service \ unit/deadline_timer \ unit/error \ + unit/generic/basic_endpoint \ + unit/generic/datagram_protocol \ + unit/generic/raw_protocol \ + unit/generic/seq_packet_protocol \ + unit/generic/stream_protocol \ unit/high_resolution_timer \ unit/io_service \ unit/ip/address \ @@ -260,6 +265,11 @@ unit_deadline_timer_service_SOURCES = unit/deadline_timer_service.cpp unit/unit_test.cpp unit_deadline_timer_SOURCES = unit/deadline_timer.cpp unit/unit_test.cpp unit_error_SOURCES = unit/error.cpp unit/unit_test.cpp +unit_generic_basic_endpoint_SOURCES = unit/generic/basic_endpoint.cpp unit/unit_test.cpp +unit_generic_datagram_protocol_SOURCES = unit/generic/datagram_protocol.cpp unit/unit_test.cpp +unit_generic_raw_protocol_SOURCES = unit/generic/raw_protocol.cpp unit/unit_test.cpp +unit_generic_seq_packet_protocol_SOURCES = unit/generic/seq_packet_protocol.cpp unit/unit_test.cpp +unit_generic_stream_protocol_SOURCES = unit/generic/stream_protocol.cpp unit/unit_test.cpp unit_high_resolution_timer_SOURCES = unit/high_resolution_timer.cpp unit/unit_test.cpp unit_io_service_SOURCES = unit/io_service.cpp unit/unit_test.cpp unit_ip_address_SOURCES = unit/ip/address.cpp unit/unit_test.cpp
diff --git a/asio/src/tests/unit/generic/.gitignore b/asio/src/tests/unit/generic/.gitignore new file mode 100644 index 0000000..c057144 --- /dev/null +++ b/asio/src/tests/unit/generic/.gitignore
@@ -0,0 +1,14 @@ +.deps +.dirstamp +*.o +*.obj +*.exe +*.ilk +*.manifest +*.pdb +*.tds +basic_endpoint +datagram_protocol +raw_protocol +seq_packet_protocol +stream_protocol
diff --git a/asio/src/tests/unit/generic/basic_endpoint.cpp b/asio/src/tests/unit/generic/basic_endpoint.cpp new file mode 100644 index 0000000..6e42fd2 --- /dev/null +++ b/asio/src/tests/unit/generic/basic_endpoint.cpp
@@ -0,0 +1,25 @@ +// +// generic/basic_endpoint.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Disable autolinking for unit tests. +#if !defined(BOOST_ALL_NO_LIB) +#define BOOST_ALL_NO_LIB 1 +#endif // !defined(BOOST_ALL_NO_LIB) + +// Test that header file is self-contained. +#include "asio/generic/basic_endpoint.hpp" + +#include "../unit_test.hpp" + +ASIO_TEST_SUITE +( + "generic/basic_endpoint", + ASIO_TEST_CASE(null_test) +)
diff --git a/asio/src/tests/unit/generic/datagram_protocol.cpp b/asio/src/tests/unit/generic/datagram_protocol.cpp new file mode 100644 index 0000000..6bd35af --- /dev/null +++ b/asio/src/tests/unit/generic/datagram_protocol.cpp
@@ -0,0 +1,243 @@ +// +// generic/datagram_protocol.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Disable autolinking for unit tests. +#if !defined(BOOST_ALL_NO_LIB) +#define BOOST_ALL_NO_LIB 1 +#endif // !defined(BOOST_ALL_NO_LIB) + +// Test that header file is self-contained. +#include "asio/generic/datagram_protocol.hpp" + +#include <cstring> +#include "asio/io_service.hpp" +#include "asio/ip/udp.hpp" +#include "../unit_test.hpp" + +//------------------------------------------------------------------------------ + +// generic_datagram_protocol_socket_compile test +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// The following test checks that all public member functions on the class +// generic::datagram_socket::socket compile and link correctly. Runtime +// failures are ignored. + +namespace generic_datagram_protocol_socket_compile { + +void connect_handler(const asio::error_code&) +{ +} + +void send_handler(const asio::error_code&, std::size_t) +{ +} + +void receive_handler(const asio::error_code&, std::size_t) +{ +} + +void test() +{ + using namespace asio; + namespace generic = asio::generic; + typedef generic::datagram_protocol dp; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + socket_base::message_flags in_flags = 0; + socket_base::send_buffer_size socket_option; + socket_base::bytes_readable io_control_command; + asio::error_code ec; + + // basic_datagram_socket constructors. + + dp::socket socket1(ios); + dp::socket socket2(ios, dp(AF_INET, IPPROTO_UDP)); + dp::socket socket3(ios, dp::endpoint()); + int native_socket1 = ::socket(AF_INET, SOCK_DGRAM, 0); + dp::socket socket4(ios, dp(AF_INET, IPPROTO_UDP), native_socket1); + +#if defined(ASIO_HAS_MOVE) + dp::socket socket5(std::move(socket4)); + dp::socket socket6(asio::ip::udp::socket(ios)); +#endif // defined(ASIO_HAS_MOVE) + + // basic_datagram_socket operators. + +#if defined(ASIO_HAS_MOVE) + socket1 = dp::socket(ios); + socket1 = std::move(socket2); + socket1 = asio::ip::udp::socket(ios); +#endif // defined(ASIO_HAS_MOVE) + + // basic_io_object functions. + + io_service& ios_ref = socket1.get_io_service(); + (void)ios_ref; + + // basic_socket functions. + + dp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); + (void)lowest_layer; + + socket1.open(dp(AF_INET, IPPROTO_UDP)); + socket1.open(dp(AF_INET, IPPROTO_UDP), ec); + + int native_socket2 = ::socket(AF_INET, SOCK_DGRAM, 0); + socket1.assign(dp(AF_INET, IPPROTO_UDP), native_socket2); + int native_socket3 = ::socket(AF_INET, SOCK_DGRAM, 0); + socket1.assign(dp(AF_INET, IPPROTO_UDP), native_socket3, ec); + + bool is_open = socket1.is_open(); + (void)is_open; + + socket1.close(); + socket1.close(ec); + + dp::socket::native_type native_socket4 = socket1.native(); + (void)native_socket4; + + socket1.cancel(); + socket1.cancel(ec); + + bool at_mark1 = socket1.at_mark(); + (void)at_mark1; + bool at_mark2 = socket1.at_mark(ec); + (void)at_mark2; + + std::size_t available1 = socket1.available(); + (void)available1; + std::size_t available2 = socket1.available(ec); + (void)available2; + + socket1.bind(dp::endpoint()); + socket1.bind(dp::endpoint(), ec); + + socket1.connect(dp::endpoint()); + socket1.connect(dp::endpoint(), ec); + + socket1.async_connect(dp::endpoint(), connect_handler); + + socket1.set_option(socket_option); + socket1.set_option(socket_option, ec); + + socket1.get_option(socket_option); + socket1.get_option(socket_option, ec); + + socket1.io_control(io_control_command); + socket1.io_control(io_control_command, ec); + + dp::endpoint endpoint1 = socket1.local_endpoint(); + dp::endpoint endpoint2 = socket1.local_endpoint(ec); + + dp::endpoint endpoint3 = socket1.remote_endpoint(); + dp::endpoint endpoint4 = socket1.remote_endpoint(ec); + + socket1.shutdown(socket_base::shutdown_both); + socket1.shutdown(socket_base::shutdown_both, ec); + + // basic_datagram_socket functions. + + socket1.send(buffer(mutable_char_buffer)); + socket1.send(buffer(const_char_buffer)); + socket1.send(null_buffers()); + socket1.send(buffer(mutable_char_buffer), in_flags); + socket1.send(buffer(const_char_buffer), in_flags); + socket1.send(null_buffers(), in_flags); + socket1.send(buffer(mutable_char_buffer), in_flags, ec); + socket1.send(buffer(const_char_buffer), in_flags, ec); + socket1.send(null_buffers(), in_flags, ec); + + socket1.async_send(buffer(mutable_char_buffer), send_handler); + socket1.async_send(buffer(const_char_buffer), send_handler); + socket1.async_send(null_buffers(), send_handler); + socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler); + socket1.async_send(buffer(const_char_buffer), in_flags, send_handler); + socket1.async_send(null_buffers(), in_flags, send_handler); + + socket1.send_to(buffer(mutable_char_buffer), + dp::endpoint()); + socket1.send_to(buffer(const_char_buffer), + dp::endpoint()); + socket1.send_to(null_buffers(), + dp::endpoint()); + socket1.send_to(buffer(mutable_char_buffer), + dp::endpoint(), in_flags); + socket1.send_to(buffer(const_char_buffer), + dp::endpoint(), in_flags); + socket1.send_to(null_buffers(), + dp::endpoint(), in_flags); + socket1.send_to(buffer(mutable_char_buffer), + dp::endpoint(), in_flags, ec); + socket1.send_to(buffer(const_char_buffer), + dp::endpoint(), in_flags, ec); + socket1.send_to(null_buffers(), + dp::endpoint(), in_flags, ec); + + socket1.async_send_to(buffer(mutable_char_buffer), + dp::endpoint(), send_handler); + socket1.async_send_to(buffer(const_char_buffer), + dp::endpoint(), send_handler); + socket1.async_send_to(null_buffers(), + dp::endpoint(), send_handler); + socket1.async_send_to(buffer(mutable_char_buffer), + dp::endpoint(), in_flags, send_handler); + socket1.async_send_to(buffer(const_char_buffer), + dp::endpoint(), in_flags, send_handler); + socket1.async_send_to(null_buffers(), + dp::endpoint(), in_flags, send_handler); + + socket1.receive(buffer(mutable_char_buffer)); + socket1.receive(null_buffers()); + socket1.receive(buffer(mutable_char_buffer), in_flags); + socket1.receive(null_buffers(), in_flags); + socket1.receive(buffer(mutable_char_buffer), in_flags, ec); + socket1.receive(null_buffers(), in_flags, ec); + + socket1.async_receive(buffer(mutable_char_buffer), receive_handler); + socket1.async_receive(null_buffers(), receive_handler); + socket1.async_receive(buffer(mutable_char_buffer), in_flags, + receive_handler); + socket1.async_receive(null_buffers(), in_flags, receive_handler); + + dp::endpoint endpoint; + socket1.receive_from(buffer(mutable_char_buffer), endpoint); + socket1.receive_from(null_buffers(), endpoint); + socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags); + socket1.receive_from(null_buffers(), endpoint, in_flags); + socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec); + socket1.receive_from(null_buffers(), endpoint, in_flags, ec); + + socket1.async_receive_from(buffer(mutable_char_buffer), + endpoint, receive_handler); + socket1.async_receive_from(null_buffers(), + endpoint, receive_handler); + socket1.async_receive_from(buffer(mutable_char_buffer), + endpoint, in_flags, receive_handler); + socket1.async_receive_from(null_buffers(), + endpoint, in_flags, receive_handler); + } + catch (std::exception&) + { + } +} + +} // namespace generic_datagram_protocol_socket_compile + +//------------------------------------------------------------------------------ + +ASIO_TEST_SUITE +( + "generic/datagram_protocol", + ASIO_TEST_CASE(generic_datagram_protocol_socket_compile::test) +)
diff --git a/asio/src/tests/unit/generic/raw_protocol.cpp b/asio/src/tests/unit/generic/raw_protocol.cpp new file mode 100644 index 0000000..f53335b --- /dev/null +++ b/asio/src/tests/unit/generic/raw_protocol.cpp
@@ -0,0 +1,243 @@ +// +// generic/raw_protocol.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Disable autolinking for unit tests. +#if !defined(BOOST_ALL_NO_LIB) +#define BOOST_ALL_NO_LIB 1 +#endif // !defined(BOOST_ALL_NO_LIB) + +// Test that header file is self-contained. +#include "asio/generic/raw_protocol.hpp" + +#include <cstring> +#include "asio/io_service.hpp" +#include "asio/ip/icmp.hpp" +#include "../unit_test.hpp" + +//------------------------------------------------------------------------------ + +// generic_raw_protocol_socket_compile test +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// The following test checks that all public member functions on the class +// generic::raw_socket::socket compile and link correctly. Runtime failures +// are ignored. + +namespace generic_raw_protocol_socket_compile { + +void connect_handler(const asio::error_code&) +{ +} + +void send_handler(const asio::error_code&, std::size_t) +{ +} + +void receive_handler(const asio::error_code&, std::size_t) +{ +} + +void test() +{ + using namespace asio; + namespace generic = asio::generic; + typedef generic::raw_protocol rp; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + socket_base::message_flags in_flags = 0; + socket_base::send_buffer_size socket_option; + socket_base::bytes_readable io_control_command; + asio::error_code ec; + + // basic_raw_socket constructors. + + rp::socket socket1(ios); + rp::socket socket2(ios, rp(AF_INET, IPPROTO_ICMP)); + rp::socket socket3(ios, rp::endpoint()); + int native_socket1 = ::socket(AF_INET, SOCK_DGRAM, 0); + rp::socket socket4(ios, rp(AF_INET, IPPROTO_ICMP), native_socket1); + +#if defined(ASIO_HAS_MOVE) + rp::socket socket5(std::move(socket4)); + rp::socket socket6(asio::ip::icmp::socket(ios)); +#endif // defined(ASIO_HAS_MOVE) + + // basic_datagram_socket operators. + +#if defined(ASIO_HAS_MOVE) + socket1 = rp::socket(ios); + socket1 = std::move(socket2); + socket1 = asio::ip::icmp::socket(ios); +#endif // defined(ASIO_HAS_MOVE) + + // basic_io_object functions. + + io_service& ios_ref = socket1.get_io_service(); + (void)ios_ref; + + // basic_socket functions. + + rp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); + (void)lowest_layer; + + socket1.open(rp(AF_INET, IPPROTO_ICMP)); + socket1.open(rp(AF_INET, IPPROTO_ICMP), ec); + + int native_socket2 = ::socket(AF_INET, SOCK_DGRAM, 0); + socket1.assign(rp(AF_INET, IPPROTO_ICMP), native_socket2); + int native_socket3 = ::socket(AF_INET, SOCK_DGRAM, 0); + socket1.assign(rp(AF_INET, IPPROTO_ICMP), native_socket3, ec); + + bool is_open = socket1.is_open(); + (void)is_open; + + socket1.close(); + socket1.close(ec); + + rp::socket::native_type native_socket4 = socket1.native(); + (void)native_socket4; + + socket1.cancel(); + socket1.cancel(ec); + + bool at_mark1 = socket1.at_mark(); + (void)at_mark1; + bool at_mark2 = socket1.at_mark(ec); + (void)at_mark2; + + std::size_t available1 = socket1.available(); + (void)available1; + std::size_t available2 = socket1.available(ec); + (void)available2; + + socket1.bind(rp::endpoint()); + socket1.bind(rp::endpoint(), ec); + + socket1.connect(rp::endpoint()); + socket1.connect(rp::endpoint(), ec); + + socket1.async_connect(rp::endpoint(), connect_handler); + + socket1.set_option(socket_option); + socket1.set_option(socket_option, ec); + + socket1.get_option(socket_option); + socket1.get_option(socket_option, ec); + + socket1.io_control(io_control_command); + socket1.io_control(io_control_command, ec); + + rp::endpoint endpoint1 = socket1.local_endpoint(); + rp::endpoint endpoint2 = socket1.local_endpoint(ec); + + rp::endpoint endpoint3 = socket1.remote_endpoint(); + rp::endpoint endpoint4 = socket1.remote_endpoint(ec); + + socket1.shutdown(socket_base::shutdown_both); + socket1.shutdown(socket_base::shutdown_both, ec); + + // basic_raw_socket functions. + + socket1.send(buffer(mutable_char_buffer)); + socket1.send(buffer(const_char_buffer)); + socket1.send(null_buffers()); + socket1.send(buffer(mutable_char_buffer), in_flags); + socket1.send(buffer(const_char_buffer), in_flags); + socket1.send(null_buffers(), in_flags); + socket1.send(buffer(mutable_char_buffer), in_flags, ec); + socket1.send(buffer(const_char_buffer), in_flags, ec); + socket1.send(null_buffers(), in_flags, ec); + + socket1.async_send(buffer(mutable_char_buffer), send_handler); + socket1.async_send(buffer(const_char_buffer), send_handler); + socket1.async_send(null_buffers(), send_handler); + socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler); + socket1.async_send(buffer(const_char_buffer), in_flags, send_handler); + socket1.async_send(null_buffers(), in_flags, send_handler); + + socket1.send_to(buffer(mutable_char_buffer), + rp::endpoint()); + socket1.send_to(buffer(const_char_buffer), + rp::endpoint()); + socket1.send_to(null_buffers(), + rp::endpoint()); + socket1.send_to(buffer(mutable_char_buffer), + rp::endpoint(), in_flags); + socket1.send_to(buffer(const_char_buffer), + rp::endpoint(), in_flags); + socket1.send_to(null_buffers(), + rp::endpoint(), in_flags); + socket1.send_to(buffer(mutable_char_buffer), + rp::endpoint(), in_flags, ec); + socket1.send_to(buffer(const_char_buffer), + rp::endpoint(), in_flags, ec); + socket1.send_to(null_buffers(), + rp::endpoint(), in_flags, ec); + + socket1.async_send_to(buffer(mutable_char_buffer), + rp::endpoint(), send_handler); + socket1.async_send_to(buffer(const_char_buffer), + rp::endpoint(), send_handler); + socket1.async_send_to(null_buffers(), + rp::endpoint(), send_handler); + socket1.async_send_to(buffer(mutable_char_buffer), + rp::endpoint(), in_flags, send_handler); + socket1.async_send_to(buffer(const_char_buffer), + rp::endpoint(), in_flags, send_handler); + socket1.async_send_to(null_buffers(), + rp::endpoint(), in_flags, send_handler); + + socket1.receive(buffer(mutable_char_buffer)); + socket1.receive(null_buffers()); + socket1.receive(buffer(mutable_char_buffer), in_flags); + socket1.receive(null_buffers(), in_flags); + socket1.receive(buffer(mutable_char_buffer), in_flags, ec); + socket1.receive(null_buffers(), in_flags, ec); + + socket1.async_receive(buffer(mutable_char_buffer), receive_handler); + socket1.async_receive(null_buffers(), receive_handler); + socket1.async_receive(buffer(mutable_char_buffer), in_flags, + receive_handler); + socket1.async_receive(null_buffers(), in_flags, receive_handler); + + rp::endpoint endpoint; + socket1.receive_from(buffer(mutable_char_buffer), endpoint); + socket1.receive_from(null_buffers(), endpoint); + socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags); + socket1.receive_from(null_buffers(), endpoint, in_flags); + socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec); + socket1.receive_from(null_buffers(), endpoint, in_flags, ec); + + socket1.async_receive_from(buffer(mutable_char_buffer), + endpoint, receive_handler); + socket1.async_receive_from(null_buffers(), + endpoint, receive_handler); + socket1.async_receive_from(buffer(mutable_char_buffer), + endpoint, in_flags, receive_handler); + socket1.async_receive_from(null_buffers(), + endpoint, in_flags, receive_handler); + } + catch (std::exception&) + { + } +} + +} // namespace generic_raw_protocol_socket_compile + +//------------------------------------------------------------------------------ + +ASIO_TEST_SUITE +( + "generic/raw_protocol", + ASIO_TEST_CASE(generic_raw_protocol_socket_compile::test) +)
diff --git a/asio/src/tests/unit/generic/seq_packet_protocol.cpp b/asio/src/tests/unit/generic/seq_packet_protocol.cpp new file mode 100644 index 0000000..705dbdf --- /dev/null +++ b/asio/src/tests/unit/generic/seq_packet_protocol.cpp
@@ -0,0 +1,187 @@ +// +// generic/seq_packet_protocol.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Disable autolinking for unit tests. +#if !defined(BOOST_ALL_NO_LIB) +#define BOOST_ALL_NO_LIB 1 +#endif // !defined(BOOST_ALL_NO_LIB) + +// Test that header file is self-contained. +#include "asio/generic/seq_packet_protocol.hpp" + +#include <cstring> +#include "asio/io_service.hpp" +#include "../unit_test.hpp" + +//------------------------------------------------------------------------------ + +// generic_seq_packet_protocol_socket_compile test +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// The following test checks that all public member functions on the class +// generic::seq_packet_socket::socket compile and link correctly. Runtime +// failures are ignored. + +namespace generic_seq_packet_protocol_socket_compile { + +void connect_handler(const asio::error_code&) +{ +} + +void send_handler(const asio::error_code&, std::size_t) +{ +} + +void receive_handler(const asio::error_code&, std::size_t) +{ +} + +void test() +{ + using namespace asio; + namespace generic = asio::generic; + typedef generic::seq_packet_protocol spp; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + const socket_base::message_flags in_flags = 0; + socket_base::message_flags out_flags = 0; + socket_base::send_buffer_size socket_option; + socket_base::bytes_readable io_control_command; + asio::error_code ec; + + // basic_seq_packet_socket constructors. + + spp::socket socket1(ios); + spp::socket socket2(ios, spp(AF_INET, 0)); + spp::socket socket3(ios, spp::endpoint()); + int native_socket1 = ::socket(AF_INET, SOCK_SEQPACKET, 0); + spp::socket socket4(ios, spp(AF_INET, 0), native_socket1); + +#if defined(ASIO_HAS_MOVE) + spp::socket socket5(std::move(socket4)); +#endif // defined(ASIO_HAS_MOVE) + + // basic_seq_packet_socket operators. + +#if defined(ASIO_HAS_MOVE) + socket1 = spp::socket(ios); + socket1 = std::move(socket2); +#endif // defined(ASIO_HAS_MOVE) + + // basic_io_object functions. + + io_service& ios_ref = socket1.get_io_service(); + (void)ios_ref; + + // basic_socket functions. + + spp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); + (void)lowest_layer; + + socket1.open(spp(AF_INET, 0)); + socket1.open(spp(AF_INET, 0), ec); + + int native_socket2 = ::socket(AF_INET, SOCK_SEQPACKET, 0); + socket1.assign(spp(AF_INET, 0), native_socket2); + int native_socket3 = ::socket(AF_INET, SOCK_SEQPACKET, 0); + socket1.assign(spp(AF_INET, 0), native_socket3, ec); + + bool is_open = socket1.is_open(); + (void)is_open; + + socket1.close(); + socket1.close(ec); + + spp::socket::native_type native_socket4 = socket1.native(); + (void)native_socket4; + + socket1.cancel(); + socket1.cancel(ec); + + bool at_mark1 = socket1.at_mark(); + (void)at_mark1; + bool at_mark2 = socket1.at_mark(ec); + (void)at_mark2; + + std::size_t available1 = socket1.available(); + (void)available1; + std::size_t available2 = socket1.available(ec); + (void)available2; + + socket1.bind(spp::endpoint()); + socket1.bind(spp::endpoint(), ec); + + socket1.connect(spp::endpoint()); + socket1.connect(spp::endpoint(), ec); + + socket1.async_connect(spp::endpoint(), connect_handler); + + socket1.set_option(socket_option); + socket1.set_option(socket_option, ec); + + socket1.get_option(socket_option); + socket1.get_option(socket_option, ec); + + socket1.io_control(io_control_command); + socket1.io_control(io_control_command, ec); + + spp::endpoint endpoint1 = socket1.local_endpoint(); + spp::endpoint endpoint2 = socket1.local_endpoint(ec); + + spp::endpoint endpoint3 = socket1.remote_endpoint(); + spp::endpoint endpoint4 = socket1.remote_endpoint(ec); + + socket1.shutdown(socket_base::shutdown_both); + socket1.shutdown(socket_base::shutdown_both, ec); + + // basic_seq_packet_socket functions. + + socket1.send(buffer(mutable_char_buffer), in_flags); + socket1.send(buffer(const_char_buffer), in_flags); + socket1.send(null_buffers(), in_flags); + socket1.send(buffer(mutable_char_buffer), in_flags, ec); + socket1.send(buffer(const_char_buffer), in_flags, ec); + socket1.send(null_buffers(), in_flags, ec); + + socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler); + socket1.async_send(buffer(const_char_buffer), in_flags, send_handler); + socket1.async_send(null_buffers(), in_flags, send_handler); + + socket1.receive(buffer(mutable_char_buffer), out_flags); + socket1.receive(null_buffers(), out_flags); + socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags); + socket1.receive(null_buffers(), in_flags, out_flags); + socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags, ec); + socket1.receive(null_buffers(), in_flags, out_flags, ec); + + socket1.async_receive(buffer(mutable_char_buffer), out_flags, + receive_handler); + socket1.async_receive(null_buffers(), out_flags, receive_handler); + socket1.async_receive(buffer(mutable_char_buffer), in_flags, + out_flags, receive_handler); + socket1.async_receive(null_buffers(), in_flags, out_flags, receive_handler); + } + catch (std::exception&) + { + } +} + +} // namespace generic_seq_packet_protocol_socket_compile + +//------------------------------------------------------------------------------ + +ASIO_TEST_SUITE +( + "generic/seq_packet_protocol", + ASIO_TEST_CASE(generic_seq_packet_protocol_socket_compile::test) +)
diff --git a/asio/src/tests/unit/generic/stream_protocol.cpp b/asio/src/tests/unit/generic/stream_protocol.cpp new file mode 100644 index 0000000..d40e3cc --- /dev/null +++ b/asio/src/tests/unit/generic/stream_protocol.cpp
@@ -0,0 +1,220 @@ +// +// generic/stream_protocol.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +// Disable autolinking for unit tests. +#if !defined(BOOST_ALL_NO_LIB) +#define BOOST_ALL_NO_LIB 1 +#endif // !defined(BOOST_ALL_NO_LIB) + +// Test that header file is self-contained. +#include "asio/generic/stream_protocol.hpp" + +#include <cstring> +#include "asio/io_service.hpp" +#include "asio/ip/tcp.hpp" +#include "../unit_test.hpp" + +//------------------------------------------------------------------------------ + +// generic_stream_protocol_socket_compile test +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// The following test checks that all public member functions on the class +// generic::stream_protocol::socket compile and link correctly. Runtime +// failures are ignored. + +namespace generic_stream_protocol_socket_compile { + +void connect_handler(const asio::error_code&) +{ +} + +void send_handler(const asio::error_code&, std::size_t) +{ +} + +void receive_handler(const asio::error_code&, std::size_t) +{ +} + +void write_some_handler(const asio::error_code&, std::size_t) +{ +} + +void read_some_handler(const asio::error_code&, std::size_t) +{ +} + +void test() +{ + using namespace asio; + namespace generic = asio::generic; + typedef generic::stream_protocol sp; + + try + { + io_service ios; + char mutable_char_buffer[128] = ""; + const char const_char_buffer[128] = ""; + socket_base::message_flags in_flags = 0; + socket_base::keep_alive socket_option; + socket_base::bytes_readable io_control_command; + asio::error_code ec; + + // basic_stream_socket constructors. + + sp::socket socket1(ios); + sp::socket socket2(ios, sp(AF_INET, IPPROTO_TCP)); + sp::socket socket3(ios, sp::endpoint()); + int native_socket1 = ::socket(AF_INET, SOCK_STREAM, 0); + sp::socket socket4(ios, sp(AF_INET, IPPROTO_TCP), native_socket1); + +#if defined(ASIO_HAS_MOVE) + sp::socket socket5(std::move(socket4)); + sp::socket socket6(asio::ip::tcp::socket(ios)); +#endif // defined(ASIO_HAS_MOVE) + + // basic_stream_socket operators. + +#if defined(ASIO_HAS_MOVE) + socket1 = sp::socket(ios); + socket1 = std::move(socket2); + socket1 = asio::ip::tcp::socket(ios); +#endif // defined(ASIO_HAS_MOVE) + + // basic_io_object functions. + + io_service& ios_ref = socket1.get_io_service(); + (void)ios_ref; + + // basic_socket functions. + + sp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); + (void)lowest_layer; + + socket1.open(sp(AF_INET, IPPROTO_TCP)); + socket1.open(sp(AF_INET, IPPROTO_TCP), ec); + + int native_socket2 = ::socket(AF_INET, SOCK_STREAM, 0); + socket1.assign(sp(AF_INET, IPPROTO_TCP), native_socket2); + int native_socket3 = ::socket(AF_INET, SOCK_STREAM, 0); + socket1.assign(sp(AF_INET, IPPROTO_TCP), native_socket3, ec); + + bool is_open = socket1.is_open(); + (void)is_open; + + socket1.close(); + socket1.close(ec); + + sp::socket::native_type native_socket4 = socket1.native(); + (void)native_socket4; + + socket1.cancel(); + socket1.cancel(ec); + + bool at_mark1 = socket1.at_mark(); + (void)at_mark1; + bool at_mark2 = socket1.at_mark(ec); + (void)at_mark2; + + std::size_t available1 = socket1.available(); + (void)available1; + std::size_t available2 = socket1.available(ec); + (void)available2; + + socket1.bind(sp::endpoint()); + socket1.bind(sp::endpoint(), ec); + + socket1.connect(sp::endpoint()); + socket1.connect(sp::endpoint(), ec); + + socket1.async_connect(sp::endpoint(), connect_handler); + + socket1.set_option(socket_option); + socket1.set_option(socket_option, ec); + + socket1.get_option(socket_option); + socket1.get_option(socket_option, ec); + + socket1.io_control(io_control_command); + socket1.io_control(io_control_command, ec); + + sp::endpoint endpoint1 = socket1.local_endpoint(); + sp::endpoint endpoint2 = socket1.local_endpoint(ec); + + sp::endpoint endpoint3 = socket1.remote_endpoint(); + sp::endpoint endpoint4 = socket1.remote_endpoint(ec); + + socket1.shutdown(socket_base::shutdown_both); + socket1.shutdown(socket_base::shutdown_both, ec); + + // basic_stream_socket functions. + + socket1.send(buffer(mutable_char_buffer)); + socket1.send(buffer(const_char_buffer)); + socket1.send(null_buffers()); + socket1.send(buffer(mutable_char_buffer), in_flags); + socket1.send(buffer(const_char_buffer), in_flags); + socket1.send(null_buffers(), in_flags); + socket1.send(buffer(mutable_char_buffer), in_flags, ec); + socket1.send(buffer(const_char_buffer), in_flags, ec); + socket1.send(null_buffers(), in_flags, ec); + + socket1.async_send(buffer(mutable_char_buffer), send_handler); + socket1.async_send(buffer(const_char_buffer), send_handler); + socket1.async_send(null_buffers(), send_handler); + socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler); + socket1.async_send(buffer(const_char_buffer), in_flags, send_handler); + socket1.async_send(null_buffers(), in_flags, send_handler); + + socket1.receive(buffer(mutable_char_buffer)); + socket1.receive(null_buffers()); + socket1.receive(buffer(mutable_char_buffer), in_flags); + socket1.receive(null_buffers(), in_flags); + socket1.receive(buffer(mutable_char_buffer), in_flags, ec); + socket1.receive(null_buffers(), in_flags, ec); + + socket1.async_receive(buffer(mutable_char_buffer), receive_handler); + socket1.async_receive(null_buffers(), receive_handler); + socket1.async_receive(buffer(mutable_char_buffer), in_flags, + receive_handler); + socket1.async_receive(null_buffers(), in_flags, receive_handler); + + socket1.write_some(buffer(mutable_char_buffer)); + socket1.write_some(buffer(const_char_buffer)); + socket1.write_some(null_buffers()); + socket1.write_some(buffer(mutable_char_buffer), ec); + socket1.write_some(buffer(const_char_buffer), ec); + socket1.write_some(null_buffers(), ec); + + socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler); + socket1.async_write_some(buffer(const_char_buffer), write_some_handler); + socket1.async_write_some(null_buffers(), write_some_handler); + + socket1.read_some(buffer(mutable_char_buffer)); + socket1.read_some(buffer(mutable_char_buffer), ec); + socket1.read_some(null_buffers(), ec); + + socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler); + socket1.async_read_some(null_buffers(), read_some_handler); + } + catch (std::exception&) + { + } +} + +} // namespace generic_stream_protocol_socket_compile + +//------------------------------------------------------------------------------ + +ASIO_TEST_SUITE +( + "generic/stream_protocol", + ASIO_TEST_CASE(generic_stream_protocol_socket_compile::test) +)