mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 03:26:01 +00:00
Refactor SocketWrapper
This commit is contained in:
@@ -21,22 +21,43 @@ Socket::~Socket ()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// General
|
||||
// basic_io_object
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool Socket::requires_handshake ()
|
||||
boost::asio::io_service& Socket::get_io_service ()
|
||||
{
|
||||
return false;
|
||||
pure_virtual ();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Close
|
||||
// basic_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void* Socket::lowest_layer (char const*) const
|
||||
{
|
||||
pure_virtual ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* Socket::native_handle (char const*) const
|
||||
{
|
||||
pure_virtual ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::cancel (boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::shutdown (shutdown_type, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::close (boost::system::error_code& ec)
|
||||
{
|
||||
@@ -45,9 +66,8 @@ boost::system::error_code Socket::close (boost::system::error_code& ec)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Acceptor
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code Socket::accept (Socket&, boost::system::error_code& ec)
|
||||
{
|
||||
@@ -76,37 +96,8 @@ Socket::async_accept (Socket&, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::LowestLayer
|
||||
// basic_stream_socket
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void* Socket::lowest_layer_raw (char const*) const
|
||||
{
|
||||
pure_virtual ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code Socket::cancel (boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::shutdown (shutdown_type, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t Socket::read_some (MutableBuffers const&, boost::system::error_code& ec)
|
||||
{
|
||||
@@ -160,9 +151,13 @@ Socket::async_write_some (ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall)
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Handshake
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool Socket::requires_handshake ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::handshake (handshake_type, boost::system::error_code& ec)
|
||||
{
|
||||
@@ -189,8 +184,6 @@ Socket::async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
|
||||
boost::system::error_code Socket::handshake (handshake_type,
|
||||
@@ -249,45 +242,6 @@ Socket::async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#if 0
|
||||
/* Stream, SyncReadStream, AsyncReadStream, WriteStream, AsyncWriteStream */
|
||||
// Note, missing std::future<> returns
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
// Stream
|
||||
typedef typename remove_reference<Stream>::type next_layer_type;
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
next_layer_type& next_layer()
|
||||
next_layer_type const& next_layer() const
|
||||
lowest_layer_type& lowest_layer()
|
||||
const lowest_layer_type& lowest_layer() const
|
||||
boost::asio::io_service& get_io_service()
|
||||
void close()
|
||||
boost::system::error_code close(boost::system::error_code& ec)
|
||||
|
||||
// SyncWriteStream
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (const ConstBufferSequence& buffers)
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (const ConstBufferSequence& buffers, boost::system::error_code& ec)
|
||||
|
||||
// AsyncWriteStream
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some (const ConstBufferSequence& buffers, WriteHandler handler)
|
||||
|
||||
// ReadStream
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (const MutableBufferSequence& buffers)
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (const MutableBufferSequence& buffers, boost::system::error_code& ec)
|
||||
|
||||
// AsyncReadStream
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some (const MutableBufferSequence& buffers, ReadHandler handler)
|
||||
};
|
||||
#endif
|
||||
/* members, and the most common base class in which they appear:
|
||||
|
||||
basic_io_object
|
||||
@@ -296,8 +250,10 @@ basic_io_object
|
||||
basic_socket <Protocol> : basic_io_object
|
||||
typedef protocol_type
|
||||
typedef lowest_layer_type
|
||||
|
||||
lowest_layer_type& lowest_layer ()
|
||||
native_handle () // Socket::native_handle() would return void* and we'd use the templates to do the static_cast
|
||||
lowest_layer_type const& lowest_layer () const
|
||||
native_handle ()
|
||||
cancel ()
|
||||
shutdon (shutdown_type)
|
||||
close ()
|
||||
@@ -314,4 +270,8 @@ basic_socket_acceptor <Protocol> : basic_io_object
|
||||
|
||||
basic_stream_socket <Protocol> : basic_socket <Protocol>
|
||||
|
||||
ssl::stream
|
||||
handshake ()
|
||||
async_handshake ()
|
||||
shutdown ()
|
||||
*/
|
||||
|
||||
@@ -28,17 +28,6 @@
|
||||
|
||||
When member functions are called and the underlying implementation does
|
||||
not support the operation, a fatal error is generated.
|
||||
|
||||
Must satisfy these requirements:
|
||||
|
||||
DefaultConstructible, MoveConstructible, CopyConstructible,
|
||||
MoveAssignable, CopyAssignable, Destructible
|
||||
|
||||
Meets the requirements of these boost concepts:
|
||||
|
||||
SyncReadStream, SyncWriteStream, AsyncReadStream, AsyncWriteStream,
|
||||
|
||||
@see SharedObjectPtr
|
||||
*/
|
||||
class Socket
|
||||
: public SocketBase
|
||||
@@ -50,126 +39,25 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// General
|
||||
// basic_io_object
|
||||
//
|
||||
|
||||
virtual boost::asio::io_service& get_io_service ();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
|
||||
virtual boost::asio::io_service& get_io_service () = 0;
|
||||
|
||||
/** Determines if the underlying stream requires a handshake.
|
||||
|
||||
If requires_handshake is true, it will be necessary to call handshake or
|
||||
async_handshake after the connection is established. Furthermore it
|
||||
will be necessary to call the shutdown member from the
|
||||
HandshakeInterface to close the connection. Do not close the underlying
|
||||
socket or else the closure will not be graceful. Only one side should
|
||||
initiate the handshaking shutdon. The other side should observe it.
|
||||
Which side does what is up to the user.
|
||||
|
||||
The default version returns false
|
||||
/** Retrieve the lowest layer object.
|
||||
Note that you must know the type name for this to work, or
|
||||
else a fatal error will occur.
|
||||
*/
|
||||
virtual bool requires_handshake ();
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
Returns nullptr if the implementation doesn't match. Usually
|
||||
you will use this if you need to get at the underlying boost::asio
|
||||
object. For example:
|
||||
|
||||
@code
|
||||
|
||||
void set_options (Socket& socket)
|
||||
{
|
||||
typedef bost::boost::asio::ip::tcp Protocol;
|
||||
typedef Protocol::socket;
|
||||
Protocol::socket* const sock =
|
||||
socket.this_layer <Protocol::socket> ();
|
||||
|
||||
if (sock != nullptr)
|
||||
sock->set_option (
|
||||
Protocol::no_delay (true));
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
template <class Object>
|
||||
Object& this_layer ()
|
||||
{
|
||||
Object* object (this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& this_layer () const
|
||||
{
|
||||
Object const* object (this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* this_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this_layer_raw (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* this_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this_layer_raw (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
// Shouldn't call this directly, use this_layer<> instead
|
||||
virtual void* this_layer_raw (char const* type_name) const = 0;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Close
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void close ()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
throw_error (close (ec));
|
||||
}
|
||||
|
||||
virtual boost::system::error_code close (boost::system::error_code& ec);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
virtual boost::system::error_code accept (Socket& peer, boost::system::error_code& ec);
|
||||
|
||||
template <class AcceptHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (boost::system::error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
|
||||
{
|
||||
return async_accept (peer, ErrorCall (
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(ErrorCall) handler);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::LowestLayer
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& lowest_layer ()
|
||||
{
|
||||
Object* object (lowest_layer_ptr <Object> ());
|
||||
Object* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
@@ -178,7 +66,7 @@ public:
|
||||
template <class Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (lowest_layer_ptr <Object> ());
|
||||
Object const* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
@@ -188,24 +76,58 @@ public:
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
lowest_layer_raw (typeid (Object).name ()));
|
||||
this->lowest_layer (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
lowest_layer_raw (typeid (Object).name ()));
|
||||
this->lowest_layer (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* lowest_layer (char const* type_name) const;
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
Note that you must know the type name for this to work, or
|
||||
else a fatal error will occur.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
Object& native_handle ()
|
||||
{
|
||||
Object* object (this->native_handle_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
// Shouldn't call this directly, use lowest_layer<> instead
|
||||
virtual void* lowest_layer_raw (char const* type_name) const;
|
||||
template <class Object>
|
||||
Object const& native_handle () const
|
||||
{
|
||||
Object const* object (this->native_handle_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
template <class Object>
|
||||
Object* native_handle_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->native_handle (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* native_handle_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->native_handle (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* native_handle (char const* type_name) const;
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
@@ -224,16 +146,40 @@ public:
|
||||
virtual boost::system::error_code shutdown (shutdown_type what,
|
||||
boost::system::error_code& ec);
|
||||
|
||||
void close ()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
throw_error (close (ec));
|
||||
}
|
||||
|
||||
virtual boost::system::error_code close (boost::system::error_code& ec);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Stream
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
|
||||
virtual boost::system::error_code accept (Socket& peer, boost::system::error_code& ec);
|
||||
|
||||
template <class AcceptHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (boost::system::error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
|
||||
{
|
||||
return async_accept (peer, ErrorCall (
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(ErrorCall) handler);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
|
||||
// SyncReadStream
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncReadStream.html
|
||||
//
|
||||
template <class MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers,
|
||||
boost::system::error_code& ec)
|
||||
@@ -244,9 +190,7 @@ public:
|
||||
virtual std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec);
|
||||
|
||||
// SyncWriteStream
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncWriteStream.html
|
||||
//
|
||||
template <class ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, boost::system::error_code &ec)
|
||||
{
|
||||
@@ -256,9 +200,7 @@ public:
|
||||
virtual std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec);
|
||||
|
||||
// AsyncReadStream
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncReadStream.html
|
||||
//
|
||||
template <class MutableBufferSequence, class ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void (boost::system::error_code, std::size_t))
|
||||
async_read_some (MutableBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
@@ -272,9 +214,7 @@ public:
|
||||
async_read_some (MutableBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler);
|
||||
|
||||
// AsyncWriteStream
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncWriteStream.html
|
||||
//
|
||||
template <class ConstBufferSequence, class WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (boost::system::error_code, std::size_t))
|
||||
async_write_some (ConstBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
@@ -289,9 +229,22 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Handshake
|
||||
// ssl::stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Determines if the underlying stream requires a handshake.
|
||||
|
||||
If requires_handshake is true, it will be necessary to call handshake or
|
||||
async_handshake after the connection is established. Furthermore it
|
||||
will be necessary to call the shutdown member from the
|
||||
HandshakeInterface to close the connection. Do not close the underlying
|
||||
socket or else the closure will not be graceful. Only one side should
|
||||
initiate the handshaking shutdon. The other side should observe it.
|
||||
Which side does what is up to the user.
|
||||
|
||||
The default version returns false.
|
||||
*/
|
||||
virtual bool requires_handshake ();
|
||||
|
||||
// ssl::stream::handshake (1 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload1.html
|
||||
|
||||
@@ -23,13 +23,11 @@
|
||||
/** Implementation details for Socket.
|
||||
Normally you wont need to use this.
|
||||
*/
|
||||
class SocketBase
|
||||
struct SocketBase
|
||||
{
|
||||
protected:
|
||||
static void pure_virtual ();
|
||||
static boost::system::error_code pure_virtual (boost::system::error_code& ec);
|
||||
|
||||
protected:
|
||||
/** Called when the underlying object does not support the interface. */
|
||||
void throw_error (boost::system::error_code const& ec)
|
||||
{
|
||||
|
||||
@@ -28,144 +28,279 @@
|
||||
Note that only a reference to the underlying is stored. Management
|
||||
of the lifetime of the object is controlled by the caller.
|
||||
|
||||
Supports these concepts:
|
||||
Examples of the type of WrappedObject:
|
||||
|
||||
CopyConstructible, CopyAssignable, Destructible
|
||||
asio::ip::tcp::socket
|
||||
arg must be an io_context
|
||||
SocketWrapper will create and take ownership of the tcp::socket
|
||||
WrappedObjectType will be tcp::socket
|
||||
next_layer () returns a asio::ip::tcp::socket&
|
||||
lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ip::tcp::socket&
|
||||
arg must be an existing socket&
|
||||
The caller owns the underlying socket object
|
||||
WrappedObjectType will be tcp::socket
|
||||
next_layer () returns a asio::ip::tcp::socket&
|
||||
lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::ip::tcp::socket>
|
||||
arg must be an io_context
|
||||
SocketWrapper creates and takes ownership of the ssl::stream
|
||||
WrappedObjecType will be asio::ssl::stream <asio::ip::tcp::socket>
|
||||
next_layer () returns a asio::ip::tcp::socket&
|
||||
lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::ip::tcp::socket&>
|
||||
arg must be an existing socket&
|
||||
The caller owns the socket, but SocketWrapper owns the ssl::stream
|
||||
WrappedObjectType will be asio::ssl::stream <asio::ip::tcp::socket&>
|
||||
next_layer () returns a asio::ip::tcp::socket&
|
||||
lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::buffered_stream <asio::ip::tcp::socket> > >
|
||||
This makes my head explode
|
||||
*/
|
||||
template <class Object>
|
||||
class SocketWrapper
|
||||
: public virtual Socket
|
||||
, protected SocketWrapperBasics
|
||||
{
|
||||
public:
|
||||
typedef typename boost::remove_pointer <
|
||||
typename boost::remove_reference <
|
||||
typename boost::remove_cv <Object>::type >::type >::type
|
||||
ObjectType;
|
||||
|
||||
SocketWrapper (Object& object) noexcept
|
||||
: m_impl (&object)
|
||||
{
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
SocketWrapper (SocketWrapper const& other) noexcept
|
||||
: m_impl (other.m_impl)
|
||||
namespace SocketWrapperMemberChecks
|
||||
{
|
||||
}
|
||||
template <bool Enable>
|
||||
struct EnableIf : boost::false_type { };
|
||||
|
||||
SocketWrapper& operator= (SocketWrapper const& other) noexcept
|
||||
{
|
||||
m_impl = other.m_impl;
|
||||
}
|
||||
template <>
|
||||
struct EnableIf <true> : boost::true_type { };
|
||||
|
||||
// Retrieve the underlying object
|
||||
Object& get_object () const noexcept
|
||||
{
|
||||
fatal_assert (m_impl != nullptr);
|
||||
return *m_impl;
|
||||
}
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service);
|
||||
|
||||
// Retrieves a reference to the underlying socket.
|
||||
// usually asio::basic_socket or asio::basic_stream_socket
|
||||
// It must be compatible with our Protocol and SocketService
|
||||
// or else a std::bad cast will be thrown.
|
||||
//
|
||||
// The reason its a template class and not a function is
|
||||
// because it would otherwise generate a compile error
|
||||
// if Object did not have a declaration for
|
||||
// protocol_type::socket
|
||||
//
|
||||
template <typename AsioObject, class Enable = void>
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown);
|
||||
|
||||
// Extracts the underlying socket type from the protocol of another asio object
|
||||
template <typename T, typename Enable = void>
|
||||
struct native_socket
|
||||
{
|
||||
typedef void* native_socket_type;
|
||||
native_socket (Socket&) { pure_virtual (); }
|
||||
native_socket_type& get () { pure_virtual (); return m_socket; }
|
||||
native_socket_type& operator-> () noexcept { return get(); }
|
||||
typedef void* socket_type;
|
||||
inline native_socket (Socket&) : m_socket (nullptr) { SocketBase::pure_virtual (); }
|
||||
inline socket_type& get () { SocketBase::pure_virtual (); return m_socket; }
|
||||
inline socket_type& operator-> () { return get (); }
|
||||
private:
|
||||
native_socket_type m_socket;
|
||||
socket_type m_socket;
|
||||
};
|
||||
|
||||
template <typename AsioObject>
|
||||
struct native_socket <AsioObject, typename boost::enable_if <boost::is_class <
|
||||
typename AsioObject::protocol_type::socket> >::type>
|
||||
// Enabled if T::protocol_type::socket exists as a type
|
||||
template <typename T>
|
||||
struct native_socket <T, typename boost::enable_if <boost::is_class <
|
||||
typename T::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename AsioObject::protocol_type::socket native_socket_type;
|
||||
native_socket (Socket& peer)
|
||||
: m_socket (&peer.this_layer <native_socket_type> ()) { }
|
||||
native_socket_type& get () noexcept { return *m_socket; }
|
||||
native_socket_type& operator-> () noexcept { return *m_socket; }
|
||||
typedef typename T::protocol_type::socket socket_type;
|
||||
inline native_socket (Socket& peer) : m_socket_ptr (&peer.native_handle <socket_type> ()) { }
|
||||
inline socket_type& get () noexcept { return *m_socket_ptr; }
|
||||
inline socket_type& operator-> () noexcept { return get (); }
|
||||
private:
|
||||
native_socket_type* m_socket;
|
||||
socket_type* m_socket_ptr;
|
||||
};
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
typedef typename boost::remove_reference <Object>::type next_layer_type;
|
||||
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
next_layer_type& next_layer () noexcept
|
||||
template <typename WrappedObject>
|
||||
class SocketWrapper
|
||||
: public virtual Socket
|
||||
, public SocketWrapperBasics
|
||||
, public Uncopyable
|
||||
{
|
||||
private:
|
||||
typedef typename boost::remove_reference <WrappedObject>::type wrapped_type;
|
||||
|
||||
public:
|
||||
typedef typename boost::remove_reference <WrappedObject>::type WrappedObjectType;
|
||||
|
||||
template <typename Arg>
|
||||
explicit SocketWrapper (Arg& arg)
|
||||
: m_object (arg)
|
||||
{
|
||||
return get_object ().next_layer ();
|
||||
}
|
||||
|
||||
next_layer_type const& next_layer () const noexcept
|
||||
template <typename Arg1, typename Arg2>
|
||||
SocketWrapper (Arg1& arg1, Arg2& arg2)
|
||||
: m_object (arg1, arg2)
|
||||
{
|
||||
return get_object ().next_layer ();
|
||||
}
|
||||
|
||||
lowest_layer_type& lowest_layer () noexcept
|
||||
{
|
||||
return get_object ().lowest_layer ();
|
||||
}
|
||||
|
||||
lowest_layer_type const& lowest_layer () const noexcept
|
||||
{
|
||||
return get_object ().lowest_layer ();
|
||||
}
|
||||
|
||||
#endif
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// General
|
||||
// basic_io_object
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return get_object ().get_io_service ();
|
||||
using namespace boost::asio;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
#if 0
|
||||
// This is the one that doesn't work, (void) arg lists
|
||||
return get_io_service (
|
||||
EnableIf <has_get_io_service <wrapped_type,
|
||||
io_service ()>::value> ());
|
||||
#else
|
||||
return get_io_service (boost::true_type ());
|
||||
#endif
|
||||
}
|
||||
|
||||
bool requires_handshake ()
|
||||
boost::asio::io_service& get_io_service (
|
||||
boost::true_type)
|
||||
{
|
||||
return Has <SocketInterface::AnyHandshake>::value;
|
||||
return m_object.get_io_service ();
|
||||
}
|
||||
|
||||
void* this_layer_raw (char const* type_name) const
|
||||
boost::asio::io_service& get_io_service (
|
||||
boost::false_type)
|
||||
{
|
||||
char const* const this_type_name (typeid (ObjectType).name ());
|
||||
if (strcmp (type_name, this_type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*>(m_impl));
|
||||
pure_virtual ();
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
|
||||
#if 0
|
||||
// This is a potential work-around for the problem with
|
||||
// the has_type_lowest_layer_type template, but requires
|
||||
// Boost 1.54 or later.
|
||||
//
|
||||
// This include will be needed:
|
||||
//
|
||||
// #include <boost/tti/has_type.hpp>
|
||||
//
|
||||
//
|
||||
BOOST_TTI_HAS_TYPE(lowest_layer_type)
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct has_type_lowest_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::lowest_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_lowest_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
void* lowest_layer (char const* type_name) const
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return lowest_layer (type_name,
|
||||
EnableIf <has_type_lowest_layer_type <wrapped_type>::value> ());
|
||||
}
|
||||
|
||||
void* lowest_layer (char const* type_name,
|
||||
boost::true_type) const
|
||||
{
|
||||
char const* const name (typeid (typename wrapped_type::lowest_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.lowest_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* lowest_layer (char const*,
|
||||
boost::false_type) const
|
||||
{
|
||||
pure_virtual ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Close
|
||||
//
|
||||
|
||||
void* native_handle (char const* type_name) const
|
||||
{
|
||||
char const* const name (typeid (wrapped_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return cancel (ec,
|
||||
EnableIf <has_cancel <wrapped_type,
|
||||
system::error_code (system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.cancel (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code shutdown (shutdown_type what, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return shutdown (what, ec,
|
||||
EnableIf <has_shutdown <wrapped_type,
|
||||
system::error_code (shutdown_type, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
|
||||
boost::system::error_code shutdown (shutdown_type what, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.shutdown (what, ec);
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (shutdown_type, boost::system::error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code close (boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return close (ec,
|
||||
Has <SocketInterface::Close> ());
|
||||
EnableIf <has_close <wrapped_type,
|
||||
system::error_code (system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
boost::system::error_code close (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().close (ec);
|
||||
return m_object.close (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code close (boost::system::error_code& ec,
|
||||
@@ -176,27 +311,25 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Acceptor
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code accept (Socket& peer, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
typedef typename native_socket <wrapped_type>::socket_type socket_type;
|
||||
return accept (peer, ec,
|
||||
Has <SocketInterface::Acceptor> ());
|
||||
EnableIf <has_accept <wrapped_type,
|
||||
system::error_code (socket_type&, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
boost::system::error_code accept (Socket& peer, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
#if 1
|
||||
return get_object ().accept (
|
||||
native_socket <Object> (peer).get (), ec);
|
||||
#else
|
||||
typedef ObjectType::protocol_type::socket socket_type;
|
||||
socket_type& socket (peer.this_layer <socket_type> ());
|
||||
return get_object ().accept (socket, ec);
|
||||
#endif
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return m_object.accept (
|
||||
native_socket <wrapped_type> (peer).get (), ec);
|
||||
}
|
||||
|
||||
boost::system::error_code accept (Socket&, boost::system::error_code& ec,
|
||||
@@ -205,11 +338,18 @@ public:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
typedef typename native_socket <wrapped_type>::socket_type socket_type;
|
||||
return async_accept (peer, BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
Has <SocketInterface::Acceptor> ());
|
||||
EnableIf <has_async_accept <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (system::error_code))
|
||||
(socket_type&, BOOST_ASIO_MOVE_ARG(TransferCall))>::value> ());
|
||||
}
|
||||
|
||||
template <typename AcceptHandler>
|
||||
@@ -217,14 +357,10 @@ public:
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
#if 1
|
||||
return get_object ().async_accept (
|
||||
native_socket <Object> (peer).get (), handler);
|
||||
#else
|
||||
typedef ObjectType::protocol_type::socket socket_type;
|
||||
socket_type& socket (peer.this_layer <socket_type> ());
|
||||
return get_object ().async_accept (socket, handler);
|
||||
#endif
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return m_object.async_accept (
|
||||
native_socket <wrapped_type> (peer).get (),
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
|
||||
}
|
||||
|
||||
template <typename AcceptHandler>
|
||||
@@ -251,92 +387,23 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::LowestLayer
|
||||
// basic_stream_socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void* lowest_layer_raw (char const* type_name) const
|
||||
{
|
||||
return lowest_layer_raw (type_name,
|
||||
Has <SocketInterface::LowestLayer> ());
|
||||
}
|
||||
|
||||
void* lowest_layer_raw (char const* type_name,
|
||||
boost::true_type) const
|
||||
{
|
||||
typedef typename ObjectType::lowest_layer_type lowest_layer_type;
|
||||
char const* const lowest_layer_type_name (typeid (lowest_layer_type).name ());
|
||||
if (strcmp (type_name, lowest_layer_type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*>(&get_object ().lowest_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* lowest_layer_raw (char const*,
|
||||
boost::false_type) const
|
||||
{
|
||||
pure_virtual ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Socket
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec)
|
||||
{
|
||||
return cancel (ec,
|
||||
Has <SocketInterface::Socket> ());
|
||||
}
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().cancel (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code cancel (boost::system::error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (shutdown_type what, boost::system::error_code& ec)
|
||||
{
|
||||
return shutdown (what, ec,
|
||||
Has <SocketInterface::Socket> ());
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (Socket::shutdown_type what, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().shutdown (what, ec);
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (Socket::shutdown_type, boost::system::error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Stream
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return read_some (buffers, ec,
|
||||
Has <SocketInterface::SyncStream> ());
|
||||
EnableIf <has_read_some <wrapped_type,
|
||||
std::size_t (MutableBuffers const&, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().read_some (buffers, ec);
|
||||
return m_object.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
@@ -347,17 +414,22 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return write_some (buffers, ec,
|
||||
Has <SocketInterface::SyncStream> ());
|
||||
EnableIf <has_write_some <wrapped_type,
|
||||
std::size_t (ConstBuffers const&, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().write_some (buffers, ec);
|
||||
return m_object.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
@@ -368,11 +440,17 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
async_read_some (MutableBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_read_some (buffers, BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
Has <SocketInterface::AsyncStream> ());
|
||||
EnableIf <has_async_read_some <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (system::error_code, std::size_t))
|
||||
(MutableBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall))>::value> ());
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
@@ -380,7 +458,7 @@ public:
|
||||
async_read_some (MutableBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().async_read_some (buffers,
|
||||
return m_object.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
|
||||
@@ -404,11 +482,17 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
async_write_some (ConstBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_write_some (buffers, BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
Has <SocketInterface::AsyncStream> ());
|
||||
EnableIf <has_async_write_some <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (system::error_code, std::size_t))
|
||||
(ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall))>::value> ());
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
@@ -416,7 +500,7 @@ public:
|
||||
async_write_some (ConstBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().async_write_some (buffers,
|
||||
return m_object.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
@@ -444,20 +528,36 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Handshake
|
||||
// ssl::stream
|
||||
//
|
||||
|
||||
bool requires_handshake ()
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return
|
||||
has_handshake <wrapped_type,
|
||||
system::error_code (handshake_type, system::error_code&)>::value ||
|
||||
has_async_handshake <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
(handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall))>::value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code handshake (handshake_type type, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return handshake (type, ec,
|
||||
Has <SocketInterface::SyncHandshake> ());
|
||||
EnableIf <has_handshake <wrapped_type,
|
||||
system::error_code (handshake_type, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
boost::system::error_code handshake (handshake_type type, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().handshake (type, ec);
|
||||
return m_object.handshake (type, ec);
|
||||
}
|
||||
|
||||
boost::system::error_code handshake (handshake_type, boost::system::error_code& ec,
|
||||
@@ -466,50 +566,60 @@ public:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_handshake (type, BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
Has <SocketInterface::AsyncHandshake> ());
|
||||
EnableIf <has_async_handshake <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (system::error_code))
|
||||
(handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall))>::value> ());
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().async_handshake (type,
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
return m_object.async_handshake (type,
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (boost::system::error_code))
|
||||
async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandshakeHandler, void (boost::system::error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
ErrorCall, void (boost::system::error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler), ec));
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec));
|
||||
return init.result.get();
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler), ec));
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
|
||||
boost::system::error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return handshake (type, buffers, ec,
|
||||
Has <SocketInterface::BufferedSyncHandshake> ());
|
||||
EnableIf <has_handshake <wrapped_type,
|
||||
system::error_code (handshake_type, ConstBuffers const&, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
@@ -517,7 +627,7 @@ public:
|
||||
ConstBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().handshake (type, buffers, ec);
|
||||
return m_object.handshake (type, buffers, ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
@@ -528,59 +638,65 @@ public:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(TransferCall) handler)
|
||||
{
|
||||
return async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
Has <SocketInterface::BufferedAsyncHandshake> ());
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_handshake (type, buffers, BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
EnableIf <has_async_handshake <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (system::error_code, std::size_t))
|
||||
(handshake_type, ConstBuffers const&, system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||
async_handshake (handshake_type type, const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBuffers const& buffers, BOOST_ASIO_MOVE_ARG(TransferCall) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||
return m_object.async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (boost::system::error_code, std::size_t))
|
||||
async_handshake (handshake_type, const ConstBufferSequence&,
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
async_handshake (handshake_type, ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
BufferedHandshakeHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||
TransferCall, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(TransferCall)(handler));
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler), ec, 0));
|
||||
BOOST_ASIO_MOVE_CAST(TransferCall)(handler), ec, 0));
|
||||
return init.result.get();
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler), ec, 0));
|
||||
BOOST_ASIO_MOVE_CAST(TransferCall)(handler), ec, 0));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code shutdown (boost::system::error_code& ec)
|
||||
{
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return shutdown (ec,
|
||||
Has <SocketInterface::SyncHandshake> ());
|
||||
EnableIf <has_shutdown <wrapped_type,
|
||||
system::error_code (system::error_code&)>::value> ());
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().shutdown (ec);
|
||||
return m_object.shutdown (ec);
|
||||
}
|
||||
|
||||
boost::system::error_code shutdown (boost::system::error_code& ec,
|
||||
@@ -589,70 +705,49 @@ public:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
{
|
||||
async_shutdown (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
Has <SocketInterface::AsyncHandshake> ());
|
||||
using namespace boost;
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_shutdown (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
EnableIf <has_async_shutdown <wrapped_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (system::error_code))
|
||||
(BOOST_ASIO_MOVE_ARG(ErrorCall))>::value> ());
|
||||
}
|
||||
|
||||
template <typename ShutdownHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return get_object ().async_shutdown (
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
|
||||
return m_object.async_shutdown (
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||
}
|
||||
|
||||
template <typename ShutdownHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
ShutdownHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
|
||||
ErrorCall, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler));
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler), ec));
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec));
|
||||
return init.result.get();
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler), ec));
|
||||
BOOST_ASIO_MOVE_CAST(ErrorCall)(handler), ec));
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit SocketWrapper (Object* object = nullptr) noexcept
|
||||
: m_impl (object)
|
||||
{
|
||||
}
|
||||
|
||||
void set (Object* ptr) noexcept
|
||||
{
|
||||
m_impl = ptr;
|
||||
}
|
||||
|
||||
template <typename Interface>
|
||||
struct Has : HasInterface <ObjectType, Interface> { };
|
||||
|
||||
public:
|
||||
Object* m_impl;
|
||||
private:
|
||||
WrappedObject m_object;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Dynamically allocate a SocketWrapper.
|
||||
This deduces the template arguments for convenience.
|
||||
*/
|
||||
template <typename Object>
|
||||
SocketWrapper <Object>* newSocketWrapper (Object& object)
|
||||
{
|
||||
return new SocketWrapper <Object> (object);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
*/
|
||||
class SocketWrapperBasics
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
#if 0
|
||||
/** Template specialization to determine available interfaces. */
|
||||
template <typename Object>
|
||||
struct InterfacesOf
|
||||
@@ -129,6 +130,7 @@ protected:
|
||||
{
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -101,8 +101,8 @@ protected:
|
||||
protocol_type m_protocol;
|
||||
socket_type m_socket;
|
||||
acceptor_type m_acceptor;
|
||||
SocketWrapper <socket_type> m_socket_wrapper;
|
||||
SocketWrapper <acceptor_type> m_acceptor_wrapper;
|
||||
SocketWrapper <socket_type&> m_socket_wrapper;
|
||||
SocketWrapper <acceptor_type&> m_acceptor_wrapper;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user