From db4a1dfaa4be25a41b66f9c0cd40ac4e827d0e30 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 24 Aug 2013 17:23:22 -0700 Subject: [PATCH] Improvements to Socket and SocketWrapper --- .../Builds/VisualStudio2012/beast.vcxproj | 2 +- .../VisualStudio2012/beast.vcxproj.filters | 2 +- .../beast/modules/beast_asio/beast_asio.h | 2 +- ...dSocketWrapper.h => SocketWrapperStrand.h} | 20 +- .../beast_asio/sockets/beast_Socket.cpp | 41 ++- .../modules/beast_asio/sockets/beast_Socket.h | 168 ++++++--- .../beast_asio/sockets/beast_SocketWrapper.h | 338 +++++++++++++----- 7 files changed, 415 insertions(+), 158 deletions(-) rename Subtrees/beast/modules/beast_asio/sockets/{beast_StrandSocketWrapper.h => SocketWrapperStrand.h} (77%) diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index a58cfd9e21..f5bd33e2ea 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -89,7 +89,7 @@ - + diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 14c8ad2a05..aff86d79a7 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -908,7 +908,7 @@ beast_core\memory - + beast_asio\sockets diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.h b/Subtrees/beast/modules/beast_asio/beast_asio.h index 47c41aa94a..645eb4cab5 100644 --- a/Subtrees/beast/modules/beast_asio/beast_asio.h +++ b/Subtrees/beast/modules/beast_asio/beast_asio.h @@ -77,7 +77,7 @@ namespace beast #include "sockets/beast_SocketBase.h" #include "sockets/beast_Socket.h" #include "sockets/beast_SocketWrapper.h" -#include "sockets/beast_StrandSocketWrapper.h" +#include "sockets/SocketWrapperStrand.h" #include "sockets/beast_SslContext.h" #include "handshake/beast_InputParser.h" diff --git a/Subtrees/beast/modules/beast_asio/sockets/beast_StrandSocketWrapper.h b/Subtrees/beast/modules/beast_asio/sockets/SocketWrapperStrand.h similarity index 77% rename from Subtrees/beast/modules/beast_asio/sockets/beast_StrandSocketWrapper.h rename to Subtrees/beast/modules/beast_asio/sockets/SocketWrapperStrand.h index d170db5a5f..a280b44129 100644 --- a/Subtrees/beast/modules/beast_asio/sockets/beast_StrandSocketWrapper.h +++ b/Subtrees/beast/modules/beast_asio/sockets/SocketWrapperStrand.h @@ -17,26 +17,26 @@ */ //============================================================================== -#ifndef BEAST_STRANDSOCKETWRAPPER_H_INCLUDED -#define BEAST_STRANDSOCKETWRAPPER_H_INCLUDED +#ifndef BEAST_ASIO_SOCKETS_SOCKETWRAPPERSTRAND_H_INCLUDED +#define BEAST_ASIO_SOCKETS_SOCKETWRAPPERSTRAND_H_INCLUDED /** Wraps the async I/O of a SocketWrapper with an io_service::strand - To use this in a chain of wrappers, customize the Wrapper type. + To use this in a chain of wrappers, customize the Base type. */ template > -class StrandSocketWrapper +class SocketWrapperStrand : public Base { public: template - StrandSocketWrapper (Arg& arg) + SocketWrapperStrand (Arg& arg) : Base (arg) , m_strand (this->get_io_service ()) { } template - StrandSocketWrapper (Arg1& arg1, Arg2& arg2) + SocketWrapperStrand (Arg1& arg1, Arg2& arg2) : Base (arg1, arg2) , m_strand (this->get_io_service ()) { @@ -49,15 +49,13 @@ public: void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler) { - this->SocketWrapper ::async_read_some (buffers, + this->Base::async_read_some (buffers, newReadHandler (m_strand.wrap (handler))); } - template - void async_write_some (ConstBuffers const& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + void async_write_some (MutableBuffers const& buffers, SharedHandlerPtr handler) { - this->SocketWrapper ::async_write_some (buffers, + this->Base::async_write_some (buffers, newWriteHandler (m_strand.wrap (handler))); } diff --git a/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.cpp b/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.cpp index d90f9eb9ac..652fb579c1 100644 --- a/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.cpp +++ b/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.cpp @@ -23,6 +23,28 @@ Socket::~Socket () #if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES +//----------------------------------------------------------------------------- +// +// Socket +// + +void* Socket::this_layer_ptr (char const*) const +{ + pure_virtual_called (__FILE__, __LINE__); + return nullptr; +} + +//----------------------------------------------------------------------------- +// +// native_handle +// + +bool Socket::native_handle (char const*, void*) +{ + pure_virtual_called (__FILE__, __LINE__); + return false; +} + //----------------------------------------------------------------------------- // // basic_io_object @@ -39,13 +61,7 @@ boost::asio::io_service& Socket::get_io_service () // basic_socket // -void* Socket::lowest_layer (char const*) const -{ - pure_virtual_called (__FILE__, __LINE__); - return nullptr; -} - -void* Socket::native_handle (char const*) const +void* Socket::lowest_layer_ptr (char const*) const { pure_virtual_called (__FILE__, __LINE__); return nullptr; @@ -121,11 +137,22 @@ void Socket::async_write_some (ConstBuffers const&, SharedHandlerPtr handler) // ssl::stream // +void* Socket::next_layer_ptr (char const*) const +{ + pure_virtual_called (__FILE__, __LINE__); + return nullptr; +} + bool Socket::needs_handshake () { return false; } +void Socket::set_verify_mode (int) +{ + pure_virtual_called (__FILE__, __LINE__); +} + boost::system::error_code Socket::handshake (handshake_type, boost::system::error_code& ec) { return pure_virtual_error (ec, __FILE__, __LINE__); diff --git a/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.h b/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.h index b60df31146..a7fc45a573 100644 --- a/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.h +++ b/Subtrees/beast/modules/beast_asio/sockets/beast_Socket.h @@ -37,6 +37,76 @@ class Socket public: virtual ~Socket (); + //-------------------------------------------------------------------------- + // + // Socket + // + + /** Retrieve the underlying object. + + @note If the type doesn't match, nullptr is returned or an + exception is thrown if trying to acquire a reference. + */ + /** @{ */ + template + Object& this_layer () + { + Object* object (this->this_layer_ptr ()); + if (object == nullptr) + Throw (std::bad_cast (), __FILE__, __LINE__); + return *object; + } + + template + Object const& this_layer () const + { + Object const* object (this->this_layer_ptr ()); + if (object == nullptr) + Throw (std::bad_cast (), __FILE__, __LINE__); + return *object; + } + + template + Object* this_layer_ptr () + { + return static_cast ( + this->this_layer_ptr (typeid (Object).name ())); + } + + template + Object const* this_layer_ptr () const + { + return static_cast ( + this->this_layer_ptr (typeid (Object).name ())); + } + /** @} */ + + virtual void* this_layer_ptr (char const* type_name) const + BEAST_SOCKET_VIRTUAL; + + //-------------------------------------------------------------------------- + // + // native_handle + // + + /** Retrieve the native representation of the object. + + Since we dont know the return type, and because almost every + asio implementation passes the result by value, you need to provide + a pointer to a default-constructed object of the matching type. + + @note If the type doesn't match, an exception is thrown. + */ + template + void native_handle (Handle* dest) + { + if (! native_handle (typeid (Handle).name (), dest)) + Throw (std::bad_cast (), __FILE__, __LINE__); + } + + virtual bool native_handle (char const* type_name, void* dest) + BEAST_SOCKET_VIRTUAL; + //-------------------------------------------------------------------------- // // basic_io_object @@ -51,8 +121,9 @@ public: // /** Retrieve the lowest layer object. - Note that you must know the type name for this to work, or - else a fatal error will occur. + + @note If the type doesn't match, nullptr is returned or an + exception is thrown if trying to acquire a reference. */ /** @{ */ template @@ -77,60 +148,21 @@ public: Object* lowest_layer_ptr () { return static_cast ( - this->lowest_layer (typeid (Object).name ())); + this->lowest_layer_ptr (typeid (Object).name ())); } template Object const* lowest_layer_ptr () const { return static_cast ( - this->lowest_layer (typeid (Object).name ())); + this->lowest_layer_ptr (typeid (Object).name ())); } /** @} */ - virtual void* lowest_layer (char const* type_name) const + virtual void* lowest_layer_ptr (char const* type_name) const BEAST_SOCKET_VIRTUAL; - /** Retrieve the underlying object. - Note that you must know the type name for this to work, or - else a fatal error will occur. - */ - /** @{ */ - template - Object& native_handle () - { - Object* object (this->native_handle_ptr ()); - if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); - return *object; - } - - template - Object const& native_handle () const - { - Object const* object (this->native_handle_ptr ()); - if (object == nullptr) - Throw (std::bad_cast (), __FILE__, __LINE__); - return *object; - } - - template - Object* native_handle_ptr () - { - return static_cast ( - this->native_handle (typeid (Object).name ())); - } - - template - Object const* native_handle_ptr () const - { - return static_cast ( - this->native_handle (typeid (Object).name ())); - } - /** @} */ - - virtual void* native_handle (char const* type_name) const - BEAST_SOCKET_VIRTUAL; + //-------------------------------------------------------------------------- void cancel () { @@ -241,6 +273,48 @@ public: // ssl::stream // + /** Retrieve the next layer object. + + @note If the type doesn't match, nullptr is returned or an + exception is thrown if trying to acquire a reference. + */ + /** @{ */ + template + Object& next_layer () + { + Object* object (this->next_layer_ptr ()); + if (object == nullptr) + Throw (std::bad_cast (), __FILE__, __LINE__); + return *object; + } + + template + Object const& next_layer () const + { + Object const* object (this->next_layer_ptr ()); + if (object == nullptr) + Throw (std::bad_cast (), __FILE__, __LINE__); + return *object; + } + + template + Object* next_layer_ptr () + { + return static_cast ( + this->next_layer_ptr (typeid (Object).name ())); + } + + template + Object const* next_layer_ptr () const + { + return static_cast ( + this->next_layer_ptr (typeid (Object).name ())); + } + /** @} */ + + virtual void* next_layer_ptr (char const* type_name) const + BEAST_SOCKET_VIRTUAL; + /** Determines if the underlying stream requires a handshake. If needs_handshake is true, it will be necessary to call handshake or @@ -256,6 +330,10 @@ public: virtual bool needs_handshake () BEAST_SOCKET_VIRTUAL; + // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__verify_mode.html + // + virtual void set_verify_mode (int verify_mode) = 0; + // 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 // diff --git a/Subtrees/beast/modules/beast_asio/sockets/beast_SocketWrapper.h b/Subtrees/beast/modules/beast_asio/sockets/beast_SocketWrapper.h index 77fd340c7b..b7e86ab093 100644 --- a/Subtrees/beast/modules/beast_asio/sockets/beast_SocketWrapper.h +++ b/Subtrees/beast/modules/beast_asio/sockets/beast_SocketWrapper.h @@ -31,32 +31,14 @@ Examples of the type of Object: asio::ip::tcp::socket - arg must be an io_context - SocketWrapper will create and take ownership of the tcp::socket - this_layer_type 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 - this_layer_type will be tcp::socket - next_layer () returns a asio::ip::tcp::socket& - lowest_layer () returns a asio::ip::tcp::socket& - asio::ssl::stream - arg must be an io_context - SocketWrapper creates and takes ownership of the ssl::stream - WrappedObjecType will be asio::ssl::stream - next_layer () returns a asio::ip::tcp::socket& - lowest_layer () returns a asio::ip::tcp::socket& - asio::ssl::stream - arg must be an existing socket& - The caller owns the socket, but SocketWrapper owns the ssl::stream - this_layer_type will be asio::ssl::stream - next_layer () returns a asio::ip::tcp::socket& - lowest_layer () returns a asio::ip::tcp::socket& + explain arg must be an io_context + explain SocketWrapper will create and take ownership of the tcp::socket + explain this_layer_type will be tcp::socket + explain next_layer () returns a asio::ip::tcp::socket& + explain lowest_layer () returns a asio::ip::tcp::socket& asio::ssl::stream > > This makes my head explode @@ -64,6 +46,9 @@ //------------------------------------------------------------------------------ +namespace detail +{ + namespace SocketWrapperMemberChecks { template @@ -87,6 +72,7 @@ namespace SocketWrapperMemberChecks 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_set_verify_mode, set_verify_mode); 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); @@ -106,7 +92,10 @@ namespace SocketWrapperMemberChecks SocketBase::pure_virtual_called (__FILE__, __LINE__); return m_socket; } - inline socket_type& operator-> () { return get (); } + inline socket_type& operator-> () + { + return get (); + } private: socket_type m_socket; }; @@ -118,13 +107,23 @@ namespace SocketWrapperMemberChecks { typedef typename T::protocol_type::socket socket_type; inline native_socket (Socket& peer) - : m_socket_ptr (&peer.native_handle ()) { } - inline socket_type& get () noexcept { return *m_socket_ptr; } - inline socket_type& operator-> () noexcept { return get (); } + : m_socket_ptr (&peer.this_layer ()) + { + } + inline socket_type& get () noexcept + { + return *m_socket_ptr; + } + inline socket_type& operator-> () noexcept + { + return get (); + } private: socket_type* m_socket_ptr; }; -}; +} + +} //------------------------------------------------------------------------------ @@ -148,19 +147,7 @@ public: //-------------------------------------------------------------------------- // - // accessors - // - - // If you have access to the SocketWrapper itself instead of the Socket, - // then these types and functions become available to you. If you want - // to access things like next_layer() and lowest_layer() directly on the - // underlying object, you might write: - // - // wrapper->this_layer().next_layer() - // - // We can't expose native versions of next_layer_type or next_layer() - // because they may not exist in the underlying object and would cause - // a compile error if we tried. + // SocketWrapper // /** The type of the object being wrapped. */ @@ -178,6 +165,96 @@ public: return m_object; } + //-------------------------------------------------------------------------- + // + // Socket + // + + void* this_layer_ptr (char const* type_name) const + { + char const* const name (typeid (this_layer_type).name ()); + if (strcmp (name, type_name) == 0) + return const_cast (static_cast (&m_object)); + return nullptr; + } + + //-------------------------------------------------------------------------- + // + // native_handle + // + +#if 0 + // This is a potential work-around for the problem with + // the has_type_native_handle_type template, but requires + // Boost 1.54 or later. + // + // This include will be needed: + // + // #include + // + // + BOOST_TTI_HAS_TYPE(native_handle_type) + +#else + template + struct has_type_native_handle_type + { + typedef char yes; + typedef struct {char dummy[2];} no; + template static yes f(typename C::native_handle_type*); + template static no f(...); +#ifdef _MSC_VER + static bool const value = sizeof(f(0)) == 1; +#else + // This line fails to compile under Visual Studio 2012 + static bool const value = sizeof(has_type_native_handle_type::f(0)) == 1; +#endif + }; + +#endif + + template ::value > + struct extract_native_handle_type + { + typedef typename T::native_handle_type type; + }; + + template + struct extract_native_handle_type + { + typedef void type; + }; + + // This will be void if native_handle_type doesn't exist in Object + typedef typename extract_native_handle_type ::type native_handle_type; + + bool native_handle (char const* type_name, void* dest) + { + using namespace detail::SocketWrapperMemberChecks; + return native_handle (type_name, dest, + EnableIf ::value> ()); + } + + bool native_handle (char const* type_name, void* dest, + boost::true_type) + { + char const* const name (typeid (typename this_layer_type::native_handle_type).name ()); + if (strcmp (name, type_name) == 0) + { + native_handle_type* const p (reinterpret_cast (dest)); + *p = m_object.native_handle (); + return true; + } + return false; + } + + bool native_handle (char const*, void*, + boost::false_type) + { + pure_virtual_called (__FILE__, __LINE__); + return false; + } + //-------------------------------------------------------------------------- // // basic_io_object @@ -185,15 +262,13 @@ public: boost::asio::io_service& get_io_service () { - using namespace SocketWrapperMemberChecks; #if 0 - Type ( ( + // Apparently has_get_io_service always results in false + using namespace detail::SocketWrapperMemberChecks; + return get_io_service ( EnableIf ::value> ()); + boost::asio::io_service&()>::value> ()); #else - // BEAST_DEFINE_IS_CALL_POSSIBLE doesn't seem to - // match (void) argument lists so this is a workaround. - // return get_io_service (boost::true_type ()); #endif } @@ -216,18 +291,14 @@ public: // 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(lowest_layer_type) -#endif + /* + To forward the lowest_layer_type type, we need to make sure it + exists in Object. This is a little more tricky than just figuring + out if Object has a particular member function. + + The problem is boost::asio::basic_socket_acceptor, which doesn't + have lowest_layer () or lowest_layer_type (). + */ template struct has_type_lowest_layer_type @@ -244,14 +315,29 @@ public: #endif }; - void* lowest_layer (char const* type_name) const + template ::value > + struct extract_lowest_layer_type { - using namespace SocketWrapperMemberChecks; - return lowest_layer (type_name, + typedef typename T::lowest_layer_type type; + }; + + template + struct extract_lowest_layer_type + { + typedef void type; + }; + + // This will be void if lowest_layer_type doesn't exist in Object + typedef typename extract_lowest_layer_type ::type lowest_layer_type; + + void* lowest_layer_ptr (char const* type_name) const + { + using namespace detail::SocketWrapperMemberChecks; + return lowest_layer_ptr (type_name, EnableIf ::value> ()); } - void* lowest_layer (char const* type_name, + void* lowest_layer_ptr (char const* type_name, boost::true_type) const { char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ()); @@ -260,7 +346,7 @@ public: return nullptr; } - void* lowest_layer (char const*, + void* lowest_layer_ptr (char const*, boost::false_type) const { pure_virtual_called (__FILE__, __LINE__); @@ -269,19 +355,9 @@ public: //-------------------------------------------------------------------------- - void* native_handle (char const* type_name) const - { - char const* const name (typeid (this_layer_type).name ()); - if (strcmp (name, type_name) == 0) - return const_cast (static_cast (&m_object)); - return nullptr; - } - - //-------------------------------------------------------------------------- - error_code cancel (error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return cancel (ec, EnableIf ::value> ()); @@ -303,7 +379,7 @@ public: error_code shutdown (shutdown_type what, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return shutdown (what, ec, EnableIf ::value> ()); @@ -326,7 +402,7 @@ public: error_code close (error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return close (ec, EnableIf ::value> ()); @@ -351,7 +427,7 @@ public: error_code accept (Socket& peer, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; typedef typename native_socket ::socket_type socket_type; return accept (peer, ec, EnableIf (peer).get (), ec); } @@ -376,7 +452,7 @@ public: void async_accept (Socket& peer, SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; typedef typename native_socket ::socket_type socket_type; async_accept (peer, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf (peer).get (), BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler)); @@ -407,7 +483,7 @@ public: std::size_t read_some (MutableBuffers const& buffers, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return read_some (buffers, ec, EnableIf ::value> ()); @@ -433,7 +509,7 @@ public: std::size_t write_some (ConstBuffers const& buffers, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return write_some (buffers, ec, EnableIf ::value> ()); @@ -459,7 +535,7 @@ public: void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; async_read_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf ::value> ()); @@ -486,7 +562,7 @@ public: void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; async_write_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf ::value> ()); @@ -514,9 +590,64 @@ public: // ssl::stream // + template + struct has_type_next_layer_type + { + typedef char yes; + typedef struct {char dummy[2];} no; + template static yes f(typename C::next_layer_type*); + template static no f(...); +#ifdef _MSC_VER + static bool const value = sizeof(f(0)) == 1; +#else + // This line fails to compile under Visual Studio 2012 + static bool const value = sizeof(has_type_next_layer_type::f(0)) == 1; +#endif + }; + + template ::value > + struct extract_next_layer_type + { + typedef typename T::next_layer_type type; + }; + + template + struct extract_next_layer_type + { + typedef void type; + }; + + // This will be void if next_layer_type doesn't exist in Object + typedef typename extract_next_layer_type ::type next_layer_type; + + void* next_layer_ptr (char const* type_name) const + { + using namespace detail::SocketWrapperMemberChecks; + return next_layer_ptr (type_name, + EnableIf ::value> ()); + } + + void* next_layer_ptr (char const* type_name, + boost::true_type) const + { + char const* const name (typeid (typename this_layer_type::next_layer_type).name ()); + if (strcmp (name, type_name) == 0) + return const_cast (static_cast (&m_object.next_layer ())); + return nullptr; + } + + void* next_layer_ptr (char const*, + boost::false_type) const + { + pure_virtual_called (__FILE__, __LINE__); + return nullptr; + } + + //-------------------------------------------------------------------------- + bool needs_handshake () { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return has_handshake ::value || @@ -526,9 +657,32 @@ public: //-------------------------------------------------------------------------- + void set_verify_mode (int verify_mode) + { + using namespace detail::SocketWrapperMemberChecks; + set_verify_mode (verify_mode, + EnableIf ::value> ()); + + } + + void set_verify_mode (int verify_mode, + boost::true_type) + { + m_object.set_verify_mode (verify_mode); + } + + void set_verify_mode (int, + boost::false_type) + { + pure_virtual_called (__FILE__, __LINE__); + } + + //-------------------------------------------------------------------------- + error_code handshake (handshake_type type, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return handshake (type, ec, EnableIf ::value> ()); @@ -550,7 +704,7 @@ public: void async_handshake (handshake_type type, SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; async_handshake (type, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf ::value> ()); @@ -579,7 +733,7 @@ public: error_code handshake (handshake_type type, ConstBuffers const& buffers, error_code& ec) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; return handshake (type, buffers, ec, EnableIf ::value> ()); @@ -603,7 +757,7 @@ public: void async_handshake (handshake_type type, ConstBuffers const& buffers, SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; async_handshake (type, buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf ::value> ()); @@ -656,7 +810,7 @@ public: void async_shutdown (SharedHandlerPtr handler) { - using namespace SocketWrapperMemberChecks; + using namespace detail::SocketWrapperMemberChecks; async_shutdown (BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler), EnableIf ::value> ());