diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj
index a66eabb50..422474a3a 100644
--- a/Builds/VisualStudio2012/beast.vcxproj
+++ b/Builds/VisualStudio2012/beast.vcxproj
@@ -75,8 +75,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -279,12 +292,60 @@
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters
index c443c1bd3..f379219ba 100644
--- a/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -149,6 +149,12 @@
{c7a576bb-27b2-486e-aa14-3c51aa86c50f}
+
+ {422da6a1-e57e-4a96-9fce-e5958c16026e}
+
+
+ {5d8ed68a-e3b5-49f3-938b-fbe7365f6293}
+
@@ -770,6 +776,45 @@
beast_asio\sockets
+
+ beast_asio\tests
+
+
+ beast_asio\tests
+
+
+ beast_asio\sockets
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests
+
+
+ beast_asio\tests
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
@@ -1192,6 +1237,30 @@
beast_asio\sockets
+
+ beast_asio\tests
+
+
+ beast_asio\tests
+
+
+ beast_asio\sockets
+
+
+ beast_asio\sockets
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
+
+ beast_asio\tests\detail
+
diff --git a/modules/beast_asio/beast_asio.cpp b/modules/beast_asio/beast_asio.cpp
index b9e45eae6..b77cf2460 100644
--- a/modules/beast_asio/beast_asio.cpp
+++ b/modules/beast_asio/beast_asio.cpp
@@ -24,6 +24,16 @@
namespace beast
{
+#include "sockets/beast_SocketBase.cpp"
+#include "sockets/beast_Socket.cpp"
#include "sockets/beast_SslContext.cpp"
+#include "tests/beast_TestPeerBasics.cpp"
+#include "tests/beast_TestPeerTests.cpp"
+
+#include "tests/detail/beast_TestPeerLogicSyncServer.cpp"
+#include "tests/detail/beast_TestPeerLogicSyncClient.cpp"
+#include "tests/detail/beast_TestPeerLogicAsyncServer.cpp"
+#include "tests/detail/beast_TestPeerLogicAsyncClient.cpp"
+
}
diff --git a/modules/beast_asio/beast_asio.h b/modules/beast_asio/beast_asio.h
index 12646080c..ac453b669 100644
--- a/modules/beast_asio/beast_asio.h
+++ b/modules/beast_asio/beast_asio.h
@@ -51,10 +51,25 @@ namespace beast
#include "sockets/beast_SocketBase.h"
#include "sockets/beast_Socket.h"
#include "sockets/beast_SocketInterface.h"
+#include "sockets/beast_SocketWrapperBasics.h"
#include "sockets/beast_SocketWrapper.h"
#include "sockets/beast_SharedSocket.h"
#include "sockets/beast_SslContext.h"
+#include "tests/beast_TestPeerBasics.h"
+#include "tests/beast_TestPeer.h"
+#include "tests/beast_TestPeerDetails.h"
+#include "tests/beast_TestPeerLogic.h"
+#include "tests/beast_TestPeerTest.h"
+
+#include "tests/detail/beast_TestPeerType.h"
+#include "tests/detail/beast_TestPeerTestType.h"
+#include "tests/detail/beast_TestPeerDetailsTcp.h"
+#include "tests/detail/beast_TestPeerLogicSyncServer.h"
+#include "tests/detail/beast_TestPeerLogicSyncClient.h"
+#include "tests/detail/beast_TestPeerLogicAsyncServer.h"
+#include "tests/detail/beast_TestPeerLogicAsyncClient.h"
+
}
#endif
diff --git a/modules/beast_asio/sockets/beast_Socket.cpp b/modules/beast_asio/sockets/beast_Socket.cpp
new file mode 100644
index 000000000..584968077
--- /dev/null
+++ b/modules/beast_asio/sockets/beast_Socket.cpp
@@ -0,0 +1,249 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+Socket::~Socket ()
+{
+}
+
+//------------------------------------------------------------------------------
+//
+// General
+//
+//------------------------------------------------------------------------------
+
+bool Socket::requires_handshake ()
+{
+ return false;
+}
+
+//------------------------------------------------------------------------------
+//
+// SocketInterface::Close
+//
+//------------------------------------------------------------------------------
+
+boost::system::error_code Socket::close (boost::system::error_code& ec)
+{
+ return pure_virtual (ec);
+}
+
+//------------------------------------------------------------------------------
+//
+// SocketInterface::Acceptor
+//
+//------------------------------------------------------------------------------
+
+boost::system::error_code Socket::accept (Socket&, boost::system::error_code& ec)
+{
+ return pure_virtual (ec);
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code))
+Socket::async_accept (Socket&, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(ErrorCall)(handler), ec));
+#endif
+}
+
+//------------------------------------------------------------------------------
+//
+// SocketInterface::LowestLayer
+//
+//------------------------------------------------------------------------------
+
+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)
+{
+ pure_virtual (ec);
+ return 0;
+}
+
+std::size_t Socket::write_some (ConstBuffers const&, boost::system::error_code& ec)
+{
+ pure_virtual (ec);
+ return 0;
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t))
+Socket::async_read_some (MutableBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(TransferCall)(handler), ec, 0));
+#endif
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t))
+Socket::async_write_some (ConstBuffers const&, BOOST_ASIO_MOVE_ARG(TransferCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(TransferCall)(handler), ec, 0));
+#endif
+}
+
+//--------------------------------------------------------------------------
+//
+// SocketInterface::Handshake
+//
+//--------------------------------------------------------------------------
+
+boost::system::error_code Socket::handshake (handshake_type, boost::system::error_code& ec)
+{
+ return pure_virtual (ec);
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code))
+Socket::async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(ErrorCall)(handler), ec));
+#endif
+}
+
+//--------------------------------------------------------------------------
+
+#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
+
+boost::system::error_code Socket::handshake (handshake_type,
+ ConstBuffers const&, boost::system::error_code& ec)
+{
+ return pure_virtual (ec);
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::TransferCall, void (boost::system::error_code, std::size_t))
+Socket::async_handshake (handshake_type, ConstBuffers const&,
+ BOOST_ASIO_MOVE_ARG(TransferCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(TransferCall)(handler), ec, 0));
+#endif
+}
+
+#endif
+
+boost::system::error_code Socket::shutdown (boost::system::error_code& ec)
+{
+ return pure_virtual (ec);
+}
+
+BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(Socket::ErrorCall, void (boost::system::error_code))
+Socket::async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
+{
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ 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(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(ErrorCall)(handler), ec));
+#endif
+}
+
diff --git a/modules/beast_asio/sockets/beast_Socket.h b/modules/beast_asio/sockets/beast_Socket.h
index 2a29bfe92..59d92684d 100644
--- a/modules/beast_asio/sockets/beast_Socket.h
+++ b/modules/beast_asio/sockets/beast_Socket.h
@@ -46,38 +46,29 @@ class Socket
, public boost::asio::socket_base
{
public:
- virtual ~Socket () { }
+ virtual ~Socket ();
//--------------------------------------------------------------------------
//
- // General attributes
+ // General
//
//--------------------------------------------------------------------------
-#if 0
- typedef Socket next_layer_type;
- typedef Socket lowest_layer_type;
-
- virtual next_layer_type& next_layer () = 0;
-
- virtual next_layer_type const& next_layer () const = 0;
-
- virtual lowest_layer_type& lowest_layer () = 0;
-
- virtual lowest_layer_type const& lowest_layer () const = 0;
-#endif
+ virtual boost::asio::io_service& get_io_service () = 0;
/** Determines if the underlying stream requires a handshake.
- If is_handshaked is true, it will be necessary to call handshake or
+ 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 is_handshaked () = 0;
+ virtual bool requires_handshake ();
/** Retrieve the underlying object.
Returns nullptr if the implementation doesn't match. Usually
@@ -88,27 +79,127 @@ public:
void set_options (Socket& socket)
{
- bost::boost::asio::ip::tcp::socket* sock =
- socket.native_object ();
+ typedef bost::boost::asio::ip::tcp Protocol;
+ typedef Protocol::socket;
+ Protocol::socket* const sock =
+ socket.this_layer ();
if (sock != nullptr)
sock->set_option (
- boost::boost::asio::ip::tcp::no_delay (true));
+ Protocol::no_delay (true));
}
@endcode
*/
-
template
- Object& native_object ()
+ Object& this_layer ()
{
- void* const object = native_object_raw ();
+ Object* object (this_layer_ptr