mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
TestPeer boost::asio Socket and UnitTest framework
This commit is contained in:
@@ -75,8 +75,21 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketBase.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketInterface.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapper.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapperBasics.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SslContext.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_BoostIncludes.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerBasics.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerDetails.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerLogic.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerTest.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerDetailsTcp.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncClient.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncServer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncClient.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncServer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerTestType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_basics\beast_basics.h" />
|
||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_DeadlineTimer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_basics\events\beast_OncePerSecond.h" />
|
||||
@@ -279,12 +292,60 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_asio\beast_asio.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_Socket.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_SocketBase.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_SslContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerTests.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerBasics.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncClient.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncServer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncClient.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncServer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_basics\beast_basics.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_basics\events\beast_DeadlineTimer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -149,6 +149,12 @@
|
||||
<Filter Include="beast_asio\system">
|
||||
<UniqueIdentifier>{c7a576bb-27b2-486e-aa14-3c51aa86c50f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\tests">
|
||||
<UniqueIdentifier>{422da6a1-e57e-4a96-9fce-e5958c16026e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\tests\detail">
|
||||
<UniqueIdentifier>{5d8ed68a-e3b5-49f3-938b-fbe7365f6293}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||
@@ -770,6 +776,45 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SslContext.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeer.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerBasics.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapperBasics.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerType.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerLogic.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerDetailsTcp.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerDetails.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerTest.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerTestType.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncClient.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncServer.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncClient.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncServer.h">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1192,6 +1237,30 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_SslContext.cpp">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerBasics.cpp">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerTests.cpp">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_Socket.cpp">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\beast_SocketBase.cpp">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncClient.cpp">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicAsyncServer.cpp">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncClient.cpp">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\detail\beast_TestPeerLogicSyncServer.cpp">
|
||||
<Filter>beast_asio\tests\detail</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\TODO.txt" />
|
||||
|
||||
@@ -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"
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
249
modules/beast_asio/sockets/beast_Socket.cpp
Normal file
249
modules/beast_asio/sockets/beast_Socket.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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 <bost::boost::asio::ip::tcp::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 (
|
||||
boost::boost::asio::ip::tcp::no_delay (true));
|
||||
Protocol::no_delay (true));
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
|
||||
template <class Object>
|
||||
Object& native_object ()
|
||||
Object& this_layer ()
|
||||
{
|
||||
void* const object = native_object_raw ();
|
||||
Object* object (this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *static_cast <Object*> (object);
|
||||
return *object;
|
||||
}
|
||||
|
||||
virtual void* native_object_raw () = 0;
|
||||
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> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
lowest_layer_raw (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
lowest_layer_raw (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
// Shouldn't call this directly, use lowest_layer<> instead
|
||||
virtual void* lowest_layer_raw (char const* type_name) const;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -122,7 +213,7 @@ public:
|
||||
throw_error (cancel (ec));
|
||||
}
|
||||
|
||||
virtual boost::system::error_code cancel (boost::system::error_code& ec) = 0;
|
||||
virtual boost::system::error_code cancel (boost::system::error_code& ec);
|
||||
|
||||
void shutdown (shutdown_type what)
|
||||
{
|
||||
@@ -131,15 +222,7 @@ public:
|
||||
}
|
||||
|
||||
virtual boost::system::error_code shutdown (shutdown_type what,
|
||||
boost::system::error_code& ec) = 0;
|
||||
|
||||
void close ()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
throw_error (close (ec));
|
||||
}
|
||||
|
||||
virtual boost::system::error_code close (boost::system::error_code& ec) = 0;
|
||||
boost::system::error_code& ec);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -158,7 +241,7 @@ public:
|
||||
return read_some (MutableBuffers (buffers), ec);
|
||||
}
|
||||
|
||||
virtual std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec) = 0;
|
||||
virtual std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec);
|
||||
|
||||
// SyncWriteStream
|
||||
//
|
||||
@@ -170,7 +253,7 @@ public:
|
||||
return write_some (BOOST_ASIO_MOVE_CAST(ConstBuffers)(ConstBuffers (buffers)), ec);
|
||||
}
|
||||
|
||||
virtual std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec) = 0;
|
||||
virtual std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec);
|
||||
|
||||
// AsyncReadStream
|
||||
//
|
||||
@@ -185,8 +268,8 @@ public:
|
||||
}
|
||||
|
||||
virtual
|
||||
BOOST_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) = 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);
|
||||
|
||||
// AsyncWriteStream
|
||||
//
|
||||
@@ -201,8 +284,8 @@ public:
|
||||
}
|
||||
|
||||
virtual
|
||||
BOOST_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) = 0;
|
||||
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);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -223,7 +306,7 @@ public:
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload2.html
|
||||
//
|
||||
virtual boost::system::error_code handshake (handshake_type type,
|
||||
boost::system::error_code& ec) = 0;
|
||||
boost::system::error_code& ec);
|
||||
|
||||
// ssl::stream::async_handshake (1 of 2)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload1.html
|
||||
@@ -237,12 +320,12 @@ public:
|
||||
}
|
||||
|
||||
virtual
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler) = 0;
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
// ssl::stream::handshake (3 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload3.html
|
||||
//
|
||||
@@ -264,7 +347,7 @@ public:
|
||||
}
|
||||
|
||||
virtual boost::system::error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, boost::system::error_code& ec) = 0;
|
||||
ConstBuffers const& buffers, boost::system::error_code& ec);
|
||||
|
||||
// ssl::stream::async_handshake (2 of 2)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload2.html
|
||||
@@ -279,9 +362,9 @@ public:
|
||||
}
|
||||
|
||||
virtual
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
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) = 0;
|
||||
BOOST_ASIO_MOVE_ARG(TransferCall) handler);
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -295,7 +378,7 @@ public:
|
||||
throw_error (shutdown (ec));
|
||||
}
|
||||
|
||||
virtual boost::system::error_code shutdown (boost::system::error_code& ec) = 0;
|
||||
virtual boost::system::error_code shutdown (boost::system::error_code& ec);
|
||||
|
||||
// ssl::stream::async_shutdown
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_shutdown.html
|
||||
@@ -307,8 +390,8 @@ public:
|
||||
}
|
||||
|
||||
virtual
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler) = 0;
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
30
modules/beast_asio/sockets/beast_SocketBase.cpp
Normal file
30
modules/beast_asio/sockets/beast_SocketBase.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
void SocketBase::pure_virtual ()
|
||||
{
|
||||
fatal_error ("A beast::Socket function was called on an object that doesn't support the interface");
|
||||
}
|
||||
|
||||
boost::system::error_code SocketBase::pure_virtual (boost::system::error_code& ec)
|
||||
{
|
||||
pure_virtual ();
|
||||
return ec = boost::system::errc::make_error_code (
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
@@ -20,11 +20,15 @@
|
||||
#ifndef BEAST_SOCKETBASE_H_INCLUDED
|
||||
#define BEAST_SOCKETBASE_H_INCLUDED
|
||||
|
||||
/** Implementation details for AbstractSocket.
|
||||
/** Implementation details for Socket.
|
||||
Normally you wont need to use this.
|
||||
*/
|
||||
class SocketBase
|
||||
{
|
||||
protected:
|
||||
static void pure_virtual ();
|
||||
static boost::system::error_code pure_virtual (boost::system::error_code& ec);
|
||||
|
||||
protected:
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -23,102 +23,40 @@
|
||||
/** These define the interfaces that SocketWrapper can adapt with SFINAE. */
|
||||
struct SocketInterface
|
||||
{
|
||||
/** Tag for some compatibility with asio::basic_socket
|
||||
// has close()
|
||||
struct Close { };
|
||||
|
||||
/** Tag for some compatibility with boost::asio::basic_socket_acceptor
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_socket_acceptor.html
|
||||
*/
|
||||
struct Acceptor : Close { };
|
||||
|
||||
// Has lowest_layer() and lowest_layer_type
|
||||
struct LowestLayer { };
|
||||
|
||||
/** Tag for parts of boost::asio::basic_socket
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_socket.html
|
||||
*/
|
||||
struct Socket { };
|
||||
struct Socket : Close, LowestLayer { };
|
||||
|
||||
/** Tag for some compatibility with asio::basic_stream_socket
|
||||
/** Tag for parts of boost::asio::basic_stream_socket
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_stream_socket.html
|
||||
*/
|
||||
struct SyncStream { };
|
||||
struct AsyncStream { };
|
||||
struct Stream : SyncStream, AsyncStream { };
|
||||
|
||||
/** Tags for compatibility with asio::ssl::stream
|
||||
/** Tags for parts of boost::asio::ssl::stream
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream.html
|
||||
*/
|
||||
struct SyncHandshake { };
|
||||
struct SyncBufferedHandshake : SyncHandshake { };
|
||||
struct AsyncHandshake { };
|
||||
struct AsyncBufferedHandshake : AsyncHandshake{ };
|
||||
struct Handshake : SyncBufferedHandshake, AsyncBufferedHandshake { };
|
||||
|
||||
protected:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Template specialization to determine available interfaces. */
|
||||
template <typename Object>
|
||||
struct InterfacesOf
|
||||
{
|
||||
/** Intrusive tag support.
|
||||
|
||||
To use this, add a struct called SocketInterfaces to your
|
||||
class and derive it from the interfaces that you support.
|
||||
For example:
|
||||
|
||||
@code
|
||||
|
||||
struct MyHandshakingStream
|
||||
{
|
||||
struct SocketInterfaces
|
||||
: SocketInterface::Stream
|
||||
, SocketInterface::Handshake
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
typedef typename Object::SocketInterfaces type;
|
||||
typedef type value;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::basic_socket
|
||||
template <typename Protocol, typename SocketService>
|
||||
struct InterfacesOf <boost::asio::basic_socket <Protocol, SocketService> >
|
||||
{
|
||||
struct value : SocketInterface::Socket { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::basic_stream_socket
|
||||
template <typename Protocol, typename SocketService>
|
||||
struct InterfacesOf <boost::asio::basic_stream_socket <Protocol, SocketService> >
|
||||
{
|
||||
struct value : SocketInterface::Socket, SocketInterface::Stream { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::ssl::stream
|
||||
template <typename Stream>
|
||||
struct InterfacesOf <boost::asio::ssl::stream <Stream> >
|
||||
{
|
||||
struct value : SocketInterface::Stream , SocketInterface::Handshake { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
#if 1
|
||||
// Less elegant, but works.
|
||||
// Determines if Object supports the specified Interface
|
||||
template <typename Object, typename Interface, class Enable = void>
|
||||
struct HasInterface : boost::false_type { };
|
||||
|
||||
template <typename Object, typename Interface>
|
||||
struct HasInterface <Object, Interface,
|
||||
typename boost::enable_if <boost::is_base_of <
|
||||
Interface, typename InterfacesOf <Object>::type> >::type >
|
||||
: boost::true_type { };
|
||||
#else
|
||||
// This should work, but doesn't.
|
||||
// K-ballo from #boost suggested it.
|
||||
//
|
||||
// Determines if Object supports the specified Interface
|
||||
template <typename Object, typename Interface>
|
||||
struct HasInterface : boost::is_base_of <Interface, typename InterfacesOf <Object> >
|
||||
{
|
||||
};
|
||||
#endif
|
||||
struct AnyHandshake { };
|
||||
struct SyncHandshake : AnyHandshake { };
|
||||
struct AsyncHandshake : AnyHandshake { };
|
||||
struct BufferedSyncHandshake : AnyHandshake { };
|
||||
struct BufferedAsyncHandshake : AnyHandshake { };
|
||||
struct Handshake : SyncHandshake, AsyncHandshake,
|
||||
BufferedSyncHandshake, BufferedAsyncHandshake,
|
||||
LowestLayer { };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,17 +34,14 @@
|
||||
*/
|
||||
template <class Object>
|
||||
class SocketWrapper
|
||||
: public SocketInterface
|
||||
, public virtual Socket
|
||||
: public virtual Socket
|
||||
, protected SocketWrapperBasics
|
||||
{
|
||||
public:
|
||||
typedef Object ObjectType;
|
||||
typedef typename boost::remove_reference <Object>::type ObjectT;
|
||||
typedef typename boost::remove_reference <Object>::type ObjectType;
|
||||
|
||||
SocketWrapper (Object& object) noexcept
|
||||
: m_impl (&object)
|
||||
//, m_next_layer (object.next_layer ())
|
||||
//, m_lowest_layer (object.lowest_layer ())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,10 +62,40 @@ public:
|
||||
return *m_impl;
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service () noexcept
|
||||
// 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 Object, class Enable = void>
|
||||
struct native_socket
|
||||
{
|
||||
return get_object ().get_io_service ();
|
||||
}
|
||||
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(); }
|
||||
private:
|
||||
native_socket_type m_socket;
|
||||
};
|
||||
|
||||
template <typename Object>
|
||||
struct native_socket <Object, typename boost::enable_if <boost::is_class <
|
||||
typename Object::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename Object::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; }
|
||||
|
||||
private:
|
||||
native_socket_type* m_socket;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -95,74 +122,44 @@ public:
|
||||
{
|
||||
return get_object ().lowest_layer ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// General
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool is_handshaked ()
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return HasInterface <ObjectT, SocketInterface::Handshake>::value;
|
||||
return get_object ().get_io_service ();
|
||||
}
|
||||
|
||||
void* native_object_raw ()
|
||||
bool requires_handshake ()
|
||||
{
|
||||
return m_impl;
|
||||
return Has <SocketInterface::AnyHandshake>::value;
|
||||
}
|
||||
|
||||
void* this_layer_raw (char const* type_name) const
|
||||
{
|
||||
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));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Socket
|
||||
// SocketInterface::Close
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
boost::system::error_code cancel (boost::system::error_code& ec)
|
||||
{
|
||||
return cancel (ec,
|
||||
HasInterface <ObjectT, SocketInterface::Socket> ());
|
||||
}
|
||||
|
||||
private:
|
||||
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);
|
||||
}
|
||||
|
||||
public:
|
||||
boost::system::error_code shutdown (shutdown_type what, boost::system::error_code& ec)
|
||||
{
|
||||
return shutdown (what, ec,
|
||||
HasInterface <ObjectT, SocketInterface::Socket> ());
|
||||
}
|
||||
|
||||
private:
|
||||
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);
|
||||
}
|
||||
|
||||
public:
|
||||
boost::system::error_code close (boost::system::error_code& ec)
|
||||
{
|
||||
return close (ec,
|
||||
HasInterface <ObjectT, SocketInterface::Socket> ());
|
||||
Has <SocketInterface::Close> ());
|
||||
}
|
||||
|
||||
private:
|
||||
boost::system::error_code close (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
@@ -175,20 +172,164 @@ private:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::Acceptor
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boost::system::error_code accept (Socket& peer, boost::system::error_code& ec)
|
||||
{
|
||||
return accept (peer, ec,
|
||||
Has <SocketInterface::Acceptor> ());
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
boost::system::error_code accept (Socket&, boost::system::error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return async_accept (peer, BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
Has <SocketInterface::Acceptor> ());
|
||||
}
|
||||
|
||||
template <typename AcceptHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ErrorCall, void (boost::system::error_code))
|
||||
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
|
||||
}
|
||||
|
||||
template <typename AcceptHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (boost::system::error_code))
|
||||
async_accept (Socket&, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
AcceptHandler, void (boost::system::error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(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(AcceptHandler)(handler), ec));
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketInterface::LowestLayer
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
std::size_t read_some (MutableBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
return read_some (buffers, ec,
|
||||
HasInterface <ObjectT, SocketInterface::SyncStream> ());
|
||||
Has <SocketInterface::SyncStream> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
@@ -204,14 +345,12 @@ private:
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
std::size_t write_some (ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
return write_some (buffers, ec,
|
||||
HasInterface <ObjectT, SocketInterface::SyncStream> ());
|
||||
Has <SocketInterface::SyncStream> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
@@ -227,15 +366,13 @@ private:
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
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)
|
||||
{
|
||||
return async_read_some (buffers, BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
HasInterface <ObjectT, SocketInterface::AsyncStream> ());
|
||||
Has <SocketInterface::AsyncStream> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename MutableBufferSequence, typename 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,
|
||||
@@ -250,11 +387,11 @@ private:
|
||||
async_read_some (MutableBufferSequence const&, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
ReadHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
system::error_code ec;
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (BOOST_ASIO_MOVE_CAST(ReadHandler)(handler), ec, 0));
|
||||
return init.result.get();
|
||||
@@ -265,15 +402,13 @@ private:
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
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)
|
||||
{
|
||||
return async_write_some (buffers, BOOST_ASIO_MOVE_CAST(TransferCall)(handler),
|
||||
HasInterface <ObjectT, SocketInterface::AsyncStream> ());
|
||||
Has <SocketInterface::AsyncStream> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ConstBufferSequence, typename 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,
|
||||
@@ -288,11 +423,11 @@ private:
|
||||
async_write_some (ConstBufferSequence const&, BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
WriteHandler, void (boost::system::error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
system::error_code ec;
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler), ec, 0));
|
||||
@@ -307,18 +442,16 @@ private:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Handshake
|
||||
// SocketInterface::Handshake
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
boost::system::error_code handshake (handshake_type type, boost::system::error_code& ec)
|
||||
{
|
||||
return handshake (type, ec,
|
||||
HasInterface <ObjectT, SocketInterface::SyncHandshake> ());
|
||||
Has <SocketInterface::SyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
boost::system::error_code handshake (handshake_type type, boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
@@ -331,15 +464,13 @@ private:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(ErrorCall, void (boost::system::error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
{
|
||||
return async_handshake (type, BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
HasInterface <ObjectT, SocketInterface::AsyncHandshake> ());
|
||||
Has <SocketInterface::AsyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
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,
|
||||
@@ -354,11 +485,11 @@ private:
|
||||
async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#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));
|
||||
system::error_code ec;
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler), ec));
|
||||
@@ -371,16 +502,14 @@ private:
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
#if BOOST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
boost::system::error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, boost::system::error_code& ec)
|
||||
{
|
||||
return handshake (type, buffers, ec,
|
||||
HasInterface <ObjectT, SocketInterface::SyncBufferedHandshake> ());
|
||||
Has <SocketInterface::BufferedSyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ConstBufferSequence>
|
||||
boost::system::error_code handshake (handshake_type type,
|
||||
ConstBufferSequence const& buffers, boost::system::error_code& ec,
|
||||
@@ -397,17 +526,15 @@ private:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(TransferCall, void (boost::system::error_code, std::size_t))
|
||||
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),
|
||||
HasInterface <ObjectT, SocketInterface::AsyncBufferedHandshake> ());
|
||||
Has <SocketInterface::BufferedAsyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
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,
|
||||
@@ -424,7 +551,7 @@ private:
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#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));
|
||||
@@ -442,14 +569,12 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
boost::system::error_code shutdown (boost::system::error_code& ec)
|
||||
{
|
||||
return shutdown (ec,
|
||||
HasInterface <ObjectT, SocketInterface::SyncHandshake> ());
|
||||
Has <SocketInterface::SyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
boost::system::error_code shutdown (boost::system::error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
@@ -462,14 +587,12 @@ private:
|
||||
return pure_virtual (ec);
|
||||
}
|
||||
|
||||
public:
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(ErrorCall) handler)
|
||||
{
|
||||
async_shutdown (BOOST_ASIO_MOVE_CAST(ErrorCall)(handler),
|
||||
HasInterface <ObjectT, SocketInterface::AsyncHandshake> ());
|
||||
Has <SocketInterface::AsyncHandshake> ());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ShutdownHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler, void (boost::system::error_code))
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
|
||||
@@ -484,11 +607,11 @@ private:
|
||||
async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#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));
|
||||
system::error_code ec;
|
||||
boost::system::error_code ec;
|
||||
ec = pure_virtual (ec);
|
||||
get_io_service ().post (boost::bind (
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler), ec));
|
||||
@@ -512,20 +635,10 @@ protected:
|
||||
m_impl = ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
static void pure_virtual ()
|
||||
{
|
||||
fatal_error ("A beast::Socket function was called on an object that doesn't support the interface");
|
||||
}
|
||||
template <typename Interface>
|
||||
struct Has : HasInterface <ObjectType, Interface> { };
|
||||
|
||||
static boost::system::error_code pure_virtual (boost::system::error_code& ec)
|
||||
{
|
||||
pure_virtual ();
|
||||
return ec = boost::system::errc::make_error_code (
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
|
||||
private:
|
||||
public:
|
||||
Object* m_impl;
|
||||
};
|
||||
|
||||
|
||||
110
modules/beast_asio/sockets/beast_SocketWrapperBasics.h
Normal file
110
modules/beast_asio/sockets/beast_SocketWrapperBasics.h
Normal file
@@ -0,0 +1,110 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_SOCKETWRAPPERBASICS_H_INCLUDED
|
||||
#define BEAST_SOCKETWRAPPERBASICS_H_INCLUDED
|
||||
|
||||
/** Some utilities for SocketWrapper and others.
|
||||
*/
|
||||
class SocketWrapperBasics
|
||||
{
|
||||
protected:
|
||||
/** Template specialization to determine available interfaces. */
|
||||
template <typename Object>
|
||||
struct InterfacesOf
|
||||
{
|
||||
/** Intrusive tag support.
|
||||
|
||||
To use this, add a struct called SocketInterfaces to your
|
||||
class and derive it from the interfaces that you support.
|
||||
For example:
|
||||
|
||||
@code
|
||||
|
||||
struct MyHandshakingStream
|
||||
{
|
||||
struct SocketInterfaces
|
||||
: SocketInterface::Stream
|
||||
, SocketInterface::Handshake
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
typedef typename Object::SocketInterfaces type;
|
||||
typedef type value;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::basic_socket_acceptor
|
||||
template <typename Protocol, typename SocketService>
|
||||
struct InterfacesOf <boost::asio::basic_socket_acceptor <Protocol, SocketService> >
|
||||
{
|
||||
struct value : SocketInterface::Acceptor { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::basic_socket
|
||||
template <typename Protocol, typename SocketService>
|
||||
struct InterfacesOf <boost::asio::basic_socket <Protocol, SocketService> >
|
||||
{
|
||||
struct value : SocketInterface::Socket { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::basic_stream_socket
|
||||
template <typename Protocol, typename SocketService>
|
||||
struct InterfacesOf <boost::asio::basic_stream_socket <Protocol, SocketService> >
|
||||
{
|
||||
struct value : SocketInterface::Socket, SocketInterface::Stream { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
// Specialization for boost::asio::ssl::stream
|
||||
template <typename Stream>
|
||||
struct InterfacesOf <boost::asio::ssl::stream <Stream> >
|
||||
{
|
||||
struct value : SocketInterface::Stream , SocketInterface::Handshake { };
|
||||
typedef value type;
|
||||
};
|
||||
|
||||
#if 1
|
||||
// Less elegant, but works.
|
||||
// Determines if Object supports the specified Interface
|
||||
template <typename Object, typename Interface, class Enable = void>
|
||||
struct HasInterface : boost::false_type { };
|
||||
|
||||
template <typename Object, typename Interface>
|
||||
struct HasInterface <Object, Interface,
|
||||
typename boost::enable_if <boost::is_base_of <
|
||||
Interface, typename InterfacesOf <Object>::type> >::type >
|
||||
: boost::true_type { };
|
||||
#else
|
||||
// This should work, but doesn't.
|
||||
// K-ballo from #boost suggested it.
|
||||
//
|
||||
// Determines if Object supports the specified Interface
|
||||
template <typename Object, typename Interface>
|
||||
struct HasInterface : boost::is_base_of <Interface, typename InterfacesOf <Object> >
|
||||
{
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -49,25 +49,25 @@
|
||||
// Configure some options based on the version of boost
|
||||
#include <boost/version.hpp>
|
||||
#if (BOOST_VERSION / 100) >= 1054
|
||||
# define BOOST_ASIO_HAS_BUFFEREDHANDSHAKE 1
|
||||
# define BOOST_ASIO_HAS_FUTURE_RETURNS 1
|
||||
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 1
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 1
|
||||
#else
|
||||
# define BOOST_ASIO_HAS_BUFFEREDHANDSHAKE 0
|
||||
# define BOOST_ASIO_HAS_FUTURE_RETURNS 0
|
||||
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 0
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 0
|
||||
#endif
|
||||
|
||||
#if ! BOOST_ASIO_HAS_FUTURE_RETURNS
|
||||
#if ! BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE(expr,val) void
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(expr,val) void
|
||||
# define BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(expr,val) void
|
||||
#else
|
||||
# if defined(GENERATING_DOCUMENTATION)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
# define BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
void_or_deduced
|
||||
# elif defined(_MSC_VER) && (_MSC_VER < 1500)
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
# define BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
boost::asio::detail::async_result_type_helper<h, sig>::type
|
||||
# else
|
||||
# define BOOST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
# define BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(h, sig) \
|
||||
boost::asio::async_result <boost::asio::handler_type<h, sig>::type>::type
|
||||
# endif
|
||||
#endif
|
||||
|
||||
63
modules/beast_asio/tests/beast_TestPeer.h
Normal file
63
modules/beast_asio/tests/beast_TestPeer.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEER_H_INCLUDED
|
||||
#define BEAST_TESTPEER_H_INCLUDED
|
||||
|
||||
/** An abstract peer for unit tests.
|
||||
*/
|
||||
class TestPeer
|
||||
: public TestPeerBasics
|
||||
, public Uncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~TestPeer () { }
|
||||
|
||||
/** Get the name of this peer. */
|
||||
virtual String name () const = 0;
|
||||
|
||||
/** Start the peer.
|
||||
If the peer is a server, the call will block until the
|
||||
listening socket is ready to receive connections.
|
||||
*/
|
||||
virtual void start () = 0;
|
||||
|
||||
/** Wait for the peer to finish.
|
||||
|
||||
If the peer does not complete before the timout expires
|
||||
then a timeout error is returned. If timeoutSeconds is less
|
||||
than 0, then the wait is infinite.
|
||||
|
||||
@return Any error code generated during the server operation.
|
||||
*/
|
||||
virtual boost::system::error_code join (int timeoutSeconds = -1) = 0;
|
||||
|
||||
/** Runs a unit test on the specified pair of peers.
|
||||
Returns true if the tests passed.
|
||||
*/
|
||||
#if 0
|
||||
static bool runTest (UnitTest& test,
|
||||
TestPeer& server,
|
||||
TestPeer& client,
|
||||
int timeoutSeconds,
|
||||
String const& name);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
101
modules/beast_asio/tests/beast_TestPeerBasics.cpp
Normal file
101
modules/beast_asio/tests/beast_TestPeerBasics.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
boost::system::error_category const& TestPeerBasics::test_category () noexcept
|
||||
{
|
||||
struct test_category_type : boost::system::error_category
|
||||
{
|
||||
char const* name () const noexcept
|
||||
{
|
||||
return "TestPeer";
|
||||
}
|
||||
|
||||
std::string message (int ev) const
|
||||
{
|
||||
switch (ev)
|
||||
{
|
||||
case errc::none: return "No error";
|
||||
case errc::timeout: return "The timeout expired before the test could complete";
|
||||
case errc::unexpected: return "An unexpected test result was encountered";
|
||||
case errc::exceptioned: return "An unexpected exception was thrown";
|
||||
case errc::skipped: return "The test was skipped because of previous errors";
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return "An unknown error";
|
||||
}
|
||||
|
||||
boost::system::error_condition default_error_condition (int ev) const noexcept
|
||||
{
|
||||
return boost::system::error_condition (ev, *this);
|
||||
}
|
||||
|
||||
bool equivalent (int ev, boost::system::error_condition const& condition) const noexcept
|
||||
{
|
||||
return default_error_condition (ev) == condition;
|
||||
}
|
||||
|
||||
bool equivalent (boost::system::error_code const& code, int ev) const noexcept
|
||||
{
|
||||
return *this == code.category() && code.value() == ev;
|
||||
}
|
||||
};
|
||||
|
||||
static test_category_type category;
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
boost::system::error_code TestPeerBasics::make_error (errc::errc_t ev) noexcept
|
||||
{
|
||||
return boost::system::error_code (ev, test_category ());
|
||||
}
|
||||
|
||||
boost::system::error_code TestPeerBasics::make_error (errc::errc_t ev, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
return ec = make_error (ev);
|
||||
}
|
||||
|
||||
bool TestPeerBasics::success (boost::system::error_code const& ec, bool eofIsOkay) noexcept
|
||||
{
|
||||
if (eofIsOkay && ec == boost::asio::error::eof)
|
||||
return true;
|
||||
return ! ec;
|
||||
}
|
||||
|
||||
bool TestPeerBasics::failure (boost::system::error_code const& ec, bool eofIsOkay) noexcept
|
||||
{
|
||||
return ! success (ec, eofIsOkay);
|
||||
}
|
||||
|
||||
bool TestPeerBasics::expected (bool condition, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
if (condition)
|
||||
ec = boost::system::error_code ();
|
||||
else
|
||||
make_error (errc::unexpected, ec);
|
||||
return condition;
|
||||
}
|
||||
|
||||
bool TestPeerBasics::unexpected (bool condition, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
return ! expected (condition, ec);
|
||||
}
|
||||
|
||||
143
modules/beast_asio/tests/beast_TestPeerBasics.h
Normal file
143
modules/beast_asio/tests/beast_TestPeerBasics.h
Normal file
@@ -0,0 +1,143 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERBASICS_H_INCLUDED
|
||||
#define BEAST_TESTPEERBASICS_H_INCLUDED
|
||||
|
||||
/** Common declarations for TestPeer.
|
||||
|
||||
@see TestPeer
|
||||
*/
|
||||
struct TestPeerBasics
|
||||
{
|
||||
// Custom error codes for distinguishing test conditions
|
||||
struct errc
|
||||
{
|
||||
enum errc_t
|
||||
{
|
||||
none = 0,
|
||||
timeout, // The peer join timeout expired
|
||||
unexpected, // An expected condition was false
|
||||
exceptioned, // An exception occurred
|
||||
skipped // Test skipped due to previous errors
|
||||
};
|
||||
};
|
||||
|
||||
/** Returns the category that represents TestPeer errors.
|
||||
*/
|
||||
static boost::system::error_category const& test_category () noexcept;
|
||||
|
||||
/** Creates a test error_code from the give code value.
|
||||
*/
|
||||
static boost::system::error_code make_error (errc::errc_t ev) noexcept;
|
||||
|
||||
/** Sets the passed error_code to a test error and returns it.
|
||||
*/
|
||||
static boost::system::error_code make_error (errc::errc_t ev,
|
||||
boost::system::error_code& ec) noexcept;
|
||||
|
||||
/** Returns true if the error code indicates success.
|
||||
*/
|
||||
static bool success (boost::system::error_code const& ec, bool eofIsOkay = false) noexcept;
|
||||
|
||||
/** Returns false if the error code indicates failure.
|
||||
*/
|
||||
static bool failure (boost::system::error_code const& ec, bool eofIsOkay = false) noexcept;
|
||||
|
||||
/** Set the error based on a failed condition and return the success.
|
||||
*/
|
||||
static bool expected (bool condition, boost::system::error_code& ec) noexcept;
|
||||
|
||||
/** Set the error based on a passed condition and return the success.
|
||||
*/
|
||||
static bool unexpected (bool condition, boost::system::error_code& ec) noexcept;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct Role
|
||||
{
|
||||
enum role_t
|
||||
{
|
||||
client,
|
||||
server
|
||||
};
|
||||
|
||||
Role (role_t role)
|
||||
: m_role (role)
|
||||
{
|
||||
}
|
||||
|
||||
String name () const noexcept
|
||||
{
|
||||
if (m_role == server)
|
||||
return "server";
|
||||
return "client";
|
||||
}
|
||||
|
||||
bool operator== (role_t role) const noexcept
|
||||
{
|
||||
return m_role == role;
|
||||
}
|
||||
|
||||
operator Socket::handshake_type () const noexcept
|
||||
{
|
||||
if (m_role == server)
|
||||
return Socket::server;
|
||||
return Socket::client;
|
||||
}
|
||||
|
||||
private:
|
||||
role_t m_role;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
struct Model
|
||||
{
|
||||
enum model_t
|
||||
{
|
||||
sync,
|
||||
async
|
||||
};
|
||||
|
||||
Model (model_t model)
|
||||
: m_model (model)
|
||||
{
|
||||
}
|
||||
|
||||
String name () const noexcept
|
||||
{
|
||||
if (m_model == async)
|
||||
return "async";
|
||||
return "sync";
|
||||
}
|
||||
|
||||
bool operator== (model_t model) const noexcept
|
||||
{
|
||||
return m_model == model;
|
||||
}
|
||||
|
||||
private:
|
||||
model_t m_model;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
#endif
|
||||
45
modules/beast_asio/tests/beast_TestPeerDetails.h
Normal file
45
modules/beast_asio/tests/beast_TestPeerDetails.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERDETAILS_H_INCLUDED
|
||||
#define BEAST_TESTPEERDETAILS_H_INCLUDED
|
||||
|
||||
/** Base class of all detail objects.
|
||||
*/
|
||||
class TestPeerDetails : public Uncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~TestPeerDetails () { }
|
||||
|
||||
virtual String name () = 0;
|
||||
|
||||
virtual Socket& get_socket () = 0;
|
||||
|
||||
virtual Socket& get_acceptor () = 0;
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::io_service m_io_service;
|
||||
};
|
||||
|
||||
#endif
|
||||
83
modules/beast_asio/tests/beast_TestPeerLogic.h
Normal file
83
modules/beast_asio/tests/beast_TestPeerLogic.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERLOGIC_H_INCLUDED
|
||||
#define BEAST_TESTPEERLOGIC_H_INCLUDED
|
||||
|
||||
/** Interface for implementing the logic part of a peer test.
|
||||
*/
|
||||
class TestPeerLogic
|
||||
: public TestPeerBasics
|
||||
, public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
explicit TestPeerLogic (Socket& socket)
|
||||
: m_socket (socket)
|
||||
{
|
||||
}
|
||||
|
||||
error_code& error () noexcept
|
||||
{
|
||||
return m_ec;
|
||||
}
|
||||
|
||||
error_code const& error () const noexcept
|
||||
{
|
||||
return m_ec;
|
||||
}
|
||||
|
||||
// also assigns, used for async handlers
|
||||
error_code const& error (error_code const& ec) noexcept
|
||||
{
|
||||
return m_ec = ec;
|
||||
}
|
||||
|
||||
Socket& socket () noexcept
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
virtual Role get_role () const noexcept = 0;
|
||||
|
||||
virtual Model get_model () const noexcept = 0;
|
||||
|
||||
virtual void on_connect ()
|
||||
{
|
||||
pure_virtual ();
|
||||
}
|
||||
|
||||
virtual void on_connect_async (error_code const&)
|
||||
{
|
||||
pure_virtual ();
|
||||
}
|
||||
|
||||
protected:
|
||||
static void pure_virtual ()
|
||||
{
|
||||
fatal_error ("A TestPeerLogic function was called incorrectly");
|
||||
}
|
||||
|
||||
private:
|
||||
error_code m_ec;
|
||||
Socket& m_socket;
|
||||
};
|
||||
|
||||
#endif
|
||||
128
modules/beast_asio/tests/beast_TestPeerTest.h
Normal file
128
modules/beast_asio/tests/beast_TestPeerTest.h
Normal file
@@ -0,0 +1,128 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_TESTPEERTEST_H_INCLUDED
|
||||
#define RIPPLE_TESTPEERTEST_H_INCLUDED
|
||||
|
||||
/** Performs a test of two peers defined by template parameters.
|
||||
*/
|
||||
struct TestPeerTest : protected TestPeerBasics
|
||||
{
|
||||
enum
|
||||
{
|
||||
/** How long to wait before aborting a peer and reporting a timeout.
|
||||
|
||||
@note Aborting synchronous logics may cause undefined behavior.
|
||||
*/
|
||||
defaultTimeoutSeconds = 30
|
||||
};
|
||||
|
||||
/** Holds the results for one peer. */
|
||||
class Result : protected TestPeerBasics
|
||||
{
|
||||
public:
|
||||
/** Default constructor indicates the test was skipped.
|
||||
*/
|
||||
Result ()
|
||||
: m_ec (make_error (errc::skipped))
|
||||
, m_message (m_ec.message ())
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct from an error code.
|
||||
The prefix is prepended to the error message.
|
||||
*/
|
||||
explicit Result (boost::system::error_code const& ec, String const& prefix = "")
|
||||
: m_ec (ec)
|
||||
, m_message ((prefix == String::empty) ? ec.message ()
|
||||
: prefix + " " + ec.message ())
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns true if the peer failed.
|
||||
*/
|
||||
bool failed () const noexcept
|
||||
{
|
||||
return failure (m_ec);
|
||||
}
|
||||
|
||||
/** Convenience for determining if the peer timed out. */
|
||||
bool timedout () const noexcept
|
||||
{
|
||||
return m_ec == make_error (errc::timeout);
|
||||
}
|
||||
|
||||
/** Provides a descriptive message.
|
||||
This is suitable to pass to UnitTest::fail.
|
||||
*/
|
||||
String message () const noexcept
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
/** Report the result to a UnitTest object.
|
||||
A return value of true indicates success.
|
||||
*/
|
||||
bool report (UnitTest& test)
|
||||
{
|
||||
bool const success = test.unexpected (failed (), message ());
|
||||
#if 0
|
||||
// Option to report passing tests
|
||||
if (success)
|
||||
test.logMessage (String ("passed ") + message());
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::system::error_code m_ec;
|
||||
String m_message;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Holds the results for both peers. */
|
||||
struct Results
|
||||
{
|
||||
String name; // A descriptive name for this test case.
|
||||
Result client;
|
||||
Result server;
|
||||
|
||||
Results () : name ("unknown")
|
||||
{
|
||||
}
|
||||
|
||||
/** Report the results to a UnitTest object.
|
||||
A return value of true indicates success.
|
||||
*/
|
||||
bool report (UnitTest& test, bool beginTestCase = true)
|
||||
{
|
||||
if (beginTestCase)
|
||||
test.beginTestCase (name);
|
||||
bool success = true;
|
||||
if (! client.report (test))
|
||||
success = false;
|
||||
if (! server.report (test))
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
46
modules/beast_asio/tests/beast_TestPeerTests.cpp
Normal file
46
modules/beast_asio/tests/beast_TestPeerTests.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class TestPeerTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
timeoutSeconds = 3
|
||||
};
|
||||
|
||||
TestPeerTests () : UnitTest ("TestPeer", "beast")
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Details, typename Arg >
|
||||
void testDetails (Arg const& arg = Arg ())
|
||||
{
|
||||
TestPeerTestType::test <Details> (*this, arg, timeoutSeconds);
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
typedef boost::asio::ip::tcp protocol;
|
||||
testDetails <TcpDetails, TcpDetails::arg_type> (protocol::v4 ());
|
||||
testDetails <TcpDetails, TcpDetails::arg_type> (protocol::v6 ());
|
||||
}
|
||||
};
|
||||
|
||||
static TestPeerTests testPeerTests;
|
||||
110
modules/beast_asio/tests/detail/beast_TestPeerDetailsTcp.h
Normal file
110
modules/beast_asio/tests/detail/beast_TestPeerDetailsTcp.h
Normal file
@@ -0,0 +1,110 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERDETAILSTCP_H_INCLUDED
|
||||
#define BEAST_TESTPEERDETAILSTCP_H_INCLUDED
|
||||
|
||||
/** Some predefined Detail classes for TestPeer
|
||||
*/
|
||||
struct TcpDetails : public TestPeerDetails
|
||||
{
|
||||
protected:
|
||||
typedef boost::asio::ip::tcp protocol_type;
|
||||
typedef protocol_type::socket socket_type;
|
||||
typedef protocol_type::acceptor acceptor_type;
|
||||
typedef protocol_type::endpoint endpoint_type;
|
||||
typedef protocol_type::resolver resolver_type;
|
||||
|
||||
struct NoArg { }; // dummy
|
||||
|
||||
public:
|
||||
typedef protocol_type arg_type;
|
||||
typedef socket_type native_socket_type;
|
||||
typedef acceptor_type native_acceptor_type;
|
||||
|
||||
explicit TcpDetails (arg_type protocol)
|
||||
: m_protocol (protocol)
|
||||
, m_socket (get_io_service ())
|
||||
, m_acceptor (get_io_service ())
|
||||
, m_socket_wrapper (m_socket)
|
||||
, m_acceptor_wrapper (m_acceptor)
|
||||
{
|
||||
}
|
||||
|
||||
static String getArgName (arg_type arg)
|
||||
{
|
||||
if (arg == protocol_type::v4 ())
|
||||
return "tcpv4";
|
||||
else if (arg == protocol_type::v6 ())
|
||||
return "tcpv6";
|
||||
return "tcp?";
|
||||
}
|
||||
|
||||
String name ()
|
||||
{
|
||||
return getArgName (m_protocol);
|
||||
}
|
||||
|
||||
Socket& get_socket ()
|
||||
{
|
||||
return m_socket_wrapper;
|
||||
}
|
||||
|
||||
Socket& get_acceptor ()
|
||||
{
|
||||
return m_acceptor_wrapper;
|
||||
}
|
||||
|
||||
socket_type& get_native_socket ()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
acceptor_type& get_native_acceptor ()
|
||||
{
|
||||
return m_acceptor;
|
||||
}
|
||||
|
||||
endpoint_type get_endpoint (TestPeer::Role role)
|
||||
{
|
||||
if (m_protocol == protocol_type::v4 ())
|
||||
{
|
||||
if (role == TestPeer::Role::server)
|
||||
return endpoint_type (m_protocol, 1053);
|
||||
else
|
||||
return endpoint_type (boost::asio::ip::address_v4::loopback (), 1053);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (role == TestPeer::Role::server)
|
||||
return endpoint_type (m_protocol, 1052);
|
||||
else
|
||||
return endpoint_type (boost::asio::ip::address_v6 ().from_string ("::1"), 1052);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
TestPeerLogicAsyncClient::TestPeerLogicAsyncClient (Socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
TestPeerBasics::Role TestPeerLogicAsyncClient::get_role () const noexcept
|
||||
{
|
||||
return Role::client;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicAsyncClient::get_model () const noexcept
|
||||
{
|
||||
return Model::async;
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_connect_async (error_code const& ec)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
socket ().async_handshake (Socket::client,
|
||||
boost::bind (&TestPeerLogicAsyncClient::on_handshake, this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
on_handshake (ec);
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_handshake (error_code const& ec)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
boost::asio::async_write (socket (), boost::asio::buffer ("hello", 5),
|
||||
boost::bind (&TestPeerLogicAsyncClient::on_write, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_write (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (unexpected (bytes_transferred == 5, error ()))
|
||||
return;
|
||||
|
||||
boost::asio::async_read_until (socket (), m_buf, std::string ("goodbye"),
|
||||
boost::bind (&TestPeerLogicAsyncClient::on_read, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_read (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (unexpected (bytes_transferred == 7, error ()))
|
||||
return;
|
||||
|
||||
// should check the data here?
|
||||
m_buf.consume (bytes_transferred);
|
||||
|
||||
boost::asio::async_read (socket (), m_buf.prepare (1),
|
||||
boost::bind (&TestPeerLogicAsyncClient::on_read_final, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncClient::on_read_final (error_code const& ec, std::size_t)
|
||||
{
|
||||
if (ec == boost::asio::error::eof)
|
||||
{
|
||||
if (failure (socket ().shutdown (Socket::shutdown_both, error ())))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't get eof, then there should be some other
|
||||
// error in there. We don't expect the server to send more bytes!
|
||||
//
|
||||
unexpected (success (error (ec)), error ());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
|
||||
#define BEAST_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
|
||||
|
||||
class TestPeerLogicAsyncClient : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicAsyncClient (Socket& socket);
|
||||
Role get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect_async (error_code const& ec);
|
||||
void on_handshake (error_code const& ec);
|
||||
void on_write (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_read (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_read_final (error_code const& ec, std::size_t);
|
||||
private:
|
||||
boost::asio::streambuf m_buf;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
TestPeerLogicAsyncServer::TestPeerLogicAsyncServer (Socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
TestPeerBasics::Role TestPeerLogicAsyncServer::get_role () const noexcept
|
||||
{
|
||||
return Role::server;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicAsyncServer::get_model () const noexcept
|
||||
{
|
||||
return Model::async;
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_connect_async (error_code const& ec)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
socket ().async_handshake (Socket::server,
|
||||
boost::bind (&TestPeerLogicAsyncServer::on_handshake, this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
on_handshake (ec);
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_handshake (error_code const& ec)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
boost::asio::async_read_until (socket (), m_buf, std::string ("hello"),
|
||||
boost::bind (&TestPeerLogicAsyncServer::on_read, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_read (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (unexpected (bytes_transferred == 5, error ()))
|
||||
return;
|
||||
|
||||
boost::asio::async_write (socket (), boost::asio::buffer ("goodbye", 7),
|
||||
boost::bind (&TestPeerLogicAsyncServer::on_write, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_write (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (failure (error (ec)))
|
||||
return;
|
||||
|
||||
if (unexpected (bytes_transferred == 7, error ()))
|
||||
return;
|
||||
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
socket ().async_shutdown (boost::bind (&TestPeerLogicAsyncServer::on_shutdown, this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need another instance of ec so we can call on_shutdown()
|
||||
error_code ec;
|
||||
on_shutdown (socket ().shutdown (Socket::shutdown_both, ec));
|
||||
}
|
||||
}
|
||||
|
||||
void TestPeerLogicAsyncServer::on_shutdown (error_code const& ec)
|
||||
{
|
||||
if (failure (error (ec), true))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERLOGICASYNCSERVER_H_INCLUDED
|
||||
#define BEAST_TESTPEERLOGICASYNCSERVER_H_INCLUDED
|
||||
|
||||
class TestPeerLogicAsyncServer : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicAsyncServer (Socket& socket);
|
||||
Role get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect_async (error_code const& ec);
|
||||
void on_handshake (error_code const& ec);
|
||||
void on_read (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_write (error_code const& ec, std::size_t bytes_transferred);
|
||||
void on_shutdown (error_code const& ec);
|
||||
private:
|
||||
boost::asio::streambuf m_buf;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
TestPeerLogicSyncClient::TestPeerLogicSyncClient (Socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
TestPeerBasics::Role TestPeerLogicSyncClient::get_role () const noexcept
|
||||
{
|
||||
return Role::client;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicSyncClient::get_model () const noexcept
|
||||
{
|
||||
return Model::sync;
|
||||
}
|
||||
|
||||
void TestPeerLogicSyncClient::on_connect ()
|
||||
{
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
if (failure (socket ().handshake (get_role (), error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const amount = boost::asio::write (
|
||||
socket (), boost::asio::buffer ("hello", 5), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 5, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char data [7];
|
||||
|
||||
size_t const amount = boost::asio::read (
|
||||
socket (), boost::asio::buffer (data, 7), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 7, error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (memcmp (&data, "goodbye", 7) == 0, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for 1 byte which should never come. Instead,
|
||||
// the server should close its end and we will get eof
|
||||
{
|
||||
char data [1];
|
||||
boost::asio::read (socket (), boost::asio::buffer (data, 1), error ());
|
||||
|
||||
if (error () == boost::asio::error::eof)
|
||||
{
|
||||
error () = error_code ();
|
||||
}
|
||||
else if (unexpected (failure (error ()), error ()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
if (failure (socket ().shutdown (error ()), true))
|
||||
return;
|
||||
}
|
||||
|
||||
if (failure (socket ().shutdown (Socket::shutdown_both, error ())))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
|
||||
#define BEAST_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
|
||||
|
||||
class TestPeerLogicSyncClient : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicSyncClient (Socket& socket);
|
||||
Role get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect ();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
TestPeerLogicSyncServer::TestPeerLogicSyncServer (Socket& socket)
|
||||
: TestPeerLogic (socket)
|
||||
{
|
||||
}
|
||||
|
||||
TestPeerBasics::Role TestPeerLogicSyncServer::get_role () const noexcept
|
||||
{
|
||||
return Role::server;
|
||||
}
|
||||
|
||||
TestPeerBasics::Model TestPeerLogicSyncServer::get_model () const noexcept
|
||||
{
|
||||
return Model::sync;
|
||||
}
|
||||
|
||||
void TestPeerLogicSyncServer::on_connect ()
|
||||
{
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
if (failure (socket ().handshake (get_role (), error ())))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::streambuf buf (5);
|
||||
std::size_t const amount = boost::asio::read_until (
|
||||
socket (), buf, "hello", error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 5, error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (buf.size () == 5, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t const amount = boost::asio::write (
|
||||
socket (), boost::asio::buffer ("goodbye", 7), error ());
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (unexpected (amount == 7, error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket ().requires_handshake ())
|
||||
{
|
||||
if (failure (socket ().shutdown (error ()), true))
|
||||
return;
|
||||
}
|
||||
|
||||
if (failure (socket ().shutdown (Socket::shutdown_both, error ())))
|
||||
return;
|
||||
|
||||
if (failure (socket ().close (error ())))
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERLOGICSYNCSERVER_H_INCLUDED
|
||||
#define BEAST_TESTPEERLOGICSYNCSERVER_H_INCLUDED
|
||||
|
||||
class TestPeerLogicSyncServer : public TestPeerLogic
|
||||
{
|
||||
public:
|
||||
explicit TestPeerLogicSyncServer (Socket& socket);
|
||||
Role get_role () const noexcept;
|
||||
Model get_model () const noexcept;
|
||||
void on_connect ();
|
||||
};
|
||||
|
||||
#endif
|
||||
119
modules/beast_asio/tests/detail/beast_TestPeerTestType.h
Normal file
119
modules/beast_asio/tests/detail/beast_TestPeerTestType.h
Normal file
@@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_TESTPEERTESTTYPE_H_INCLUDED
|
||||
#define RIPPLE_TESTPEERTESTTYPE_H_INCLUDED
|
||||
|
||||
/** Performs a test of two peers defined by template parameters.
|
||||
*/
|
||||
class TestPeerTestType : public TestPeerTest
|
||||
{
|
||||
public:
|
||||
/** Test two peers and return the results.
|
||||
*/
|
||||
template <typename Details, typename ServerLogic, typename ClientLogic, class Arg>
|
||||
static Results run (Arg const& arg, int timeoutSeconds = defaultTimeoutSeconds)
|
||||
{
|
||||
Results results;
|
||||
|
||||
results.name = Details::getArgName (arg);
|
||||
|
||||
try
|
||||
{
|
||||
TestPeerType <ServerLogic, Details> server (arg);
|
||||
|
||||
results.name << " / " << server.name ();
|
||||
|
||||
try
|
||||
{
|
||||
TestPeerType <ClientLogic, Details> client (arg);
|
||||
|
||||
results.name << " / " << client.name ();
|
||||
|
||||
try
|
||||
{
|
||||
server.start ();
|
||||
|
||||
try
|
||||
{
|
||||
client.start ();
|
||||
|
||||
boost::system::error_code const ec =
|
||||
client.join (timeoutSeconds);
|
||||
|
||||
results.client = Result (ec, client.name ());
|
||||
|
||||
try
|
||||
{
|
||||
boost::system::error_code const ec =
|
||||
server.join (timeoutSeconds);
|
||||
|
||||
results.server = Result (ec, server.name ());
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (make_error (
|
||||
errc::exceptioned), server.name ());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.client = Result (make_error (
|
||||
errc::exceptioned), client.name ());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (make_error (
|
||||
errc::exceptioned), server.name ());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.client = Result (make_error (
|
||||
errc::exceptioned), "client");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
results.server = Result (make_error (
|
||||
errc::exceptioned), "server");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Reports tests of Details against all known logic combinations to a UnitTest.
|
||||
*/
|
||||
template <typename Details, class Arg>
|
||||
static void test (UnitTest& test, Arg const& arg,
|
||||
int timeoutSeconds = defaultTimeoutSeconds,
|
||||
bool beginTestCase = true)
|
||||
{
|
||||
run <Details, TestPeerLogicSyncServer, TestPeerLogicSyncClient> (arg, timeoutSeconds).report (test, beginTestCase);
|
||||
run <Details, TestPeerLogicSyncServer, TestPeerLogicAsyncClient> (arg, timeoutSeconds).report (test, beginTestCase);
|
||||
run <Details, TestPeerLogicAsyncServer, TestPeerLogicSyncClient> (arg, timeoutSeconds).report (test, beginTestCase);
|
||||
run <Details, TestPeerLogicAsyncServer, TestPeerLogicAsyncClient> (arg, timeoutSeconds).report (test, beginTestCase);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
176
modules/beast_asio/tests/detail/beast_TestPeerType.h
Normal file
176
modules/beast_asio/tests/detail/beast_TestPeerType.h
Normal file
@@ -0,0 +1,176 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TESTPEERTYPE_H_INCLUDED
|
||||
#define BEAST_TESTPEERTYPE_H_INCLUDED
|
||||
|
||||
template <typename Logic, typename DetailsType>
|
||||
class TestPeerType
|
||||
: public DetailsType
|
||||
, public Logic
|
||||
, public TestPeer
|
||||
, public Thread
|
||||
{
|
||||
public:
|
||||
typedef typename DetailsType::arg_type arg_type;
|
||||
typedef TestPeerType <Logic, DetailsType> ThisType;
|
||||
|
||||
TestPeerType (arg_type const& arg)
|
||||
: DetailsType (arg)
|
||||
, Logic (get_socket ())
|
||||
, Thread (name ())
|
||||
{
|
||||
}
|
||||
|
||||
~TestPeerType ()
|
||||
{
|
||||
}
|
||||
|
||||
String name () const
|
||||
{
|
||||
return get_model ().name () + "_" + get_role ().name ();
|
||||
}
|
||||
|
||||
void start ()
|
||||
{
|
||||
startThread ();
|
||||
}
|
||||
|
||||
boost::system::error_code join (int timeoutSeconds)
|
||||
{
|
||||
if (! wait (timeoutSeconds * 1000))
|
||||
{
|
||||
stopThread (0);
|
||||
return error (make_error (errc::timeout));
|
||||
}
|
||||
|
||||
return error ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run ()
|
||||
{
|
||||
if (get_model () == Model::async)
|
||||
{
|
||||
if (get_role () == Role::server)
|
||||
{
|
||||
run_async_server ();
|
||||
}
|
||||
else if (get_role () == Role::client)
|
||||
{
|
||||
run_async_client ();
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
}
|
||||
else if (get_model () == Model::sync)
|
||||
{
|
||||
if (get_role () == Role::server)
|
||||
{
|
||||
run_sync_server ();
|
||||
}
|
||||
else if (get_role () == Role::client)
|
||||
{
|
||||
run_sync_client ();
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error () = make_error (errc::unexpected);
|
||||
}
|
||||
|
||||
get_io_service ().run ();
|
||||
|
||||
notify ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run_sync_server ()
|
||||
{
|
||||
do_listen ();
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
if (failure (get_acceptor ().accept (get_socket (), error ())))
|
||||
return;
|
||||
|
||||
this->on_connect ();
|
||||
|
||||
if (failure (error ()))
|
||||
return ;
|
||||
}
|
||||
|
||||
void run_async_server ()
|
||||
{
|
||||
do_listen ();
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
|
||||
get_acceptor ().async_accept (get_socket (), boost::bind (
|
||||
&Logic::on_connect_async, this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void run_sync_client ()
|
||||
{
|
||||
if (failure (get_native_socket ().connect (get_endpoint (get_role ()), error ())))
|
||||
return;
|
||||
|
||||
this->on_connect ();
|
||||
|
||||
if (failure (error ()))
|
||||
return;
|
||||
}
|
||||
|
||||
void run_async_client ()
|
||||
{
|
||||
get_native_socket ().async_connect (get_endpoint (get_role ()),
|
||||
boost::bind (&Logic::on_connect_async, this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void do_listen ()
|
||||
{
|
||||
if (failure (get_native_acceptor ().open (get_endpoint (get_role ()).protocol (), error ())))
|
||||
return;
|
||||
|
||||
if (failure (get_native_acceptor ().set_option (socket_type::reuse_address (true), error ())))
|
||||
return;
|
||||
|
||||
if (failure (get_native_acceptor ().bind (get_endpoint (get_role ()), error ())))
|
||||
return;
|
||||
|
||||
if (failure (get_native_acceptor ().listen (socket_type::max_connections, error ())))
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -129,16 +129,7 @@ bool UnitTest::expect (bool trueCondition, String const& failureMessage)
|
||||
|
||||
bool UnitTest::unexpected (bool falseCondition, String const& failureMessage)
|
||||
{
|
||||
if (! falseCondition)
|
||||
{
|
||||
pass ();
|
||||
}
|
||||
else
|
||||
{
|
||||
fail (failureMessage);
|
||||
}
|
||||
|
||||
return ! falseCondition;
|
||||
return expect (! falseCondition, failureMessage);
|
||||
}
|
||||
|
||||
void UnitTest::pass ()
|
||||
|
||||
Reference in New Issue
Block a user