Refactor beast::asio:

* New tools for completion handlers:
  - wrap_handler provides composed io_service execution guarantees.
  - bind_handler rebinds arguments to handlers.
  - shared_handler type-erases any completion handler.
  - buffer_sequence type-erases templated BufferSequences
  - abstract_socket replaces Socket
  - socket_wrapper replaces SocketWrapper
  - beast::asio placeholders to work with std::bind

* Removed obsolete classes and functions
  - AbstractHandler
  - ComposedAsyncOperation
  - SharedFunction
  - SharedHandler
  - SharedHandlerAllocator
  - SharedHandlerPtr
  - SharedHandlerType
  - SocketBase
  - SocketWrapperStrand
  - wrapHandler

* Refactored classes to use new tools
  - abstract_socket
  - socket_wrapper
  - HandshakeDetector
  - HttpClientType

* Miscellanous tidying
  - socket classes moved to beast::asio namespace
  - beast asio files provide their own namespace declaration.
  - Fix IsCallPossible conflicting template parameter name
  - Use <boost/get_pointer.hpp> for C++11 compatibility.
  - Remove extraneous include path from build environment.
This commit is contained in:
Vinnie Falco
2014-03-07 20:06:12 -08:00
parent 5478c540cb
commit 6546c30e17
88 changed files with 2709 additions and 3378 deletions

View File

@@ -83,8 +83,15 @@
<ItemGroup>
<ClInclude Include="..\..\beast\Arithmetic.h" />
<ClInclude Include="..\..\beast\Asio.h" />
<ClInclude Include="..\..\beast\asio\abstract_socket.h" />
<ClInclude Include="..\..\beast\asio\bind_handler.h" />
<ClInclude Include="..\..\beast\asio\buffer_sequence.h" />
<ClInclude Include="..\..\beast\asio\io_latency_probe.h" />
<ClInclude Include="..\..\beast\asio\IPAddressConversion.h" />
<ClInclude Include="..\..\beast\asio\placeholders.h" />
<ClInclude Include="..\..\beast\asio\shared_handler.h" />
<ClInclude Include="..\..\beast\asio\socket_wrapper.h" />
<ClInclude Include="..\..\beast\asio\wrap_handler.h" />
<ClInclude Include="..\..\beast\Atomic.h" />
<ClInclude Include="..\..\beast\Boost.h" />
<ClInclude Include="..\..\beast\boost\ErrorCode.h" />
@@ -150,6 +157,7 @@
<ClInclude Include="..\..\beast\HeapBlock.h" />
<ClInclude Include="..\..\beast\HTTP.h" />
<ClInclude Include="..\..\beast\http\impl\http-parser\http_parser.h" />
<ClInclude Include="..\..\beast\http\impl\http_parser.h" />
<ClInclude Include="..\..\beast\http\ParsedURL.h" />
<ClInclude Include="..\..\beast\http\URL.h" />
<ClInclude Include="..\..\beast\Insight.h" />
@@ -238,15 +246,7 @@
<ClInclude Include="..\..\beast\utility\StaticObject.h" />
<ClInclude Include="..\..\beast\Version.h" />
<ClInclude Include="..\..\config\BeastConfig.h" />
<ClInclude Include="..\..\modules\beast_asio\async\AbstractHandler.h" />
<ClInclude Include="..\..\modules\beast_asio\async\AsyncObject.h" />
<ClInclude Include="..\..\modules\beast_asio\async\ComposedAsyncOperation.h" />
<ClInclude Include="..\..\modules\beast_asio\async\WrapHandler.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandler.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerAllocator.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerPtr.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerType.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\BuffersType.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\FixedInputBuffer.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\PeerRole.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\SharedArg.h" />
@@ -270,9 +270,6 @@
<ClInclude Include="..\..\modules\beast_asio\protocol\HandshakeDetector.h" />
<ClInclude Include="..\..\modules\beast_asio\protocol\InputParser.h" />
<ClInclude Include="..\..\modules\beast_asio\protocol\PrefilledReadStream.h" />
<ClInclude Include="..\..\modules\beast_asio\sockets\Socket.h" />
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketBase.h" />
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketWrapper.h" />
<ClInclude Include="..\..\modules\beast_asio\system\BoostIncludes.h" />
<ClInclude Include="..\..\modules\beast_asio\system\OpenSSLIncludes.h" />
<ClInclude Include="..\..\modules\beast_asio\tests\TestPeer.h" />
@@ -325,7 +322,6 @@
<ClInclude Include="..\..\modules\beast_core\memory\MemoryAlignment.h" />
<ClInclude Include="..\..\modules\beast_core\memory\MemoryBlock.h" />
<ClInclude Include="..\..\modules\beast_core\memory\OptionalScopedPointer.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedFunction.h" />
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h" />
<ClInclude Include="..\..\modules\beast_core\misc\Main.h" />
<ClInclude Include="..\..\modules\beast_core\misc\Result.h" />
@@ -424,6 +420,12 @@
<ClInclude Include="..\..\modules\beast_sqlite\sqlite\sqlite3ext.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\beast\asio\abstract_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="..\..\beast\asio\Asio.cpp" />
<ClCompile Include="..\..\beast\asio\impl\IPAddressConversion.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -743,12 +745,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\utility\Utility.cpp" />
<ClCompile Include="..\..\modules\beast_asio\async\SharedHandler.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\basics\PeerRole.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -826,18 +822,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\sockets\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\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\system\BoostUnitTests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>

View File

@@ -159,9 +159,6 @@
<Filter Include="beast_asio">
<UniqueIdentifier>{54bbe439-76c3-4781-becc-9c70a2be6d82}</UniqueIdentifier>
</Filter>
<Filter Include="beast_asio\sockets">
<UniqueIdentifier>{af535ad5-a06c-462f-8ac0-8207a708e032}</UniqueIdentifier>
</Filter>
<Filter Include="beast_asio\system">
<UniqueIdentifier>{c7a576bb-27b2-486e-aa14-3c51aa86c50f}</UniqueIdentifier>
</Filter>
@@ -710,36 +707,12 @@
<ClInclude Include="..\..\modules\beast_core\system\SystemStats.h">
<Filter>beast_core\system</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\ComposedAsyncOperation.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandler.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerAllocator.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerPtr.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerType.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\FixedInputBuffer.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\PeerRole.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\sockets\Socket.h">
<Filter>beast_asio\sockets</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketBase.h">
<Filter>beast_asio\sockets</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketWrapper.h">
<Filter>beast_asio\sockets</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\system\OpenSSLIncludes.h">
<Filter>beast_asio\system</Filter>
</ClInclude>
@@ -824,9 +797,6 @@
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParserImpl.h">
<Filter>beast_asio\http</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\BuffersType.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\SharedSingleton.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
@@ -839,9 +809,6 @@
<ClInclude Include="..\..\modules\beast_core\diagnostic\FatalError.h">
<Filter>beast_core\diagnostic</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\memory\SharedFunction.h">
<Filter>beast_core\memory</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\Config.h">
<Filter>beast</Filter>
</ClInclude>
@@ -986,12 +953,6 @@
<ClInclude Include="..\..\beast\crypto\Sha256.h">
<Filter>beast\crypto</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\WrapHandler.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\AbstractHandler.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\Chrono.h">
<Filter>beast</Filter>
</ClInclude>
@@ -1338,6 +1299,30 @@
<ClInclude Include="..\..\beast\cxx14\utility.h">
<Filter>beast\cxx14</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\abstract_socket.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\bind_handler.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\buffer_sequence.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\placeholders.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\shared_handler.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\socket_wrapper.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\asio\wrap_handler.h">
<Filter>beast\asio</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\http\impl\http_parser.h">
<Filter>beast\http\impl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
@@ -1649,18 +1634,9 @@
<ClCompile Include="..\..\modules\beast_core\system\SystemStats.cpp">
<Filter>beast_core\system</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\async\SharedHandler.cpp">
<Filter>beast_asio\async</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\basics\PeerRole.cpp">
<Filter>beast_asio\basics</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\sockets\Socket.cpp">
<Filter>beast_asio\sockets</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\sockets\SocketBase.cpp">
<Filter>beast_asio\sockets</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\beast_asio\system\BoostUnitTests.cpp">
<Filter>beast_asio\system</Filter>
</ClCompile>
@@ -1931,6 +1907,9 @@
<ClCompile Include="..\..\beast\cxx14\tests\integer_sequence.test.cpp">
<Filter>beast\cxx14\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\asio\abstract_socket.cpp">
<Filter>beast\asio</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt">

View File

@@ -20,6 +20,4 @@
#ifndef BEAST_ASIO_H_INCLUDED
#define BEAST_ASIO_H_INCLUDED
#include "asio/IPAddressConversion.h"
#endif

View File

@@ -20,3 +20,9 @@
#include "BeastConfig.h"
#include "impl/IPAddressConversion.cpp"
#include "tests/wrap_handler_tests.cpp"
#include "tests/bind_handler_tests.cpp"
#include "tests/shared_handler_tests.cpp"
#include "abstract_socket.cpp" // TEMPORARY!

View File

@@ -0,0 +1,217 @@
//------------------------------------------------------------------------------
/*
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.
*/
//==============================================================================
#include "abstract_socket.h"
#include "bind_handler.h"
namespace beast {
namespace asio {
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//------------------------------------------------------------------------------
//
// Socket
//
//------------------------------------------------------------------------------
void* abstract_socket::this_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
//------------------------------------------------------------------------------
//
// native_handle
//
//------------------------------------------------------------------------------
bool abstract_socket::native_handle (char const*, void*)
{
pure_virtual_called ();
return false;
}
//------------------------------------------------------------------------------
//
// basic_io_object
//
//------------------------------------------------------------------------------
boost::asio::io_service& abstract_socket::get_io_service ()
{
pure_virtual_called ();
return *static_cast <boost::asio::io_service*>(nullptr);
}
//------------------------------------------------------------------------------
//
// basic_socket
//
//------------------------------------------------------------------------------
void*
abstract_socket::lowest_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
auto
abstract_socket::cancel (boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
auto
abstract_socket::shutdown (shutdown_type, boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
auto
abstract_socket::close (boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
//------------------------------------------------------------------------------
//
// basic_socket_acceptor
//
//------------------------------------------------------------------------------
auto
abstract_socket::accept (abstract_socket&, error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_accept (abstract_socket&, error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
//------------------------------------------------------------------------------
//
// basic_stream_socket
//
//------------------------------------------------------------------------------
std::size_t
abstract_socket::read_some (mutable_buffers, error_code& ec)
{
ec = pure_virtual_error ();
return 0;
}
std::size_t
abstract_socket::write_some (const_buffers, error_code& ec)
{
ec = pure_virtual_error ();
return 0;
}
void
abstract_socket::async_read_some (mutable_buffers, transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
void
abstract_socket::async_write_some (const_buffers, transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
//------------------------------------------------------------------------------
//
// ssl::stream
//
//------------------------------------------------------------------------------
void*
abstract_socket::next_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
bool
abstract_socket::needs_handshake ()
{
return false;
}
void
abstract_socket::set_verify_mode (int)
{
pure_virtual_called ();
}
auto
abstract_socket::handshake (handshake_type, error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_handshake (handshake_type, error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
auto
abstract_socket::handshake (handshake_type, const_buffers, error_code& ec) ->
error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_handshake (handshake_type, const_buffers,
transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
auto
abstract_socket::shutdown (error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_shutdown (error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
#endif
}
}

View File

@@ -17,8 +17,28 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_SOCKETS_SOCKET_H_INCLUDED
#define BEAST_ASIO_SOCKETS_SOCKET_H_INCLUDED
#ifndef BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
#define BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
#include "buffer_sequence.h"
#include "shared_handler.h"
#include <boost/asio/socket_base.hpp>
#include <boost/asio/ssl/stream_base.hpp>
// Checking overrides replaces unimplemented stubs with pure virtuals
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_SOCKET_VIRTUAL = 0
#else
# define BEAST_SOCKET_VIRTUAL
#endif
namespace beast {
namespace asio {
/** A high level socket abstraction.
@@ -29,18 +49,61 @@
When member functions are called and the underlying implementation does
not support the operation, a fatal error is generated.
*/
class Socket
: public SocketBase
, public boost::asio::ssl::stream_base
class abstract_socket
: public boost::asio::ssl::stream_base
, public boost::asio::socket_base
{
protected:
typedef boost::system::error_code error_code;
typedef asio::shared_handler <void (void)> post_handler;
typedef asio::shared_handler <void (error_code)> error_handler;
typedef asio::shared_handler <
void (error_code, std::size_t)> transfer_handler;
static
void
pure_virtual_called()
{
throw std::runtime_error ("pure virtual called");
}
static
error_code
pure_virtual_error ()
{
pure_virtual_called();
return boost::system::errc::make_error_code (
boost::system::errc::function_not_supported);
}
static
error_code
pure_virtual_error (error_code& ec)
{
return ec = pure_virtual_error();
}
static
void
throw_if (error_code const& ec)
{
if (ec)
throw boost::system::system_error (ec);
}
public:
virtual ~Socket ();
virtual ~abstract_socket ()
{
}
//--------------------------------------------------------------------------
//
// Socket
// abstract_socket
//
//--------------------------------------------------------------------------
/** Retrieve the underlying object.
@@ -48,32 +111,32 @@ public:
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <typename Object>
template <class Object>
Object& this_layer ()
{
Object* object (this->this_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object const& this_layer () const
{
Object const* object (this->this_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object* this_layer_ptr ()
{
return static_cast <Object*> (
this->this_layer_ptr (typeid (Object).name ()));
}
template <typename Object>
template <class Object>
Object const* this_layer_ptr () const
{
return static_cast <Object const*> (
@@ -88,6 +151,7 @@ public:
//
// native_handle
//
//--------------------------------------------------------------------------
/** Retrieve the native representation of the object.
@@ -101,7 +165,7 @@ public:
void native_handle (Handle* dest)
{
if (! native_handle (typeid (Handle).name (), dest))
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
}
virtual bool native_handle (char const* type_name, void* dest)
@@ -111,6 +175,7 @@ public:
//
// basic_io_object
//
//--------------------------------------------------------------------------
virtual boost::asio::io_service& get_io_service ()
BEAST_SOCKET_VIRTUAL;
@@ -119,6 +184,7 @@ public:
//
// basic_socket
//
//--------------------------------------------------------------------------
/** Retrieve the lowest layer object.
@@ -126,32 +192,32 @@ public:
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <typename Object>
template <class Object>
Object& lowest_layer ()
{
Object* object (this->lowest_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object const& lowest_layer () const
{
Object const* object (this->lowest_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object* lowest_layer_ptr ()
{
return static_cast <Object*> (
this->lowest_layer_ptr (typeid (Object).name ()));
}
template <typename Object>
template <class Object>
Object const* lowest_layer_ptr () const
{
return static_cast <Object const*> (
@@ -167,7 +233,8 @@ public:
void cancel ()
{
error_code ec;
throw_error (cancel (ec), __FILE__, __LINE__);
cancel (ec);
throw_if (ec);
}
virtual error_code cancel (error_code& ec)
@@ -176,7 +243,8 @@ public:
void shutdown (shutdown_type what)
{
error_code ec;
throw_error (shutdown (what, ec), __FILE__, __LINE__);
shutdown (what, ec);
throw_if (ec);
}
virtual error_code shutdown (shutdown_type what,
@@ -186,7 +254,8 @@ public:
void close ()
{
error_code ec;
throw_error (close (ec), __FILE__, __LINE__);
close (ec);
throw_if (ec);
}
virtual error_code close (error_code& ec)
@@ -196,82 +265,39 @@ public:
//
// basic_socket_acceptor
//
//--------------------------------------------------------------------------
virtual error_code accept (Socket& peer, error_code& ec)
virtual error_code accept (abstract_socket& peer, error_code& ec)
BEAST_SOCKET_VIRTUAL;
template <typename AcceptHandler>
void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
{
return async_accept (peer,
newAcceptHandler (BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)));
}
virtual void async_accept (Socket& peer, SharedHandlerPtr handler)
virtual void async_accept (abstract_socket& peer, error_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// basic_stream_socket
//
//--------------------------------------------------------------------------
// SyncReadStream
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncReadStream.html
//
template <typename MutableBufferSequence>
std::size_t read_some (MutableBufferSequence const& buffers,
error_code& ec)
{
return read_some (MutableBuffers (buffers), ec);
}
virtual std::size_t read_some (MutableBuffers const& buffers, error_code& ec)
virtual std::size_t read_some (mutable_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
// SyncWriteStream
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncWriteStream.html
//
template <typename ConstBufferSequence>
std::size_t write_some (ConstBufferSequence const& buffers, error_code &ec)
{
return write_some (ConstBuffers (buffers), ec);
}
virtual std::size_t write_some (ConstBuffers const& buffers, error_code& ec)
virtual std::size_t write_some (const_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
// AsyncReadStream
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncReadStream.html
//
template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some (MutableBufferSequence const& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
return async_read_some (MutableBuffers (buffers),
newReadHandler (BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)));
}
virtual void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
virtual void async_read_some (mutable_buffers buffers,
transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
// AsyncWriteStream
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncWriteStream.html
//
template <typename ConstBufferSequence, typename WriteHandler>
void async_write_some (ConstBufferSequence const& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
return async_write_some (ConstBuffers (buffers),
newWriteHandler (BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)));
}
virtual void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler)
virtual void async_write_some (const_buffers buffers,
transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// ssl::stream
//
//--------------------------------------------------------------------------
/** Retrieve the next layer object.
@@ -279,32 +305,32 @@ public:
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <typename Object>
template <class Object>
Object& next_layer ()
{
Object* object (this->next_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object const& next_layer () const
{
Object const* object (this->next_layer_ptr <Object> ());
if (object == nullptr)
Throw (std::bad_cast (), __FILE__, __LINE__);
throw std::bad_cast ();
return *object;
}
template <typename Object>
template <class Object>
Object* next_layer_ptr ()
{
return static_cast <Object*> (
this->next_layer_ptr (typeid (Object).name ()));
}
template <typename Object>
template <class Object>
Object const* next_layer_ptr () const
{
return static_cast <Object const*> (
@@ -330,107 +356,49 @@ public:
virtual bool needs_handshake ()
BEAST_SOCKET_VIRTUAL;
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__verify_mode.html
//
virtual void set_verify_mode (int verify_mode) = 0;
virtual void set_verify_mode (int verify_mode)
BEAST_SOCKET_VIRTUAL;
// ssl::stream::handshake (1 of 4)
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload1.html
//
void handshake (handshake_type type)
{
error_code ec;
throw_error (handshake (type, ec), __FILE__, __LINE__);
handshake (type, ec);
throw_if (ec);
}
// ssl::stream::handshake (2 of 4)
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload2.html
//
virtual error_code handshake (handshake_type type, error_code& ec)
BEAST_SOCKET_VIRTUAL;
// 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
//
template <typename HandshakeHandler>
void async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
{
return async_handshake (type,
newHandshakeHandler (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)));
}
virtual void async_handshake (handshake_type type, SharedHandlerPtr handler)
virtual void async_handshake (handshake_type type, error_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
#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
//
template <typename ConstBufferSequence>
void handshake (handshake_type type, ConstBufferSequence const& buffers)
{
error_code ec;
throw_error (handshake (type, buffers, ec), __FILE__, __LINE__);
}
// ssl::stream::handshake (4 of 4)
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload4.html
//
template <typename ConstBufferSequence>
error_code handshake (handshake_type type,
ConstBufferSequence const& buffers, error_code& ec)
{
return handshake (type, ConstBuffers (buffers), ec);
}
virtual error_code handshake (handshake_type type,
ConstBuffers const& buffers, error_code& ec)
const_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
// 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
//
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
void async_handshake (handshake_type type, ConstBufferSequence const& buffers,
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
{
return async_handshake (type, ConstBuffers (buffers),
newBufferedHandshakeHandler (BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)));
}
virtual void async_handshake (handshake_type type, ConstBuffers const& buffers,
SharedHandlerPtr handler)
virtual void async_handshake (handshake_type type,
const_buffers buffers, transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
#endif
//--------------------------------------------------------------------------
// ssl::stream::shutdown
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/shutdown.html
//
void shutdown ()
{
error_code ec;
throw_error (shutdown (ec), __FILE__, __LINE__);
shutdown (ec);
throw_if (ec);
}
virtual error_code shutdown (error_code& ec)
BEAST_SOCKET_VIRTUAL;
// ssl::stream::async_shutdown
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_shutdown.html
//
template <typename ShutdownHandler>
void async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
{
return async_shutdown (
newShutdownHandler (BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)));
}
virtual void async_shutdown (SharedHandlerPtr handler)
virtual void async_shutdown (error_handler handler)
BEAST_SOCKET_VIRTUAL;
};
}
}
#endif

163
beast/asio/bind_handler.h Normal file
View File

@@ -0,0 +1,163 @@
//------------------------------------------------------------------------------
/*
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_ASIO_BIND_HANDLER_H_INCLUDED
#define BEAST_ASIO_BIND_HANDLER_H_INCLUDED
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <functional>
#include "../cxx14/type_traits.h" // <type_traits>
#include "../cxx14/utility.h" // <utility>
namespace beast {
namespace asio {
namespace detail {
/** Nullary handler that calls Handler with bound arguments.
The rebound handler provides the same io_service execution
guarantees as the original handler.
*/
template <class DeducedHandler, class... Args>
class bound_handler
{
private:
typedef std::tuple <std::decay_t <Args>...> args_type;
std::decay_t <DeducedHandler> m_handler;
args_type m_args;
template <class Handler, class Tuple, std::size_t... S>
static void invoke (Handler& h, Tuple& args,
std::index_sequence <S...>)
{
h (std::get <S> (args)...);
}
public:
typedef void result_type;
bound_handler (DeducedHandler&& handler, Args&&... args)
: m_handler (std::forward <DeducedHandler> (handler))
, m_args (std::forward <Args> (args)...)
{
}
void
operator() ()
{
invoke (m_handler, m_args,
std::index_sequence_for <Args...> ());
}
void
operator() () const
{
invoke (m_handler, m_args,
std::index_sequence_for <Args...> ());
}
template <class Function>
friend
void
asio_handler_invoke (Function& f, bound_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_handler);
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f, bound_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_handler);
}
friend
void*
asio_handler_allocate (std::size_t size, bound_handler* h)
{
return boost_asio_handler_alloc_helpers::
allocate (size, h->m_handler);
}
friend
void
asio_handler_deallocate (void* p, std::size_t size, bound_handler* h)
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, h->m_handler);
}
friend
bool
asio_handler_is_continuation (bound_handler* h)
{
return boost_asio_handler_cont_helpers::
is_continuation (h->m_handler);
}
};
}
//------------------------------------------------------------------------------
/** Binds parameters to a handler to produce a nullary functor.
The returned handler provides the same io_service execution guarantees
as the original handler. This is designed to use as a replacement for
io_service::wrap, to ensure that the handler will not be invoked
immediately by the calling function.
*/
template <class DeducedHandler, class... Args>
detail::bound_handler <DeducedHandler, Args...>
bind_handler (DeducedHandler&& handler, Args&&... args)
{
return detail::bound_handler <DeducedHandler, Args...> (
std::forward <DeducedHandler> (handler),
std::forward <Args> (args)...);
}
}
}
//------------------------------------------------------------------------------
namespace std {
template <class Handler, class... Args>
void bind (beast::asio::detail::bound_handler <
Handler, Args...>, ...) = delete;
#if 0
template <class Handler, class... Args>
struct is_bind_expression <
beast::asio::detail::bound_handler <Handler, Args...>
> : std::true_type
{
};
#endif
}
#endif

View 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_ASIO_BUFFER_SEQUENCE_H_INCLUDED
#define BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <iterator>
#include "../cxx14/type_traits.h" // <type_traits>
#include <vector>
namespace beast {
namespace asio {
template <class Buffer>
class buffer_sequence
{
private:
typedef std::vector <Buffer> sequence_type;
public:
typedef Buffer value_type;
typedef typename sequence_type::const_iterator const_iterator;
private:
sequence_type m_buffers;
template <class FwdIter>
void assign (FwdIter first, FwdIter last)
{
m_buffers.clear();
m_buffers.reserve (std::distance (first, last));
for (;first != last; ++first)
m_buffers.push_back (*first);
}
public:
buffer_sequence ()
{
}
template <
class BufferSequence,
class = std::enable_if_t <std::is_constructible <
Buffer, typename BufferSequence::value_type>::value>
>
buffer_sequence (BufferSequence const& s)
{
assign (std::begin (s), std::end (s));
}
template <
class FwdIter,
class = std::enable_if_t <std::is_constructible <
Buffer, typename std::iterator_traits <
FwdIter>::value_type>::value>
>
buffer_sequence (FwdIter first, FwdIter last)
{
assign (first, last);
}
template <class BufferSequence>
std::enable_if_t <std::is_constructible <
Buffer, typename BufferSequence::value_type>::value,
buffer_sequence&
>
operator= (BufferSequence const& s)
{
return assign (s);
}
const_iterator
begin () const noexcept
{
return m_buffers.begin ();
}
const_iterator
end () const noexcept
{
return m_buffers.end ();
}
};
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
typedef buffer_sequence <boost::asio::mutable_buffer> mutable_buffers;
}
}
#endif

View File

@@ -17,31 +17,25 @@
*/
//==============================================================================
void SharedHandler::operator() ()
{
pure_virtual_called (__FILE__, __LINE__);
#ifndef BEAST_ASIO_PLACEHOLDERS_H_INCLUDED
#define BEAST_ASIO_PLACEHOLDERS_H_INCLUDED
#include <functional>
namespace beast {
namespace asio {
namespace placeholders {
// asio placeholders that work with std::bind
namespace {
static auto const error (std::placeholders::_1);
static auto const bytes_transferred (std::placeholders::_2);
static auto const iterator (std::placeholders::_2);
static auto const signal_number (std::placeholders::_2);
}
}
void SharedHandler::operator() (error_code const&)
{
pure_virtual_called (__FILE__, __LINE__);
}
}
void SharedHandler::operator() (error_code const&, std::size_t)
{
pure_virtual_called (__FILE__, __LINE__);
}
void SharedHandler::pure_virtual_called (char const* fileName, int lineNumber)
{
// These shouldn't be getting called. But since the object returned
// by most implementations of bind have operator() up to high arity
// levels, it is not generally possible to write a traits test that
// works in all scenarios for detecting a particular signature of a
// handler.
//
// We use Throw here so beast has a chance to dump the stack BEFORE
// the stack is unwound.
//
Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber);
}
#endif

472
beast/asio/shared_handler.h Normal file
View File

@@ -0,0 +1,472 @@
//------------------------------------------------------------------------------
/*
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_ASIO_SHARED_HANDLER_H_INCLUDED
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
#include "../mpl/IsCallPossible.h"
#include <functional>
#include <memory>
#include "../cxx14/type_traits.h" // <type_traits>
#include <boost/utility/base_from_member.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#ifndef BEAST_ASIO_NO_ALLOCATE_SHARED
#define BEAST_ASIO_NO_ALLOCATE_SHARED 0
#endif
#ifndef BEAST_ASIO_NO_HANDLER_RESULT_OF
#define BEAST_ASIO_NO_HANDLER_RESULT_OF 1
#endif
namespace beast {
namespace asio {
class shared_handler_wrapper_base
{
public:
virtual ~shared_handler_wrapper_base()
{
}
virtual void invoke (std::function <void (void)> f) = 0;
virtual void* allocate (std::size_t size) = 0;
virtual void deallocate (void* p, std::size_t size) = 0;
virtual bool is_continuation () = 0;
};
//------------------------------------------------------------------------------
template <class Signature>
class shared_handler_wrapper_func
: public shared_handler_wrapper_base
{
private:
std::function <Signature> m_func;
public:
template <class Handler>
explicit shared_handler_wrapper_func (Handler&& handler)
: m_func (std::ref (std::forward <Handler> (handler)))
{
}
template <class... Args>
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
void
#else
std::result_of_t <std::function <Signature> (Args...)>
#endif
operator() (Args&&... args) const
{
return m_func (std::forward <Args> (args)...);
}
};
//------------------------------------------------------------------------------
namespace detail {
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4512) // assignment operator could not be generated
#endif
template <class Signature, class Handler>
class shared_handler_wrapper
: private boost::base_from_member <Handler>
, public shared_handler_wrapper_func <Signature>
{
private:
typedef boost::base_from_member <Handler> Base;
BEAST_DEFINE_IS_CALL_POSSIBLE(has_is_continuation, is_continuation);
public:
shared_handler_wrapper (Handler&& handler)
: boost::base_from_member <Handler> (std::move (handler))
, shared_handler_wrapper_func <Signature> (Base::member)
{
}
shared_handler_wrapper (Handler const& handler)
: boost::base_from_member <Handler> (handler)
, shared_handler_wrapper_func <Signature> (Base::member)
{
}
private:
void
invoke (std::function <void (void)> f) override
{
return boost_asio_handler_invoke_helpers::
invoke (f, Base::member);
}
void*
allocate (std::size_t size) override
{
return boost_asio_handler_alloc_helpers::
allocate (size, Base::member);
}
void
deallocate (void* p, std::size_t size) override
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, Base::member);
}
bool
is_continuation () override
{
return is_continuation (std::integral_constant <bool,
has_is_continuation <Handler, bool(void)>::value>());
}
bool
is_continuation (std::true_type)
{
return Base::member.is_continuation();
}
bool
is_continuation (std::false_type)
{
return boost_asio_handler_cont_helpers::
is_continuation (Base::member);
}
};
#ifdef _MSC_VER
#pragma warning (pop)
#endif
template <class T>
struct is_shared_handler : public std::false_type
{
};
//------------------------------------------------------------------------------
template <class T, class Handler>
class handler_allocator
{
private:
// We want a partial template specialization as a friend
// but that isn't allowed so we friend all versions. This
// should produce a compile error if Handler is not constructible
// from H.
//
template <class U, class H>
friend class handler_allocator;
Handler m_handler;
public:
typedef T value_type;
typedef T* pointer;
template <class U>
struct rebind
{
public:
typedef handler_allocator <U, Handler> other;
};
handler_allocator() = delete;
handler_allocator (Handler const& handler)
: m_handler (handler)
{
}
template <class U>
handler_allocator (
handler_allocator <U, Handler> const& other)
: m_handler (other.m_handler)
{
}
handler_allocator&
operator= (handler_allocator const&) = delete;
pointer
allocate (std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
return static_cast <pointer> (
boost_asio_handler_alloc_helpers::allocate (
size, m_handler));
}
void
deallocate (pointer p, std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
boost_asio_handler_alloc_helpers::deallocate (
p, size, m_handler);
}
// Work-around for MSVC not using allocator_traits
// in the implementation of shared_ptr
//
#ifdef _MSC_VER
void
destroy (T* t)
{
t->~T();
}
#endif
friend
bool
operator== (handler_allocator const& lhs, handler_allocator const& rhs)
{
return true;
}
friend
bool
operator!= (handler_allocator const& lhs, handler_allocator const& rhs)
{
return ! (lhs == rhs);
}
};
}
//------------------------------------------------------------------------------
/** Handler shared reference that provides io_service execution guarantees. */
template <
class Signature
>
class shared_handler
{
private:
template <class T>
friend class shared_handler_allocator;
typedef shared_handler_wrapper_func <
Signature> wrapper_type;
typedef std::shared_ptr <wrapper_type> ptr_type;
ptr_type m_ptr;
public:
shared_handler()
{
}
template <
class DeducedHandler,
class = std::enable_if_t <
! detail::is_shared_handler <
std::decay_t <DeducedHandler>>::value &&
std::is_constructible <std::function <Signature>,
std::decay_t <DeducedHandler>>::value
>
>
shared_handler (DeducedHandler&& handler)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
#if BEAST_ASIO_NO_ALLOCATE_SHARED
m_ptr = std::make_shared <detail::shared_handler_wrapper <
Signature, Handler>> (std::forward <DeducedHandler> (handler));
#else
m_ptr = std::allocate_shared <detail::shared_handler_wrapper <
Signature, Handler>> (detail::handler_allocator <char, Handler> (
handler), std::forward <DeducedHandler> (handler));
#endif
}
shared_handler (shared_handler&& other)
: m_ptr (std::move (other.m_ptr))
{
}
shared_handler (shared_handler const& other)
: m_ptr (other.m_ptr)
{
}
shared_handler&
operator= (std::nullptr_t)
{
m_ptr = nullptr;
}
shared_handler&
operator= (shared_handler const& rhs)
{
m_ptr = rhs.m_ptr;
return *this;
}
bool
empty() const
{
return ! m_ptr.operator bool();
}
operator bool() const
{
return !empty();
}
void
reset()
{
m_ptr.reset();
}
template <class... Args>
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
void
#else
std::result_of_t <std::function <Signature> (Args...)>
#endif
operator() (Args&&... args) const
{
return (*m_ptr)(std::forward <Args> (args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function&& f, shared_handler* h)
{
return h->m_ptr->invoke (f);
}
friend
void*
asio_handler_allocate (
std::size_t size, shared_handler* h)
{
return h->m_ptr->allocate (size);
}
friend
void
asio_handler_deallocate (
void* p, std::size_t size, shared_handler* h)
{
return h->m_ptr->deallocate (p, size);
}
friend
bool
asio_handler_is_continuation (
shared_handler* h)
{
return h->m_ptr->is_continuation ();
}
};
//------------------------------------------------------------------------------
namespace detail {
template <
class Signature
>
struct is_shared_handler <
shared_handler <Signature>
> : public std::true_type
{
};
}
//------------------------------------------------------------------------------
template <class T>
class shared_handler_allocator
{
private:
template <class U>
friend class shared_handler_allocator;
std::shared_ptr <shared_handler_wrapper_base> m_ptr;
public:
typedef T value_type;
typedef T* pointer;
shared_handler_allocator() = delete;
template <class Signature>
shared_handler_allocator (
shared_handler <Signature> const& handler)
: m_ptr (handler.m_ptr)
{
}
template <class U>
shared_handler_allocator (
shared_handler_allocator <U> const& other)
: m_ptr (other.m_ptr)
{
}
pointer
allocate (std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
return static_cast <pointer> (
m_ptr->allocate (size));
}
void
deallocate (pointer p, std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
m_ptr->deallocate (p, size);
}
friend
bool
operator== (shared_handler_allocator const& lhs,
shared_handler_allocator const& rhs)
{
return lhs.m_ptr == rhs.m_ptr;
}
friend
bool
operator!= (shared_handler_allocator const& lhs,
shared_handler_allocator const& rhs)
{
return ! (lhs == rhs);
}
};
}
}
#endif

View File

@@ -17,33 +17,42 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_SOCKETS_SOCKETBASE_H_INCLUDED
#define BEAST_ASIO_SOCKETS_SOCKETBASE_H_INCLUDED
#include "BeastConfig.h"
/** Common implementation details for Socket and related classes.
Normally you wont need to use this.
*/
struct SocketBase
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../bind_handler.h"
#include <functional>
namespace beast {
namespace asio {
class bind_handler_Tests : public UnitTest
{
public:
typedef boost::system::error_code error_code;
static void foo (int)
{
}
/** The error returned when a pure virtual is called.
This is mostly academic since a pure virtual call generates
a fatal error but in case that gets disabled, this will at
least return a suitable error code.
*/
static error_code pure_virtual_error ();
void runTest()
{
beginTestCase ("call");
/** Convenience for taking a reference and returning the error_code. */
static error_code pure_virtual_error (error_code& ec,
char const* fileName, int lineNumber);
auto f (bind_handler (std::bind (&foo, std::placeholders::_1),
42));
/** Called when a function doesn't support the interface. */
static void pure_virtual_called (char const* fileName, int lineNumber);
f();
/** Called when synchronous functions without error parameters get an error. */
static void throw_error (error_code const& ec, char const* fileName, int lineNumber);
pass();
}
bind_handler_Tests() : UnitTest ("bind_handler", "beast", runManual)
{
}
};
#endif
static bind_handler_Tests bind_handler_tests;
}
}

View File

@@ -0,0 +1,239 @@
//------------------------------------------------------------------------------
/*
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.
*/
//==============================================================================
#include "BeastConfig.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../shared_handler.h"
// Disables is_constructible tests for std::function
// Visual Studio std::function fails the is_constructible tests
#ifndef BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
# ifdef _MSC_VER
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 1
# else
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 0
# endif
#endif
namespace beast {
class shared_handler_Tests : public UnitTest
{
public:
struct test_results
{
bool call;
bool invoke;
bool alloc;
bool dealloc;
bool cont;
test_results ()
: call (false)
, invoke (false)
, alloc (false)
, dealloc (false)
, cont (false)
{
}
};
struct test_handler
{
std::reference_wrapper <test_results> results;
explicit test_handler (test_results& results_)
: results (results_)
{
}
void operator() ()
{
results.get().call = true;
}
template <class Function>
friend void asio_handler_invoke (
Function& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
template <class Function>
friend void asio_handler_invoke (
Function const& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
friend void* asio_handler_allocate (
std::size_t size, test_handler* h)
{
h->results.get().alloc = true;
return boost::asio::asio_handler_allocate (size);
}
friend void asio_handler_deallocate (
void* p, std::size_t size, test_handler* h)
{
h->results.get().dealloc = true;
boost::asio::asio_handler_deallocate (p, size);
}
friend bool asio_handler_is_continuation (
test_handler* h)
{
h->results.get().cont = true;
return true;
}
};
struct test_invokable
{
bool call;
test_invokable ()
: call (false)
{
}
void operator() ()
{
call = true;
}
};
template <class Handler>
bool async_op (Handler&& handler)
{
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
handler();
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
return boost_asio_handler_cont_helpers::is_continuation (handler);
}
void virtual_async_op (asio::shared_handler <void(void)> handler)
{
async_op (handler);
}
void runTest()
{
beginTestCase ("hooks");
#if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
static_assert (! std::is_constructible <
std::function <void(void)>, int&&>::value,
"Cannot construct std::function from int&&");
static_assert (! std::is_constructible <
std::function <void(void)>, int>::value,
"Cannot construct std::function from int");
static_assert (! std::is_constructible <
asio::shared_handler <void(void)>, int>::value,
"Cannot construct shared_handler from int");
#endif
static_assert (std::is_constructible <
asio::shared_handler <void(int)>,
asio::shared_handler <void(int)>>::value,
"Should construct <void(int)> from <void(int)>");
static_assert (! std::is_constructible <
asio::shared_handler <void(int)>,
asio::shared_handler <void(void)>>::value,
"Can't construct <void(int)> from <void(void)>");
// Hooks called when using the raw handler
{
test_results r;
test_handler h (r);
async_op (h);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
expect (r.invoke);
expect (f.call);
}
// Use of std::function shows the hooks not getting called
{
test_results r;
std::function <void(void)> fh ((test_handler) (r));
async_op (fh);
expect (r.call);
unexpected (r.alloc);
unexpected (r.dealloc);
unexpected (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), fh);
unexpected (r.invoke);
expect (f.call);
}
// Make sure shared_handler calls the hooks
{
test_results r;
asio::shared_handler <void(void)> sh ((test_handler)(r));
async_op (sh);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), sh);
expect (r.invoke);
expect (f.call);
}
// Make sure shared_handler via implicit conversion calls hooks
{
test_results r;
test_handler h (r);
virtual_async_op ((test_handler) (r));
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
}
}
shared_handler_Tests() : UnitTest ("shared_handler", "beast")
{
}
};
static shared_handler_Tests shared_handler_tests;
}

View File

@@ -0,0 +1,287 @@
//------------------------------------------------------------------------------
/*
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.
*/
//==============================================================================
#include "BeastConfig.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "../wrap_handler.h"
#include <boost/version.hpp>
#include <boost/bind.hpp>
#include <functional>
#include <memory>
namespace beast {
namespace asio {
//------------------------------------------------------------------------------
// Displays the order of destruction of parameters in the bind wrapper
//
class boost_bind_Tests : public UnitTest
{
public:
struct Result
{
std::string text;
void push_back (std::string const& s)
{
if (! text.empty())
text += ", ";
text += s;
}
};
struct Payload
{
std::reference_wrapper <Result> m_result;
std::string m_name;
explicit Payload (Result& result, std::string const& name)
: m_result (result)
, m_name (name)
{
}
~Payload ()
{
m_result.get().push_back (m_name);
}
};
struct Arg
{
std::shared_ptr <Payload> m_payload;
Arg (Result& result, std::string const& name)
: m_payload (std::make_shared <Payload> (result, name))
{
}
};
static void foo (Arg const&, Arg const&, Arg const&)
{
}
void runTest()
{
beginTestCase ("order");
{
Result r;
{
boost::bind (&foo,
Arg (r, "one"),
Arg (r, "two"),
Arg (r, "three"));
}
logMessage (std::string ("boost::bind (") + r.text + ")");
}
{
Result r;
{
std::bind (&foo,
Arg (r, "one"),
Arg (r, "two"),
Arg (r, "three"));
}
logMessage (std::string ("std::bind (") + r.text + ")");
}
pass();
}
boost_bind_Tests() : UnitTest ("bind", "beast", runManual)
{
}
};
static boost_bind_Tests boost_bind_tests;
//------------------------------------------------------------------------------
class wrap_handler_handler_Tests : public UnitTest
{
public:
struct test_results
{
bool call;
bool invoke;
bool alloc;
bool dealloc;
bool cont;
test_results ()
: call (false)
, invoke (false)
, alloc (false)
, dealloc (false)
, cont (false)
{
}
};
struct test_handler
{
std::reference_wrapper <test_results> results;
explicit test_handler (test_results& results_)
: results (results_)
{
}
void operator() ()
{
results.get().call = true;
}
template <class Function>
friend void asio_handler_invoke (
Function& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
template <class Function>
friend void asio_handler_invoke (
Function const& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
friend void* asio_handler_allocate (
std::size_t, test_handler* h)
{
h->results.get().alloc = true;
return nullptr;
}
friend void asio_handler_deallocate (
void*, std::size_t, test_handler* h)
{
h->results.get().dealloc = true;
}
friend bool asio_handler_is_continuation (
test_handler* h)
{
h->results.get().cont = true;
return true;
}
};
struct test_invokable
{
bool call;
test_invokable ()
: call (false)
{
}
void operator() ()
{
call = true;
}
};
template <class Handler>
bool async_op (Handler&& handler)
{
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
(handler)();
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
return boost_asio_handler_cont_helpers::is_continuation (handler);
}
void runTest()
{
beginTestCase ("hooks");
// Hooks called when using the raw handler
{
test_results r;
test_handler h (r);
async_op (h);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
expect (r.invoke);
expect (f.call);
}
// Use of boost::bind shows the hooks not getting called
{
test_results r;
test_handler h (r);
auto b (std::bind (&test_handler::operator(), &h));
async_op (b);
expect (r.call);
unexpected (r.alloc);
unexpected (r.dealloc);
unexpected (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), b);
unexpected (r.invoke);
expect (f.call);
}
// Make sure the wrapped handler calls the hooks
{
test_results r;
test_handler h (r);
auto w (wrap_handler (
std::bind (&test_handler::operator(), test_handler(r)), h));
async_op (w);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), w);
expect (r.invoke);
expect (f.call);
}
}
wrap_handler_handler_Tests() : UnitTest ("wrap_handler", "beast")
{
}
};
static wrap_handler_handler_Tests wrap_handler_handler_tests;
}
}

176
beast/asio/wrap_handler.h Normal file
View 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_ASIO_WRAP_HANDLER_H_INCLUDED
#define BEAST_ASIO_WRAP_HANDLER_H_INCLUDED
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <type_traits>
#include <utility>
namespace beast {
namespace asio {
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4512) // assignment operator could not be generated
#endif
namespace detail {
/** A handler which wraps another handler using a specfic context.
The handler is invoked with the same io_service execution guarantees
as the provided context.
@note A copy of Context is made.
*/
template <class Handler, class Context>
class wrapped_handler
{
private:
Handler m_handler;
Context m_context;
bool m_continuation;
// If this goes off, consider carefully what the intent is.
static_assert (! std::is_reference <Handler>::value,
"Handler should not be a reference type");
public:
wrapped_handler (bool continuation, Handler&& handler, Context context)
: m_handler (std::move (handler))
, m_context (context)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (context))
{
}
wrapped_handler (bool continuation, Handler const& handler, Context context)
: m_handler (handler)
, m_context (context)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (context))
{
}
template <class... Args>
void
operator() (Args&&... args)
{
m_handler (std::forward <Args> (args)...);
}
template <class... Args>
void
operator() (Args&&... args) const
{
m_handler (std::forward <Args> (args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function& f, wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_context);
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f, wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_context);
}
friend
void*
asio_handler_allocate (std::size_t size, wrapped_handler* h)
{
return boost_asio_handler_alloc_helpers::
allocate (size, h->m_context);
}
friend
void
asio_handler_deallocate (void* p, std::size_t size, wrapped_handler* h)
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, h->m_context);
}
friend
bool
asio_handler_is_continuation (wrapped_handler* h)
{
return h->m_continuation;
}
};
}
//------------------------------------------------------------------------------
// Tag for dispatching wrap_handler with is_continuation == true
enum continuation_t
{
continuation
};
/** Returns a wrapped handler so it executes within another context.
The handler is invoked with the same io_service execution guarantees
as the provided context. The handler will be copied if necessary.
@note A copy of Context is made.
*/
/** @{ */
template <class DeducedHandler, class Context>
detail::wrapped_handler <
std::remove_reference_t <DeducedHandler>,
Context
>
wrap_handler (DeducedHandler&& handler, Context const& context,
bool continuation = false)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
return detail::wrapped_handler <Handler, Context> (continuation,
std::forward <DeducedHandler> (handler), context);
}
template <class DeducedHandler, class Context>
detail::wrapped_handler <
std::remove_reference_t <DeducedHandler>,
Context
>
wrap_handler (continuation_t, DeducedHandler&& handler,
Context const& context)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
return detail::wrapped_handler <Handler, Context> (true,
std::forward <DeducedHandler> (handler), context);
}
/** @} */
}
}
#endif

View File

@@ -17,26 +17,30 @@
*/
//==============================================================================
boost::system::error_code SocketBase::pure_virtual_error ()
#ifndef BEAST_BOOST_GET_POINTER_H_INCLUDED
#define BEAST_BOOST_GET_POINTER_H_INCLUDED
#include <boost/get_pointer.hpp>
// Boost 1.55 incorrectly defines BOOST_NO_CXX11_SMART_PTR
// when building with clang 3.4 and earlier. This workaround
// gives beast its own overloads.
#ifdef BOOST_NO_CXX11_SMART_PTR
#include <memory>
namespace beast {
template <class T>
T* get_pointer (std::unique_ptr<T> const& p)
{
return boost::system::errc::make_error_code (
boost::system::errc::function_not_supported);
return p.get();
}
boost::system::error_code SocketBase::pure_virtual_error (error_code& ec,
char const* fileName, int lineNumber)
template <class T>
T* get_pointer (std::shared_ptr<T> const& p)
{
pure_virtual_called (fileName, lineNumber);
return ec = pure_virtual_error ();
return p.get();
}
}
#endif
void SocketBase::pure_virtual_called (char const* fileName, int lineNumber)
{
Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber);
}
void SocketBase::throw_error (error_code const& ec, char const* fileName, int lineNumber)
{
if (ec)
Throw (boost::system::system_error (ec), fileName, lineNumber);
}
#endif

View File

@@ -27,13 +27,11 @@
namespace std {
#if ! BEAST_NO_CXX14_MAKE_UNIQUE
template <class T, class... Args>
std::unique_ptr <T> make_unique (Args&&... args)
{
return std::unique_ptr <T> (new T (std::forward <Args> (args)...));
}
#endif
}

View File

@@ -19,10 +19,10 @@
#include "../ParsedURL.h"
#include "http-parser/http_parser.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
#include "http_parser.h"
namespace beast {
ParsedURL::ParsedURL ()

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
/*
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_HTTP_HTTP_PARSER_H_INCLUDED
#define BEAST_HTTP_HTTP_PARSER_H_INCLUDED
#include "BeastConfig.h"
// Wraps the C-language joyent http parser header in our namespace
namespace beast {
#include "http-parser/http_parser.h"
}
#endif

View File

@@ -62,7 +62,7 @@ namespace is_call_possible_detail
}
#define BEAST_DEFINE_HAS_MEMBER_FUNCTION(trait_name, member_function_name) \
template<typename T, typename Signature> class trait_name; \
template<typename T, typename IsCallPossibleSignature> class trait_name; \
\
template<typename T, typename Result> \
class trait_name<T, Result(void)> \
@@ -160,7 +160,7 @@ struct trait_name##_detail
BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \
}; \
\
template <typename T, typename Signature> \
template <typename T, typename IsCallPossibleSignature> \
struct trait_name \
{ \
private: \
@@ -261,7 +261,8 @@ struct trait_name
}; \
\
public: \
static const bool value = impl<trait_name##_detail::has_member<T,Signature>::value, Signature>::value; \
static const bool value = impl<trait_name##_detail::template has_member<T,IsCallPossibleSignature>::value, \
IsCallPossibleSignature>::value; \
}
}

View File

@@ -1,712 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ABSTRACTHANDLER_H_INCLUDED
#define BEAST_ASIO_ABSTRACTHANDLER_H_INCLUDED
namespace beast {
namespace detail {
struct AbstractHandlerCallBase : SharedObject
{
//typedef SharedFunction <void(void),
// AbstractHandlerAllocator <char> > invoked_type;
typedef SharedFunction <void(void)> invoked_type;
virtual void* allocate (std::size_t size) = 0;
virtual void deallocate (void* p, std::size_t size) = 0;
virtual bool is_continuation () = 0;
virtual void invoke (invoked_type& invoked) = 0;
template <typename Function>
void invoke (BEAST_MOVE_ARG(Function) f)
{
invoked_type invoked (BEAST_MOVE_CAST(Function)(f)
//, AbstractHandlerAllocator<char>(this)
);
invoke (invoked);
}
};
/*
template <typename T>
struct AbstractHandlerAllocator
{
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef T const* const_pointer;
typedef T const& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
AbstractHandlerAllocator (AbstractHandler* handler) noexcept
: m_ptr (handler)
{
}
AbstractHandlerAllocator (SharedPtr <AbstractHandler> const& ptr) noexcept
: m_ptr (ptr)
{
}
template <typename U>
AbstractHandlerAllocator (AbstractHandlerAllocator <U> const& other)
: m_ptr (other.m_ptr)
{
}
template <typename U>
struct rebind
{
typedef AbstractHandlerAllocator <U> other;
};
pointer address (reference x) const
{
return &x;
}
const_pointer address (const_reference x) const
{
return &x;
}
pointer allocate (size_type n) const
{
size_type const bytes = n * sizeof (value_type);
return static_cast <pointer> (m_ptr->allocate (bytes));
}
void deallocate (pointer p, size_type n) const
{
size_type const bytes = n * sizeof (value_type);
m_ptr->deallocate (p, bytes);
}
size_type max_size () const noexcept
{
return std::numeric_limits <size_type>::max () / sizeof (value_type);
}
void construct (pointer p, const_reference val) const
{
new ((void *)p) value_type (val);
}
void destroy (pointer p) const
{
p->~value_type ();
}
private:
template <typename>
friend struct AbstractHandlerAllocator;
friend class AbstractHandler;
SharedPtr <AbstractHandler> m_ptr;
};
*/
}
/** A reference counted, abstract completion handler. */
template <typename Signature, class Allocator = std::allocator <char> >
struct AbstractHandler;
//------------------------------------------------------------------------------
// arity 0
template <class R, class A>
struct AbstractHandler <R (void), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() () = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (BEAST_MOVE_ARG(H) h, A a = A ())
: m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a)
{ }
R operator()()
{ return (m_h)(); }
R operator()() const
{ return (m_h)(); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (BEAST_MOVE_CAST(H)(h), a))
{ }
R operator() ()
{ return (*m_call)(); }
R operator() () const
{ return (*m_call)(); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (void), A>* handler)
{
return handler->allocate (size);
}
template <class R, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (void), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (void), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (void), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
//------------------------------------------------------------------------------
// arity 1
template <class R, class P1, class A>
struct AbstractHandler <R (P1), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() (P1) = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (H h, A a = A ())
: m_h (h)
, m_alloc (a)
{
}
R operator()(P1 p1)
{ return (m_h)(p1); }
R operator()(P1 p1) const
{ return (m_h)(p1); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (H h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (h, a))
{
}
R operator() (P1 p1)
{ return (*m_call)(p1); }
R operator() (P1 p1) const
{ return (*m_call)(p1); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class P1, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (P1), A>* handler)
{
return handler->allocate (size);
}
template <class R, class P1, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (P1), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class P1, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (P1), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class P1, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (P1), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
//------------------------------------------------------------------------------
// arity 2
template <class R, class P1, class P2, class A>
struct AbstractHandler <R (P1, P2), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() (P1, P2) = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (BEAST_MOVE_ARG(H) h, A a = A ())
: m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a)
{ }
R operator()(P1 p1, P2 p2)
{ return (m_h)(p1, p2); }
R operator()(P1 p1, P2 p2) const
{ return (m_h)(p1, p2); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (BEAST_MOVE_CAST(H)(h), a))
{ }
R operator() (P1 p1, P2 p2)
{ return (*m_call)(p1, p2); }
R operator() (P1 p1, P2 p2) const
{ return (*m_call)(p1, p2); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class P1, class P2, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (P1, P2), A>* handler)
{
return handler->allocate (size);
}
template <class R, class P1, class P2, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (P1, P2), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class P1, class P2, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (P1, P2), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class P1, class P2, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (P1, P2), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
//------------------------------------------------------------------------------
// arity 3
template <class R, class P1, class P2, class P3, class A>
struct AbstractHandler <R (P1, P2, P3), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() (P1, P2, P3) = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (BEAST_MOVE_ARG(H) h, A a = A ())
: m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a)
{ }
R operator()(P1 p1, P2 p2, P3 p3)
{ return (m_h)(p1, p2, p3); }
R operator()(P1 p1, P2 p2, P3 p3) const
{ return (m_h)(p1, p2, p3); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (BEAST_MOVE_CAST(H)(h), a))
{ }
R operator() (P1 p1, P2 p2, P3 p3)
{ return (*m_call)(p1, p2, p3); }
R operator() (P1 p1, P2 p2, P3 p3) const
{ return (*m_call)(p1, p2, p3); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class P1, class P2, class P3, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (P1, P2, P3), A>* handler)
{
return handler->allocate (size);
}
template <class R, class P1, class P2, class P3, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (P1, P2, P3), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class P1, class P2, class P3, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (P1, P2, P3), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class P1, class P2, class P3, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (P1, P2, P3), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
//------------------------------------------------------------------------------
// arity 4
template <class R, class P1, class P2, class P3, class P4, class A>
struct AbstractHandler <R (P1, P2, P3, P4), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() (P1, P2, P3, P4) = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (BEAST_MOVE_ARG(H) h, A a = A ())
: m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a)
{ }
R operator()(P1 p1, P2 p2, P3 p3, P4 p4)
{ return (m_h)(p1, p2, p3, p4); }
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const
{ return (m_h)(p1, p2, p3, p4); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (BEAST_MOVE_CAST(H)(h), a))
{ }
R operator() (P1 p1, P2 p2, P3 p3, P4 p4)
{ return (*m_call)(p1, p2, p3, p4); }
R operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
{ return (*m_call)(p1, p2, p3, p4); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class P1, class P2, class P3, class P4, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (P1, P2, P3, P4), A>* handler)
{
return handler->allocate (size);
}
template <class R, class P1, class P2, class P3, class P4, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (P1, P2, P3, P4), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class P1, class P2, class P3, class P4, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (P1, P2, P3, P4), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class P1, class P2, class P3, class P4, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (P1, P2, P3, P4), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
//------------------------------------------------------------------------------
// arity 5
template <class R, class P1, class P2, class P3, class P4, class P5, class A>
struct AbstractHandler <R (P1, P2, P3, P4, P5), A>
{
typedef R result_type;
struct Call : detail::AbstractHandlerCallBase
{ virtual R operator() (P1, P2, P3, P4, P5) = 0; };
template <typename H>
struct CallType : public Call
{
typedef typename A:: template rebind <CallType <H> >::other Allocator;
CallType (BEAST_MOVE_ARG(H) h, A a = A ())
: m_h (BEAST_MOVE_CAST(H)(h)), m_alloc (a)
{ }
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
{ return (m_h)(p1, p2, p3, p4, p5); }
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
{ return (m_h)(p1, p2, p3, p4, p5); }
void* allocate (std::size_t size)
{ return boost_asio_handler_alloc_helpers::allocate(size, m_h); }
void deallocate (void* pointer, std::size_t size)
{ boost_asio_handler_alloc_helpers::deallocate( pointer, size, m_h); }
bool is_continuation ()
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
{ return boost_asio_handler_cont_helpers::is_continuation(m_h); }
#else
{ return false; }
#endif
void invoke (typename detail::AbstractHandlerCallBase::invoked_type& invoked)
{ boost_asio_handler_invoke_helpers::invoke <
typename detail::AbstractHandlerCallBase::invoked_type, H> (invoked, m_h); }
private:
H m_h;
Allocator m_alloc;
};
template <typename H>
AbstractHandler (BEAST_MOVE_ARG(H) h, A a = A ())
: m_call (new (
typename A:: template rebind <CallType <H> >::other (a)
.allocate (1)) CallType <H> (BEAST_MOVE_CAST(H)(h), a))
{ }
R operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
{ return (*m_call)(p1, p2, p3, p4, p5); }
R operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
{ return (*m_call)(p1, p2, p3, p4, p5); }
void* allocate (std::size_t size) const { return m_call->allocate(size); }
void deallocate (void* pointer, std::size_t size) const { m_call->deallocate(pointer,size); }
bool is_continuation () const { return m_call->is_continuation(); }
template <typename Function>
void invoke (Function& function) const
{
m_call->invoke(function);
}
template <typename Function>
void invoke (Function const& function) const
{
m_call->invoke(function);
}
private:
SharedPtr <Call> m_call;
};
template <class R, class P1, class P2, class P3, class P4, class P5, class A>
void* asio_handler_allocate (std::size_t size,
AbstractHandler <R (P1, P2, P3, P4, P5), A>* handler)
{
return handler->allocate (size);
}
template <class R, class P1, class P2, class P3, class P4, class P5, class A>
void asio_handler_deallocate (void* pointer, std::size_t size,
AbstractHandler <R (P1, P2, P3, P4, P5), A>* handler)
{
handler->deallocate (pointer, size);
}
template <class R, class P1, class P2, class P3, class P4, class P5, class A>
bool asio_handler_is_continuation(
AbstractHandler <R (P1, P2, P3, P4, P5), A>* handler)
{
return handler->is_continuation();
}
template <typename Function, class R, class P1, class P2, class P3, class P4, class P5, class A>
void asio_handler_invoke (BEAST_MOVE_ARG(Function) function,
AbstractHandler <R (P1, P2, P3, P4, P5), A>* handler)
{
handler->invoke (BEAST_MOVE_CAST(Function)(function));
}
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
#define BEAST_ASIO_ASYNCOBJECT_H_INCLUDED
namespace beast {
namespace asio {
/** Mix-in to track when all pending I/O is complete.
Derived classes must be callable with this signature:
void asyncHandlersComplete()
@@ -80,4 +83,7 @@ private:
Atomic <int> m_pending;
};
}
}
#endif

View File

@@ -1,98 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ASYNC_COMPOSEDASYNCOPERATION_H_INCLUDED
#define BEAST_ASIO_ASYNC_COMPOSEDASYNCOPERATION_H_INCLUDED
/** Base class for creating composed asynchronous operations.
The composed operation will have its operator() overloads called with
the same context and execution safety guarantees as the original
SharedHandler.
*/
class ComposedAsyncOperation : public SharedHandler
{
protected:
/** Construct the composed operation.
The composed operation will execute in the context of the
SharedHandler. A reference to the SharedHandler is maintained
for the lifetime of the composed operation.
*/
explicit ComposedAsyncOperation (SharedHandlerPtr const& ptr)
: m_ptr (ptr)
{
// Illegal to do anything with handler here, because
// usually it hasn't been assigned by the derived class yet.
}
~ComposedAsyncOperation ()
{
}
void invoke (invoked_type& invoked)
{
boost_asio_handler_invoke_helpers::
invoke (invoked, *m_ptr);
}
void* allocate (std::size_t size)
{
return boost_asio_handler_alloc_helpers::
allocate (size, *m_ptr);
}
void deallocate (void* p, std::size_t size)
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, *m_ptr);
}
/** Override this function as needed.
Usually you will logical-and your own continuation condition. In
the following example, isContinuing is a derived class member:
@code
bool derived::is_continuation ()
{
bool const ourResult = this->isContinuing ()
return ourResult || ComposedAsyncOperation <Handler>::is_contiation ();
}
@endcode
*/
bool is_continuation ()
{
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
return boost_asio_handler_cont_helpers::
is_continuation (*m_ptr);
#else
return false;
#endif
}
void destroy () const
{
delete this;
}
private:
SharedHandlerPtr const m_ptr;
};
#endif

View File

@@ -1,108 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ASYNC_SHAREDHANDLER_H_INCLUDED
#define BEAST_ASIO_ASYNC_SHAREDHANDLER_H_INCLUDED
template <typename T>
struct SharedHandlerAllocator;
/** Reference counted wrapper that can hold any other boost::asio handler.
This object will match these signatures:
@code
void (void)
void (system::error_code)
void (system::error_code, std::size_t)
@endcode
If the underlying implementation does not support the signature,
undefined behavior will result.
Supports these concepts:
Destructible
*/
class SharedHandler : public SharedObject
{
protected:
typedef boost::system::error_code error_code;
typedef SharedFunction <void(void),
SharedHandlerAllocator <char> > invoked_type;
SharedHandler () noexcept { }
public:
// For asio::async_result<>
typedef void result_type;
typedef SharedPtr <SharedHandler> Ptr;
virtual void operator() ();
virtual void operator() (error_code const&);
virtual void operator() (error_code const&, std::size_t);
template <typename Function>
void invoke (BEAST_MOVE_ARG(Function) f);
virtual void invoke (invoked_type& invoked) = 0;
virtual void* allocate (std::size_t size) = 0;
virtual void deallocate (void* p, std::size_t size) = 0;
virtual bool is_continuation () = 0;
static void pure_virtual_called (char const* fileName, int lineNumber);
private:
template <typename Function>
friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler*);
friend void* asio_handler_allocate (std::size_t, SharedHandler*);
friend void asio_handler_deallocate (void*, std::size_t, SharedHandler*);
friend bool asio_handler_is_continuation (SharedHandler*);
};
//--------------------------------------------------------------------------
//
// Context execution guarantees
//
template <class Function>
void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler* handler)
{
handler->invoke (BOOST_ASIO_MOVE_CAST(Function)(f));
}
inline void* asio_handler_allocate (std::size_t size, SharedHandler* handler)
{
return handler->allocate (size);
}
inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandler* handler)
{
handler->deallocate (p, size);
}
inline bool asio_handler_is_continuation (SharedHandler* handler)
{
return handler->is_continuation ();
}
#endif

View File

@@ -1,123 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ASYNC_SHAREDHANDLERALLOCATOR_H_INCLUDED
#define BEAST_ASIO_ASYNC_SHAREDHANDLERALLOCATOR_H_INCLUDED
/** Custom Allocator using the allocation hooks from the Handler.
This class is compatible with std::allocator and can be used in any
boost interface which takes a template parameter of type Allocator.
This includes std::function and especially boost::asio::streambuf
and relatives. This is vastly more efficient in a variety of situations
especially during an upcall and when using stackful coroutines.
The Allocator holds a reference to the underlying SharedHandler. The
SharedHandler will not be destroyed as long as any Allocator is still
using it.
*/
template <typename T>
struct SharedHandlerAllocator
{
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef T const* const_pointer;
typedef T const& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
SharedHandlerAllocator (SharedHandler* handler) noexcept
: m_ptr (handler)
{
}
SharedHandlerAllocator (SharedHandlerPtr const& handler) noexcept
: m_ptr (handler)
{
}
template <typename U>
SharedHandlerAllocator (SharedHandlerAllocator <U> const& other)
: m_ptr (other.m_ptr)
{
}
template <typename U>
struct rebind
{
typedef SharedHandlerAllocator <U> other;
};
pointer address (reference x) const
{
return &x;
}
const_pointer address (const_reference x) const
{
return &x;
}
pointer allocate (size_type n) const
{
size_type const bytes = n * sizeof (value_type);
return static_cast <pointer> (m_ptr->allocate (bytes));
}
void deallocate (pointer p, size_type n) const
{
size_type const bytes = n * sizeof (value_type);
m_ptr->deallocate (p, bytes);
}
size_type max_size () const noexcept
{
return std::numeric_limits <size_type>::max () / sizeof (value_type);
}
void construct (pointer p, const_reference val) const
{
new ((void *)p) value_type (val);
}
void destroy (pointer p) const
{
p->~value_type ();
}
private:
template <typename>
friend struct SharedHandlerAllocator;
friend class SharedHandler;
SharedHandlerPtr m_ptr;
};
//------------------------------------------------------------------------------
template <typename Function>
void SharedHandler::invoke (BEAST_MOVE_ARG(Function) f)
{
// The allocator will hold a reference to the SharedHandler
// so that we can safely destroy the function object.
invoked_type invoked (f,SharedHandlerAllocator <char> (this));
invoke (invoked);
}
#endif

View File

@@ -1,326 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ASYNC_SHAREDHANDLERPTR_H_INCLUDED
#define BEAST_ASIO_ASYNC_SHAREDHANDLERPTR_H_INCLUDED
/** RAII container for a SharedHandler.
This object behaves exactly like a SharedHandler except that it
merely contains a shared pointer to the underlying SharedHandler.
All calls are forwarded to the underlying SharedHandler, and all
of the execution safety guarantees are met by forwarding them through
to the underlying SharedHandler.
*/
class SharedHandlerPtr
{
protected:
typedef boost::system::error_code error_code;
public:
// For asio::async_result<>
typedef void result_type;
/** Construct a null handler.
A null handler cannot be called. It can, however, be checked
for validity by calling isNull, and later assigned.
@see isNull, isNotNull
*/
inline SharedHandlerPtr ()
{
}
/** Construct from an existing SharedHandler.
Ownership of the handler is transferred to the container.
*/
inline SharedHandlerPtr (SharedHandler* handler)
: m_ptr (handler)
{
}
/** Construct a reference from an existing container. */
inline SharedHandlerPtr (SharedHandlerPtr const& other)
: m_ptr (other.m_ptr)
{
}
/** Assign a reference from an existing container. */
inline SharedHandlerPtr& operator= (SharedHandlerPtr const& other)
{
m_ptr = other.m_ptr;
return *this;
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Move-construct a reference from an existing container.
The other container is set to a null handler.
*/
inline SharedHandlerPtr (SharedHandlerPtr&& other)
: m_ptr (other.m_ptr)
{
other.m_ptr = nullptr;
}
/** Move-assign a reference from an existing container.
The other container is set to a null handler.
*/
inline SharedHandlerPtr& operator= (SharedHandlerPtr&& other)
{
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
return *this;
}
#endif
/** Returns true if the handler is a null handler. */
inline bool isNull () const
{
return m_ptr == nullptr;
}
/** Returns true if the handler is not a null handler. */
inline bool isNotNull () const
{
return m_ptr != nullptr;
}
/** Dereference the container.
This returns a reference to the underlying SharedHandler object.
*/
inline SharedHandler& operator* () const
{
return *m_ptr;
}
/** SharedHandler member access.
This lets you call functions directly on the SharedHandler.
*/
inline SharedHandler* operator-> () const
{
return m_ptr.get ();
}
/** Retrieve the SharedHandler as a Context.
This can be used for invoking functions in the context:
@code
template <Function>
void callOnHandler (Function f, SharedHandlerPtr ptr)
{
boost::asio_handler_invoke (f, ptr.get ());
}
@endcode
*/
inline SharedHandler* get () const
{
return m_ptr.get ();
}
/** Invoke the SharedHandler with signature void(void)
Normally this is called by a dispatcher, you shouldn't call it directly.
*/
inline void operator() () const
{
(*m_ptr)();
}
/** Invoke the SharedHandler with signature void(error_code)
Normally this is called by a dispatcher, you shouldn't call it directly.
*/
inline void operator() (error_code const& ec) const
{
(*m_ptr)(ec);
}
/** Invoke the SharedHandler with signature void(error_code, size_t)
Normally this is called by a dispatcher, you shouldn't call it directly.
*/
inline void operator() (error_code const& ec, std::size_t bytes_transferred) const
{
(*m_ptr)(ec, bytes_transferred);
}
private:
// These ensure that SharedHandlerPtr invocations adhere to
// the asio::io_service execution guarantees of the underlying SharedHandler.
//
template <typename Function>
friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr*);
friend void* asio_handler_allocate (std::size_t, SharedHandlerPtr*);
friend void asio_handler_deallocate (void*, std::size_t, SharedHandlerPtr*);
friend bool asio_handler_is_continuation (SharedHandlerPtr*);
SharedHandler::Ptr m_ptr;
};
//--------------------------------------------------------------------------
//
// Context execution guarantees
//
template <class Function>
void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr* ptr)
{
boost_asio_handler_invoke_helpers::
invoke <Function, SharedHandler>
(BOOST_ASIO_MOVE_CAST(Function)(f), *ptr->get ());
}
inline void* asio_handler_allocate (std::size_t size, SharedHandlerPtr* ptr)
{
return boost_asio_handler_alloc_helpers::
allocate <SharedHandler> (size, *ptr->get ());
}
inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandlerPtr* ptr)
{
boost_asio_handler_alloc_helpers::
deallocate <SharedHandler> (p, size, *ptr->get ());
}
inline bool asio_handler_is_continuation (SharedHandlerPtr* ptr)
{
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
return boost_asio_handler_cont_helpers::
is_continuation <SharedHandler> (*ptr->get ());
#else
return false;
#endif
}
//--------------------------------------------------------------------------
//
// Helpers
//
//--------------------------------------------------------------------------
// void(error_code)
template <typename Handler>
SharedHandlerPtr newErrorHandler (
BOOST_ASIO_MOVE_ARG(Handler) handler)
{
return newSharedHandlerContainer <ErrorSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(Handler)(handler));
}
// void(error_code, size_t)
template <typename Handler>
SharedHandlerPtr newTransferHandler (
BOOST_ASIO_MOVE_ARG(Handler) handler)
{
return newSharedHandlerContainer <TransferSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(Handler)(handler));
}
//--------------------------------------------------------------------------
// CompletionHandler
//
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html
//
template <typename CompletionHandler>
SharedHandlerPtr newCompletionHandler (
BOOST_ASIO_MOVE_ARG(CompletionHandler) handler)
{
return newSharedHandlerContainer <PostSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler));
}
// AcceptHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html
//
template <typename AcceptHandler>
SharedHandlerPtr newAcceptHandler (
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
{
return newSharedHandlerContainer <ErrorSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
}
// ConnectHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html
//
template <typename ConnectHandler>
SharedHandlerPtr newConnectHandler (
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
{
return newSharedHandlerContainer <ErrorSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
}
// ShutdownHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html
//
template <typename ShutdownHandler>
SharedHandlerPtr newShutdownHandler(
BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
{
return newSharedHandlerContainer <ErrorSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
}
// HandshakeHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html
//
template <typename HandshakeHandler>
SharedHandlerPtr newHandshakeHandler(
BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
{
return newSharedHandlerContainer <ErrorSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
}
// ReadHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html
//
template <typename ReadHandler>
SharedHandlerPtr newReadHandler(
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
return newSharedHandlerContainer <TransferSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
}
// WriteHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html
//
template <typename WriteHandler>
SharedHandlerPtr newWriteHandler(
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
return newSharedHandlerContainer <TransferSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
}
// BufferedHandshakeHandler
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html
//
template <typename BufferedHandshakeHandler>
SharedHandlerPtr newBufferedHandshakeHandler(
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
{
return newSharedHandlerContainer <TransferSharedHandlerType> (
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
}
#endif

View File

@@ -1,211 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_ASYNC_SHAREDHANDLERTYPE_H_INCLUDED
#define BEAST_ASIO_ASYNC_SHAREDHANDLERTYPE_H_INCLUDED
/** An instance of SharedHandler that wraps an existing Handler.
The wrapped handler will meet all the execution guarantees of
the original Handler object.
*/
template <typename Handler>
class SharedHandlerType : public SharedHandler
{
protected:
SharedHandlerType (std::size_t size,
BOOST_ASIO_MOVE_ARG(Handler) handler)
: m_size (size)
, m_handler (BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
~SharedHandlerType ()
{
}
void invoke (invoked_type& invoked)
{
boost_asio_handler_invoke_helpers::
invoke <invoked_type, Handler> (invoked, m_handler);
}
void* allocate (std::size_t size)
{
return boost_asio_handler_alloc_helpers::
allocate <Handler> (size, m_handler);
}
void deallocate (void* p, std::size_t size)
{
boost_asio_handler_alloc_helpers::
deallocate <Handler> (p, size, m_handler);
}
bool is_continuation ()
{
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
return boost_asio_handler_cont_helpers::
is_continuation <Handler> (m_handler);
#else
return false;
#endif
}
// Called by SharedObject hook to destroy the object. We need
// this because we allocated it using a custom allocator.
// Destruction is tricky, the algorithm is as follows:
//
// First we move-assign the handler to our stack. If the build
// doesn't support move-assignment it will be a copy, still ok.
// We convert 'this' to a pointer to the polymorphic base, to
// ensure that the following direct destructor call will reach
// the most derived class. Finally, we deallocate the memory
// using the handler that is local to the stack.
//
// For this to work we need to make sure regular operator delete
// is never called for our object (it's private). We also need
// the size from the original allocation, which we saved at
// the time of construction.
//
void destroy () const
{
Handler local (BOOST_ASIO_MOVE_CAST(Handler)(m_handler));
std::size_t const size (m_size);
SharedHandler* const shared (
const_cast <SharedHandler*> (
static_cast <SharedHandler const*>(this)));
shared->~SharedHandler ();
boost_asio_handler_alloc_helpers::
deallocate <Handler> (shared, size, local);
}
protected:
std::size_t const m_size;
Handler mutable m_handler;
};
//--------------------------------------------------------------------------
//
// A SharedHandlerType for this signature:
// void(void)
//
template <typename Handler>
class PostSharedHandlerType : public SharedHandlerType <Handler>
{
public:
PostSharedHandlerType (std::size_t size,
BOOST_ASIO_MOVE_ARG(Handler) handler)
: SharedHandlerType <Handler> (size,
BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
protected:
void operator() ()
{
this->m_handler ();
}
};
//--------------------------------------------------------------------------
//
// A SharedHandlerType for this signature:
// void(error_code)
//
template <typename Handler>
class ErrorSharedHandlerType : public SharedHandlerType <Handler>
{
public:
ErrorSharedHandlerType (std::size_t size,
BOOST_ASIO_MOVE_ARG(Handler) handler)
: SharedHandlerType <Handler> (size,
BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
protected:
void operator() (boost::system::error_code const& ec)
{
this->m_handler (ec);
}
};
//--------------------------------------------------------------------------
//
// A SharedHandlerType for this signature:
// void(error_code, size_t)
//
template <typename Handler>
class TransferSharedHandlerType : public SharedHandlerType <Handler>
{
public:
TransferSharedHandlerType (std::size_t size,
BOOST_ASIO_MOVE_ARG(Handler) handler)
: SharedHandlerType <Handler> (size,
BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
protected:
void operator() (boost::system::error_code const& ec,
std::size_t bytes_transferred)
{
this->m_handler (ec, bytes_transferred);
}
};
//--------------------------------------------------------------------------
//
// These specializations will make sure we don't do
// anything silly like wrap ourselves in our own wrapper...
//
#if 1
template <>
class PostSharedHandlerType <SharedHandler>
{
};
template <>
class ErrorSharedHandlerType <SharedHandler>
{
};
template <>
class TransferSharedHandlerType <SharedHandler>
{
};
#endif
//--------------------------------------------------------------------------
/** Construct a wrapped handler using the context's allocation hooks.
*/
template <template <typename> class Container, typename Handler>
Container <Handler>* newSharedHandlerContainer (BOOST_ASIO_MOVE_ARG(Handler) handler)
{
typedef Container <Handler> ContainerType;
std::size_t const size (sizeof (ContainerType));
Handler local (BOOST_ASIO_MOVE_CAST(Handler)(handler));
void* const p (boost_asio_handler_alloc_helpers::
allocate <Handler> (size, local));
return new (p) ContainerType (size, BOOST_ASIO_MOVE_CAST(Handler)(local));
}
#endif

View File

@@ -1,209 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_WRAPHANDLER_H_INCLUDED
#define BEAST_ASIO_WRAPHANDLER_H_INCLUDED
namespace beast {
namespace detail {
// Wrapper returned by wrapHandler, calls the Handler in the given Context
//
template <typename Handler, typename Context>
class WrappedHandler
{
public:
typedef void result_type; // for result_of
WrappedHandler (Handler& handler, Context const& context)
: m_handler (handler)
, m_context (context)
{
}
WrappedHandler (Handler const& handler, Context const& context)
: m_handler (handler)
, m_context (context)
{
}
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
WrappedHandler (WrappedHandler const& other)
: m_handler (other.m_handler)
, m_context (other.m_context)
{
}
WrappedHandler (BEAST_MOVE_ARG(WrappedHandler) other)
: m_handler (BEAST_MOVE_CAST(Handler)(other.m_handler))
, m_context (BEAST_MOVE_CAST(Context)(other.m_context))
{
}
#endif
Handler& handler()
{ return m_handler; }
Handler const& handler() const
{ return m_handler; }
Context& context()
{ return m_context; }
Context const& context() const
{ return m_context; }
void operator() ()
{ m_handler(); }
void operator() () const
{ m_handler(); }
template <class P1>
void operator() (P1 const& p1)
{ m_handler(p1); }
template <class P1>
void operator() (P1 const& p1) const
{ m_handler(p1); }
template <class P1, class P2>
void operator() (P1 const& p1, P2 const& p2)
{ m_handler(p1, p2); }
template <class P1, class P2>
void operator() (P1 const& p1, P2 const& p2) const
{ m_handler(p1, p2); }
template <class P1, class P2, class P3>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3)
{ m_handler(p1, p2, p3); }
template <class P1, class P2, class P3>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3) const
{ m_handler(p1, p2, p3); }
template <class P1, class P2, class P3, class P4>
void operator()
(P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4)
{ m_handler(p1, p2, p3, p4); }
template <class P1, class P2, class P3, class P4>
void operator()
(P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const
{ m_handler(p1, p2, p3, p4); }
template <class P1, class P2, class P3,
class P4, class P5>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5)
{ m_handler(p1, p2, p3, p4, p5); }
template <class P1, class P2, class P3,
class P4, class P5>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5) const
{ m_handler(p1, p2, p3, p4, p5); }
template <class P1, class P2, class P3,
class P4, class P5, class P6>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5, P6 const& p6)
{ m_handler(p1, p2, p3, p4, p5, p6); }
template <class P1, class P2, class P3,
class P4, class P5, class P6>
void operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5, P6 const& p6) const
{ m_handler(p1, p2, p3, p4, p5, p6); }
private:
Handler m_handler;
Context m_context;
};
//------------------------------------------------------------------------------
template <typename Handler, typename Context>
void* asio_handler_allocate (std::size_t size,
WrappedHandler <Handler, Context>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->context());
}
template <typename Handler, typename Context>
void asio_handler_deallocate (void* pointer, std::size_t size,
WrappedHandler <Handler, Context>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->context());
}
template <typename Handler, typename Context>
bool asio_handler_is_continuation(
WrappedHandler <Handler, Context>* this_handler)
{
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
return boost_asio_handler_cont_helpers::is_continuation(
this_handler->handler());
#else
return false;
#endif
}
template <typename Function, typename Handler, typename Context>
void asio_handler_invoke (Function& function,
WrappedHandler <Handler, Context>* handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, handler->context());
}
template <typename Function, typename Handler, typename Context>
void asio_handler_invoke (Function const& function,
WrappedHandler <Handler, Context>* handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, handler->context());
}
}
//------------------------------------------------------------------------------
/** Returns a handler that calls Handler using Context hooks.
This is useful when implementing composed asynchronous operations that
need to call their own intermediate handlers before issuing the final
completion to the original handler.
*/
template <typename Handler, typename Context>
detail::WrappedHandler <Handler, Context>
wrapHandler (
BEAST_MOVE_ARG(Handler) handler,
BEAST_MOVE_ARG(Context) context)
{
return detail::WrappedHandler <Handler, Context> (
BEAST_MOVE_CAST(Handler)(handler),
BEAST_MOVE_CAST(Context)(context));
}
}
#endif

View File

@@ -1,135 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_BUFFERSTYPE_H_INCLUDED
#define BEAST_ASIO_BUFFERSTYPE_H_INCLUDED
/** Storage for a BufferSequence.
Meets these requirements:
BufferSequence
ConstBufferSequence (when Buffer is mutable_buffer)
MutableBufferSequence (when Buffer is const_buffer)
*/
template <class Buffer>
class BuffersType
{
public:
typedef Buffer value_type;
typedef std::vector <Buffer> container_type;
typedef typename container_type::const_iterator const_iterator;
/** Construct a null buffer.
This is the equivalent of @ref asio::null_buffers.
*/
BuffersType ()
: m_size (0)
{
}
/** Construct from a container.
Ownership of the container is transferred, the caller's
value becomes undefined, but valid.
*/
explicit BuffersType (container_type& container)
: m_size (0)
{
m_buffers.swap (container);
for (typename container_type::const_iterator iter (m_buffers.begin ());
iter != m_buffers.end (); ++iter)
//m_size += iter->size ();
m_size += boost::asio::buffer_size (*iter);
}
/** Construct a BuffersType from an existing BufferSequence.
@see assign
*/
template <class BufferSequence>
BuffersType (BufferSequence const& buffers)
{
assign (buffers);
}
/** Assign a BuffersType from an existing BufferSequence.
@see assign
*/
template <class BufferSequence>
BuffersType <Buffer>& operator= (BufferSequence const& buffers)
{
return assign (buffers);
}
/** Assign a BuffersType from an existing BufferSequence
A copy is not made. The data is still owned by the original
BufferSequence object. This merely points to that data.
*/
template <class BufferSequence>
BuffersType <Buffer>& assign (BufferSequence const& buffers)
{
m_size = 0;
m_buffers.clear ();
m_buffers.reserve (std::distance (buffers.begin (), buffers.end ()));
for (typename BufferSequence::const_iterator iter (
buffers.begin ()); iter != buffers.end(); ++ iter)
{
//m_size += iter->size ();
m_size += boost::asio::buffer_size (*iter);
m_buffers.push_back (*iter);
}
return *this;
}
/** Determine the total size of all buffers.
This is faster than calling boost::asio::buffer_size.
*/
std::size_t size () const noexcept
{
return m_size;
}
const_iterator begin () const noexcept
{
return m_buffers.begin ();
}
const_iterator end () const noexcept
{
return m_buffers.end ();
}
private:
std::size_t m_size;
std::vector <Buffer> m_buffers;
};
//------------------------------------------------------------------------------
/** A single linear read-only buffer. */
typedef boost::asio::const_buffer ConstBuffer;
/** A single linear writable buffer. */
typedef boost::asio::mutable_buffer MutableBuffer;
/** Meets the requirements of ConstBufferSequence */
typedef BuffersType <ConstBuffer> ConstBuffers;
/** Meets the requirements of MutableBufferSequence */
typedef BuffersType <MutableBuffer> MutableBuffers;
#endif

View File

@@ -20,6 +20,11 @@
#ifndef BEAST_ASIO_BASICS_FIXEDINPUTBUFFER_H_INCLUDED
#define BEAST_ASIO_BASICS_FIXEDINPUTBUFFER_H_INCLUDED
#include "../../../beast/asio/buffer_sequence.h"
namespace beast {
namespace asio {
/** Represents a small, fixed size buffer.
This provides a convenient interface for doing a bytewise
verification/reject test on a handshake protocol.
@@ -164,7 +169,7 @@ protected:
template <typename ConstBufferSequence, typename Storage>
SizedCtorParams (ConstBufferSequence const& buffers, Storage& storage)
{
MutableBuffer buffer (boost::asio::buffer (storage));
boost::asio::mutable_buffer buffer (boost::asio::buffer (storage));
data = boost::asio::buffer_cast <uint8 const*> (buffer);
bytes = boost::asio::buffer_copy (buffer, buffers);
}
@@ -187,7 +192,10 @@ public:
private:
boost::array <uint8, Bytes> m_storage;
MutableBuffer m_buffer;
boost::asio::mutable_buffer m_buffer;
};
}
}
#endif

View File

@@ -17,6 +17,9 @@
*/
//==============================================================================
namespace beast {
namespace asio {
PeerRole::PeerRole (role_t role)
: m_role (role)
{
@@ -35,10 +38,13 @@ bool PeerRole::operator== (role_t role) const noexcept
}
#if 0
PeerRole::operator Socket::handshake_type () const noexcept
PeerRole::operator abstract_socket::handshake_type () const noexcept
{
if (m_role == server)
return Socket::server;
return Socket::client;
return abstract_socket::server;
return abstract_socket::client;
}
#endif
}
}

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_BASICS_PEERROLE_H_INCLUDED
#define BEAST_ASIO_BASICS_PEERROLE_H_INCLUDED
namespace beast {
namespace asio {
/** Identifies if the peer is a client or a server. */
struct PeerRole
{
@@ -37,4 +40,7 @@ private:
role_t m_role;
};
}
}
#endif

View File

@@ -17,6 +17,9 @@
*/
//==============================================================================
namespace beast {
namespace asio {
SSLContext::SSLContext (ContextType& context)
: m_context (context)
{
@@ -26,3 +29,5 @@ SSLContext::~SSLContext ()
{
}
}
}

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_BASICS_SSLCONTEXT_H_INCLUDED
#define BEAST_ASIO_BASICS_SSLCONTEXT_H_INCLUDED
namespace beast {
namespace asio {
/** Simple base class for passing a context around.
This lets derived classes hide their implementation from the headers.
*/
@@ -58,4 +61,7 @@ protected:
ContextType& m_context;
};
}
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_SHAREDARG_H_INCLUDED
#define BEAST_ASIO_SHAREDARG_H_INCLUDED
namespace beast {
namespace asio {
/** A container that turns T into a SharedObject.
We use this to manage the lifetime of objects passed to handlers.
*/
@@ -158,4 +161,7 @@ private:
SharedPtr <Arg> m_arg;
};
}
}
#endif

View File

@@ -23,18 +23,11 @@
#include "beast_asio.h"
namespace beast {
# include "../../beast/http/impl/http-parser/http_parser.h"
#include "async/SharedHandler.cpp"
# include "../../beast/http/impl/http_parser.h"
#include "basics/PeerRole.cpp"
#include "basics/SSLContext.cpp"
#include "sockets/SocketBase.cpp"
#include "sockets/Socket.cpp"
#include "protocol/HandshakeDetectLogicPROXY.cpp"
# include "http/HTTPParserImpl.h"
@@ -58,8 +51,6 @@ namespace beast {
#include "system/BoostUnitTests.cpp"
}
#include "http/HTTPParser.cpp"
#include "http/HTTPRequestParser.cpp"
#include "http/HTTPResponseParser.cpp"

View File

@@ -43,45 +43,19 @@
// This module requires boost and possibly OpenSSL
#include "system/BoostIncludes.h"
// Checking overrides replaces unimplemented stubs with pure virtuals
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 0
#endif
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_SOCKET_VIRTUAL = 0
#else
# define BEAST_SOCKET_VIRTUAL
#endif
#include "../../beast/Asio.h"
#include "../../beast/MPL.h"
#include "../../beast/Utility.h"
#include "../../beast/HTTP.h"
#include "async/AbstractHandler.h"
#include "async/WrapHandler.h"
namespace beast {
#include "../../beast/asio/IPAddressConversion.h"
// Order matters
# include "async/SharedHandler.h"
# include "async/SharedHandlerType.h"
# include "async/SharedHandlerPtr.h"
# include "async/ComposedAsyncOperation.h"
#include "async/SharedHandlerAllocator.h"
#include "async/AsyncObject.h"
# include "basics/BuffersType.h"
#include "basics/FixedInputBuffer.h"
#include "basics/PeerRole.h"
#include "basics/SSLContext.h"
#include "basics/SharedArg.h"
# include "sockets/SocketBase.h"
# include "sockets/Socket.h"
# include "sockets/SocketWrapper.h"
#include "sockets/SocketWrapperStrand.h"
# include "http/HTTPVersion.h"
# include "http/HTTPField.h"
# include "http/HTTPHeaders.h"
@@ -89,16 +63,12 @@ namespace beast {
# include "http/HTTPRequest.h"
# include "http/HTTPResponse.h"
}
# include "http/HTTPParser.h"
#include "http/HTTPRequestParser.h"
#include "http/HTTPResponseParser.h"
#include "http/HTTPClientType.h"
namespace beast {
# include "protocol/InputParser.h"
# include "protocol/HandshakeDetectLogic.h"
#include "protocol/HandshakeDetectLogicPROXY.h"
@@ -120,7 +90,5 @@ namespace beast {
#include "tests/TestPeerDetailsTcp.h"
#include "tests/PeerTest.h"
}
#endif

View File

@@ -17,6 +17,12 @@
*/
//==============================================================================
#include "../../../beast/asio/wrap_handler.h"
#include "../../../beast/asio/placeholders.h"
namespace beast {
namespace asio {
class HTTPClientType : public HTTPClientBase, public Uncopyable
{
public:
@@ -69,7 +75,7 @@ public:
}
void async_get (boost::asio::io_service& io_service, URL const& url,
AbstractHandler <void (result_type)> handler)
asio::shared_handler <void (result_type)> handler)
{
new Session (*this, io_service, url,
handler, m_timeoutSeconds, m_messageLimitBytes, m_bufferSize);
@@ -150,7 +156,6 @@ public:
class Session
: public SharedObject
, public AsyncObject <Session>
, public List <Session>::Node
{
public:
@@ -173,7 +178,7 @@ public:
boost::asio::deadline_timer m_timer;
resolver m_resolver;
socket m_socket;
AbstractHandler <void (result_type)> m_handler;
asio::shared_handler <void (result_type)> m_handler;
URL m_url;
boost::asio::ssl::context m_context;
@@ -184,7 +189,7 @@ public:
String m_get_string;
WaitableEvent m_done;
ScopedPointer <Socket> m_stream;
ScopedPointer <abstract_socket> m_stream;
struct State
{
@@ -204,7 +209,7 @@ public:
Session (HTTPClientType& owner,
boost::asio::io_service& io_service,
URL const& url,
AbstractHandler <void (result_type)> const& handler,
asio::shared_handler <void (result_type)> const& handler,
double timeoutSeconds,
std::size_t messageLimitBytes,
std::size_t bufferSize)
@@ -238,16 +243,14 @@ public:
boost::posix_time::milliseconds (
long (timeoutSeconds * 1000)));
m_timer.async_wait (m_strand.wrap (wrapHandler (
boost::bind (&Session::handle_timer, Ptr(this),
boost::asio::placeholders::error,
CompletionCounter(this)), m_handler)));
m_timer.async_wait (m_strand.wrap (asio::wrap_handler (
std::bind (&Session::handle_timer, Ptr(this),
asio::placeholders::error), m_handler)));
}
// Start the operation on an io_service thread
io_service.dispatch (m_strand.wrap (wrapHandler (
boost::bind (&Session::handle_start, Ptr(this),
CompletionCounter(this)), m_handler)));
io_service.dispatch (m_strand.wrap (asio::wrap_handler (
std::bind (&Session::handle_start, Ptr(this)), m_handler)));
}
~Session ()
@@ -258,8 +261,8 @@ public:
result = *state;
}
m_io_service.wrap (m_handler) (std::make_pair (
result.error, result.response));
m_io_service.post (bind_handler (m_handler,
std::make_pair (result.error, result.response)));
m_owner.remove (*this);
}
@@ -313,10 +316,9 @@ public:
m_buffer.getData (), m_buffer.getSize ());
m_stream->async_read_some (buf, m_strand.wrap (
wrapHandler (boost::bind (&Session::handle_read,
Ptr(this), boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
CompletionCounter(this)), m_handler)));
asio::wrap_handler (std::bind (&Session::handle_read,
Ptr(this), asio::placeholders::error,
asio::placeholders::bytes_transferred), m_handler)));
}
//----------------------------------------------------------------------
@@ -324,25 +326,19 @@ public:
// Completion handlers
//
// Called when there are no more pending i/o completions
void asyncHandlersComplete()
{
}
// Called when the operation starts
void handle_start (CompletionCounter)
void handle_start ()
{
query q (queryFromURL <query> (m_url));
m_resolver.async_resolve (q, m_strand.wrap (
wrapHandler (boost::bind (&Session::handle_resolve,
Ptr(this), boost::asio::placeholders::error,
boost::asio::placeholders::iterator,
CompletionCounter(this)), m_handler)));
asio::wrap_handler (std::bind (&Session::handle_resolve,
Ptr(this), asio::placeholders::error,
asio::placeholders::iterator), m_handler)));
}
// Called when the timer completes
void handle_timer (error_code ec, CompletionCounter)
void handle_timer (error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -358,7 +354,7 @@ public:
}
// Called when the resolver completes
void handle_resolve (error_code ec, iterator iter, CompletionCounter)
void handle_resolve (error_code ec, iterator iter)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -371,13 +367,12 @@ public:
resolver_entry const entry (*iter);
m_socket.async_connect (entry.endpoint (), m_strand.wrap (
wrapHandler (boost::bind (&Session::handle_connect,
Ptr(this), boost::asio::placeholders::error,
CompletionCounter(this)), m_handler)));
asio::wrap_handler (std::bind (&Session::handle_connect,
Ptr(this), asio::placeholders::error), m_handler)));
}
// Called when the connection attempt completes
void handle_connect (error_code ec, CompletionCounter)
void handle_connect (error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -391,25 +386,24 @@ public:
if (m_url.scheme () == "https")
{
typedef boost::asio::ssl::stream <socket&> ssl_stream;
m_stream = new SocketWrapper <ssl_stream> (m_socket, m_context);
m_stream = new socket_wrapper <ssl_stream> (m_socket, m_context);
/*
m_stream->set_verify_mode (
boost::asio::ssl::verify_peer |
boost::asio::ssl::verify_fail_if_no_peer_cert);
*/
m_stream->async_handshake (Socket::client, m_strand.wrap (
wrapHandler (boost::bind (&Session::handle_handshake,
Ptr(this), boost::asio::placeholders::error,
CompletionCounter(this)), m_handler)));
m_stream->async_handshake (abstract_socket::client, m_strand.wrap (
asio::wrap_handler (std::bind (&Session::handle_handshake,
Ptr(this), asio::placeholders::error), m_handler)));
return;
}
m_stream = new SocketWrapper <socket&> (m_socket);
handle_handshake (ec, CompletionCounter(this));
m_stream = new socket_wrapper <socket&> (m_socket);
handle_handshake (ec);
}
// Called when the SSL handshake completes
void handle_handshake (error_code ec, CompletionCounter)
void handle_handshake (error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -427,17 +421,16 @@ public:
"Connection: close\r\n\r\n";
boost::asio::async_write (*m_stream, stringBuffer (
m_get_string), m_strand.wrap (wrapHandler (
boost::bind (&Session::handle_write, Ptr(this),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
CompletionCounter(this)), m_handler)));
m_get_string), m_strand.wrap (asio::wrap_handler (
std::bind (&Session::handle_write, Ptr(this),
asio::placeholders::error,
asio::placeholders::bytes_transferred), m_handler)));
async_read_some ();
}
// Called when the write operation completes
void handle_write (error_code ec, std::size_t, CompletionCounter)
void handle_write (error_code ec, std::size_t)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -453,7 +446,7 @@ public:
}
void handle_read (error_code ec,
std::size_t bytes_transferred, CompletionCounter)
std::size_t bytes_transferred)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -499,14 +492,13 @@ public:
{
if (m_stream->needs_handshake ())
{
m_stream->async_shutdown (m_strand.wrap (wrapHandler (
boost::bind (&Session::handle_shutdown, Ptr(this),
boost::asio::placeholders::error,
CompletionCounter(this)), m_handler)));
m_stream->async_shutdown (m_strand.wrap (asio::wrap_handler (
std::bind (&Session::handle_shutdown,
Ptr(this), asio::placeholders::error), m_handler)));
}
else
{
handle_shutdown (error_code (), CompletionCounter(this));
handle_shutdown (error_code ());
}
return;
}
@@ -514,7 +506,7 @@ public:
async_read_some ();
}
void handle_shutdown (error_code ec, CompletionCounter)
void handle_shutdown (error_code ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
@@ -692,4 +684,5 @@ public:
static HTTPClientTests httpClientTests;
}
}

View File

@@ -20,9 +20,12 @@
#ifndef BEAST_ASIO_HTTPCLIENTTYPE_H_INCLUDED
#define BEAST_ASIO_HTTPCLIENTTYPE_H_INCLUDED
#include "../../../beast/asio/shared_handler.h"
#include <utility>
namespace beast {
namespace asio {
class HTTPClientBase
{
@@ -49,17 +52,8 @@ public:
Handler will be called with this signature:
void (result_type)
*/
template <typename Handler>
void async_get (boost::asio::io_service& io_service,
URL const& url, BEAST_MOVE_ARG(Handler) handler)
{
async_get (io_service, url,
AbstractHandler <void (result_type)> (
BEAST_MOVE_CAST(Handler)(handler)));
}
virtual void async_get (boost::asio::io_service& io_service,
URL const& url, AbstractHandler <void (result_type)> handler) = 0;
URL const& url, asio::shared_handler <void (result_type)> handler) = 0;
/** Cancel all pending asynchronous operations. */
virtual void cancel() = 0;
@@ -68,6 +62,7 @@ public:
virtual void wait() = 0;
};
}
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPField::HTTPField ()
{
}
@@ -49,3 +51,5 @@ String HTTPField::value () const
{
return m_value;
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPFIELD_H_INCLUDED
#define BEAST_ASIO_HTTPFIELD_H_INCLUDED
namespace beast {
/** A single header.
The header is a field/value pair.
Time complexity of copies is constant.
@@ -39,4 +41,6 @@ private:
String m_value;
};
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPHeaders::HTTPHeaders ()
{
}
@@ -84,3 +86,4 @@ String HTTPHeaders::toString () const
return s;
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPHEADERS_H_INCLUDED
#define BEAST_ASIO_HTTPHEADERS_H_INCLUDED
namespace beast {
/** A set of HTTP headers. */
class HTTPHeaders
{
@@ -68,4 +70,6 @@ private:
StringPairArray m_fields;
};
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPMessage::HTTPMessage (HTTPVersion const& version_,
StringPairArray& fields,
DynamicBuffer& body)
@@ -48,3 +50,5 @@ String HTTPMessage::toString () const
s << m_headers.toString ();
return s;
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
#define BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
namespace beast {
/** A complete HTTP message.
This provides the information common to all HTTP messages, including
@@ -60,4 +62,6 @@ private:
DynamicBuffer m_body;
};
}
#endif

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_HTTPPARSERIMPL_H_INCLUDED
#define BEAST_HTTPPARSERIMPL_H_INCLUDED
namespace beast {
class HTTPParserImpl
{
public:
@@ -266,4 +268,6 @@ private:
DynamicBuffer m_body;
};
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPRequest::HTTPRequest (
HTTPVersion const& version_,
StringPairArray& fields,
@@ -40,3 +42,4 @@ String HTTPRequest::toString () const
return s;
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPREQUEST_H_INCLUDED
#define BEAST_ASIO_HTTPREQUEST_H_INCLUDED
namespace beast {
class HTTPRequest : public HTTPMessage
{
public:
@@ -42,4 +44,6 @@ private:
unsigned short m_method;
};
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPResponse::HTTPResponse (
HTTPVersion const& version_,
StringPairArray& fields,
@@ -40,3 +42,4 @@ String HTTPResponse::toString () const
return s;
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
#define BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
namespace beast {
class HTTPResponse : public HTTPMessage
{
public:
@@ -42,4 +44,6 @@ private:
unsigned short m_status;
};
}
#endif

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
HTTPVersion::HTTPVersion ()
: m_major (0)
, m_minor (0)
@@ -91,3 +93,5 @@ bool HTTPVersion::operator<= (HTTPVersion const& rhs) const
return (m_major < rhs.m_major) ||
((m_major == rhs.m_major) && (m_minor <= rhs.m_minor));
}
}

View File

@@ -20,6 +20,8 @@
#ifndef BEAST_ASIO_HTTPVERSION_H_INCLUDED
#define BEAST_ASIO_HTTPVERSION_H_INCLUDED
namespace beast {
/** The HTTP version. This is the major.minor version number. */
class HTTPVersion
{
@@ -43,4 +45,6 @@ private:
unsigned short m_minor;
};
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGIC_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGIC_H_INCLUDED
namespace beast {
namespace asio {
class HandshakeDetectLogic
{
public:
@@ -138,4 +141,7 @@ private:
Logic m_logic;
};
}
}
#endif

View File

@@ -17,4 +17,8 @@
*/
//==============================================================================
namespace beast {
namespace asio {
}
}

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICPROXY_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICPROXY_H_INCLUDED
namespace beast {
namespace asio {
/** Handshake detector for the PROXY protcol
http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
@@ -156,4 +159,7 @@ private:
ProxyInfo m_info;
};
}
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
namespace beast {
namespace asio {
// Handshake for SSL 2
//
// http://tools.ietf.org/html/rfc5246#appendix-E.2
@@ -105,4 +108,7 @@ public:
}
};
}
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
namespace beast {
namespace asio {
// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
//
// http://www.ietf.org/rfc/rfc2246.txt
@@ -79,4 +82,7 @@ public:
}
};
}
}
#endif

View File

@@ -20,7 +20,16 @@
#ifndef BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTOR_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_HANDSHAKEDETECTOR_H_INCLUDED
//------------------------------------------------------------------------------
#include "../../../beast/boost/get_pointer.h"
#include "../../../beast/asio/bind_handler.h"
#include "../../../beast/asio/wrap_handler.h"
#include "../../../beast/asio/placeholders.h"
#include "../../../beast/asio/shared_handler.h"
#include <boost/asio/detail/handler_cont_helpers.hpp>
namespace beast {
namespace asio {
/** A wrapper to decode the handshake data on a Stream.
@@ -99,42 +108,35 @@ public:
DetectHandler must have this signature:
void(error_code)
*/
template <typename DetectHandler, typename Allocator>
void async_detect (Stream& stream,
boost::asio::basic_streambuf <Allocator>& buffer,
BOOST_ASIO_MOVE_ARG(DetectHandler) handler)
{
async_detect <Allocator> (stream, buffer, SharedHandlerPtr (
new ErrorSharedHandlerType <DetectHandler> (
BOOST_ASIO_MOVE_CAST(DetectHandler)(handler))));
}
template <typename Allocator>
void async_detect (Stream& stream,
boost::asio::basic_streambuf <Allocator>& buffer,
SharedHandlerPtr handler)
asio::shared_handler <void(error_code)> handler)
{
typedef AsyncOp <Allocator> OpType;
OpType* const op = new AsyncOp <Allocator> (
m_logic, stream, buffer, handler);
stream.get_io_service ().wrap (SharedHandlerPtr (op))
(error_code (), 0);
typedef AsyncOp <Allocator> Op;
auto const op (std::make_shared <Op> (std::ref (m_logic),
std::ref (stream), std::ref (buffer), std::cref (handler)));
//op->start();
stream.get_io_service().post (asio::wrap_handler (std::bind (
&Op::start, op), handler));
}
private:
template <typename Allocator>
struct AsyncOp : ComposedAsyncOperation
class AsyncOp
: public std::enable_shared_from_this <AsyncOp <Allocator>>
{
public:
typedef boost::asio::basic_streambuf <Allocator> BuffersType;
AsyncOp (HandshakeDetectLogicType <Logic>& logic, Stream& stream,
BuffersType& buffer, SharedHandlerPtr const& handler)
: ComposedAsyncOperation (handler)
, m_logic (logic)
BuffersType& buffer, asio::shared_handler <
void(error_code)> const& handler)
: m_logic (logic)
, m_stream (stream)
, m_buffer (buffer)
, m_handler (handler)
, m_running (false)
, m_continuation (false)
{
}
@@ -143,12 +145,19 @@ private:
{
}
void operator() (error_code const& ec_, size_t bytes_transferred)
void start()
{
m_running = true;
async_read_some (error_code(), 0);
}
error_code ec (ec_);
void on_read (error_code ec, size_t bytes_transferred)
{
m_continuation = true;
async_read_some (ec, bytes_transferred);
}
void async_read_some (error_code ec, size_t bytes_transferred)
{
if (! ec)
{
m_buffer.commit (bytes_transferred);
@@ -166,7 +175,11 @@ private:
typename BuffersType::mutable_buffers_type buffers (
m_buffer.prepare (needed - available));
m_stream.async_read_some (buffers, SharedHandlerPtr (this));
m_stream.async_read_some (buffers, asio::wrap_handler (
std::bind (&AsyncOp <Allocator>::on_read,
this->shared_from_this(), asio::placeholders::error,
asio::placeholders::bytes_transferred),
m_handler, m_continuation));
}
return;
@@ -177,30 +190,30 @@ private:
}
// Finalize with a call to the original handler.
m_stream.get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST (SharedHandlerPtr)(m_handler))
(ec);
}
bool is_continuation ()
if (m_continuation)
{
return m_running
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|| boost_asio_handler_cont_helpers::is_continuation (m_handler);
#endif
;
m_handler (ec);
return;
}
// Post, otherwise we would call the
// handler from the initiating function.
m_stream.get_io_service ().post (asio::bind_handler (
m_handler, ec));
}
private:
HandshakeDetectLogicType <Logic>& m_logic;
Stream& m_stream;
BuffersType& m_buffer;
SharedHandlerPtr m_handler;
bool m_running;
asio::shared_handler <void(error_code)> m_handler;
bool m_continuation;
};
private:
HandshakeDetectLogicType <Logic> m_logic;
};
}
}
#endif

View File

@@ -20,8 +20,10 @@
#ifndef BEAST_ASIO_HANDSHAKE_INPUTPARSER_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_INPUTPARSER_H_INCLUDED
namespace InputParser
{
namespace beast {
namespace asio {
namespace InputParser {
/** Tri-valued parsing state.
This is convertible to bool which means continue.
@@ -380,8 +382,9 @@ struct Get <IPv4Address>
}
};
//------------------------------------------------------------------------------
}
}
}
#endif

View File

@@ -20,6 +20,12 @@
#ifndef BEAST_ASIO_HANDSHAKE_PREFILLEDREADSTREAM_H_INCLUDED
#define BEAST_ASIO_HANDSHAKE_PREFILLEDREADSTREAM_H_INCLUDED
#include "../../../beast/cxx14/type_traits.h" // <type_traits>
#include <utility>
namespace beast {
namespace asio {
/** Front-ends a stream with a provided block of data.
When read operations are performed on this object, bytes will first be
@@ -29,25 +35,25 @@
Write operations are all simply passed through.
*/
template <typename Stream>
template <class Stream>
class PrefilledReadStream : public Uncopyable
{
protected:
typedef boost::system::error_code error_code;
void throw_error (error_code const& ec, char const* fileName, int lineNumber)
static void throw_if (error_code const& ec)
{
Throw (boost::system::system_error (ec), fileName, lineNumber);
throw boost::system::system_error (ec);
}
public:
typedef typename boost::remove_reference <Stream>::type next_layer_type;
typedef std::remove_reference_t <Stream> next_layer_type;
typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
/** Single argument constructor for when we are wrapped in something.
arg is passed through to the next layer's constructor.
*/
template <typename Arg>
template <class Arg>
explicit PrefilledReadStream (Arg& arg)
: m_next_layer (arg)
{
@@ -57,7 +63,7 @@ public:
This creates a copy of the data. The argument is passed through
to the constructor of Stream.
*/
template <typename Arg, typename ConstBufferSequence>
template <class Arg, class ConstBufferSequence>
PrefilledReadStream (Arg& arg, ConstBufferSequence const& buffers)
: m_next_layer (arg)
{
@@ -69,15 +75,14 @@ public:
is here is for the case when you can't pass the buffer through the
constructor because there is another object wrapping this stream.
*/
template <typename ConstBufferSequence>
template <class ConstBufferSequence>
void fill (ConstBufferSequence const& buffers)
{
// We don't assume the caller's buffers will
// remain valid for the lifetime of this object.
//
using namespace boost;
m_buffer.commit (asio::buffer_copy (
m_buffer.prepare (asio::buffer_size (buffers)),
m_buffer.commit (boost::asio::buffer_copy (
m_buffer.prepare (boost::asio::buffer_size (buffers)),
buffers));
}
@@ -109,8 +114,8 @@ public:
void close()
{
error_code ec;
if (close (ec))
throw_error (ec, __FILE__, __LINE__);
close (ec);
throw_if (ec);
}
error_code close (error_code& ec)
@@ -122,18 +127,18 @@ public:
return lowest_layer ().close(ec);
}
template <typename MutableBufferSequence>
template <class MutableBufferSequence>
std::size_t read_some (MutableBufferSequence const& buffers)
{
error_code ec;
std::size_t const amount = read_some (buffers, ec);
if (ec)
throw_error (ec, __FILE__, __LINE__);
throw_if (ec);
return amount;
}
template <typename MutableBufferSequence>
std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec)
template <class MutableBufferSequence>
std::size_t read_some (MutableBufferSequence const& buffers,
error_code& ec)
{
if (m_buffer.size () > 0)
{
@@ -146,46 +151,46 @@ public:
return m_next_layer.read_some (buffers, ec);
}
template <typename ConstBufferSequence>
template <class ConstBufferSequence>
std::size_t write_some (ConstBufferSequence const& buffers)
{
error_code ec;
std::size_t const amount = write_some (buffers, ec);
if (ec)
throw_error (ec, __FILE__, __LINE__);
auto const amount (write_some (buffers, ec));
throw_if (ec);
return amount;
}
template <typename ConstBufferSequence>
std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec)
template <class ConstBufferSequence>
std::size_t write_some (ConstBufferSequence const& buffers,
error_code& ec)
{
return m_next_layer.write_some (buffers, ec);
}
template <typename MutableBufferSequence, typename ReadHandler>
template <class MutableBufferSequence, class ReadHandler>
void async_read_some (MutableBufferSequence const& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
ReadHandler&& handler)
{
if (m_buffer.size () > 0)
{
std::size_t const bytes_transferred = boost::asio::buffer_copy (
buffers, m_buffer.data ());
auto const bytes_transferred (boost::asio::buffer_copy (
buffers, m_buffer.data ()));
m_buffer.consume (bytes_transferred);
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) (
error_code (), bytes_transferred);
get_io_service ().post (bind_handler (
std::forward <ReadHandler> (handler),
error_code (), bytes_transferred));
return;
}
m_next_layer.async_read_some (buffers,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
std::forward <ReadHandler> (handler));
}
template <typename ConstBufferSequence, typename WriteHandler>
template <class ConstBufferSequence, class WriteHandler>
void async_write_some (ConstBufferSequence const& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
WriteHandler&& handler)
{
m_next_layer.async_write_some (buffers,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
std::forward <WriteHandler> (handler));
}
private:
@@ -193,4 +198,7 @@ private:
boost::asio::streambuf m_buffer;
};
}
}
#endif

View File

@@ -1,199 +0,0 @@
//------------------------------------------------------------------------------
/*
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 ()
{
}
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//-----------------------------------------------------------------------------
//
// Socket
//
void* Socket::this_layer_ptr (char const*) const
{
pure_virtual_called (__FILE__, __LINE__);
return nullptr;
}
//-----------------------------------------------------------------------------
//
// native_handle
//
bool Socket::native_handle (char const*, void*)
{
pure_virtual_called (__FILE__, __LINE__);
return false;
}
//-----------------------------------------------------------------------------
//
// basic_io_object
//
boost::asio::io_service& Socket::get_io_service ()
{
pure_virtual_called (__FILE__, __LINE__);
return *static_cast <boost::asio::io_service*>(nullptr);
}
//-----------------------------------------------------------------------------
//
// basic_socket
//
void* Socket::lowest_layer_ptr (char const*) const
{
pure_virtual_called (__FILE__, __LINE__);
return nullptr;
}
boost::system::error_code Socket::cancel (boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
boost::system::error_code Socket::shutdown (shutdown_type, boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
boost::system::error_code Socket::close (boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
//------------------------------------------------------------------------------
//
// basic_socket_acceptor
//
boost::system::error_code Socket::accept (Socket&, boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
void Socket::async_accept (Socket&, SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error ());
}
//------------------------------------------------------------------------------
//
// basic_stream_socket
//
std::size_t Socket::read_some (MutableBuffers const&, boost::system::error_code& ec)
{
pure_virtual_called (__FILE__, __LINE__);
ec = pure_virtual_error ();
return 0;
}
std::size_t Socket::write_some (ConstBuffers const&, boost::system::error_code& ec)
{
pure_virtual_called (__FILE__, __LINE__);
ec = pure_virtual_error ();
return 0;
}
void Socket::async_read_some (MutableBuffers const&, SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error (), 0);
}
void Socket::async_write_some (ConstBuffers const&, SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error (), 0);
}
//--------------------------------------------------------------------------
//
// ssl::stream
//
void* Socket::next_layer_ptr (char const*) const
{
pure_virtual_called (__FILE__, __LINE__);
return nullptr;
}
bool Socket::needs_handshake ()
{
return false;
}
void Socket::set_verify_mode (int)
{
pure_virtual_called (__FILE__, __LINE__);
}
boost::system::error_code Socket::handshake (handshake_type, boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
void Socket::async_handshake (handshake_type, SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error ());
}
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
boost::system::error_code Socket::handshake (handshake_type,
ConstBuffers const&, boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
void Socket::async_handshake (handshake_type, ConstBuffers const&, SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error (), 0);
}
#endif
boost::system::error_code Socket::shutdown (boost::system::error_code& ec)
{
return pure_virtual_error (ec, __FILE__, __LINE__);
}
void Socket::async_shutdown (SharedHandlerPtr handler)
{
get_io_service ().wrap (
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
(pure_virtual_error ());
}
//------------------------------------------------------------------------------
#endif

View File

@@ -1,66 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ASIO_SOCKETS_SOCKETWRAPPERSTRAND_H_INCLUDED
#define BEAST_ASIO_SOCKETS_SOCKETWRAPPERSTRAND_H_INCLUDED
/** Wraps the async I/O of a SocketWrapper with an io_service::strand
To use this in a chain of wrappers, customize the Base type.
*/
template <typename Object, typename Base = SocketWrapper <Object> >
class SocketWrapperStrand
: public Base
{
public:
template <typename Arg>
SocketWrapperStrand (Arg& arg)
: Base (arg)
, m_strand (this->get_io_service ())
{
}
template <typename Arg1, typename Arg2>
SocketWrapperStrand (Arg1& arg1, Arg2& arg2)
: Base (arg1, arg2)
, m_strand (this->get_io_service ())
{
}
//--------------------------------------------------------------------------
//
// basic_stream_socket
//
void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
{
this->Base::async_read_some (buffers,
newReadHandler (m_strand.wrap (handler)));
}
void async_write_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
{
this->Base::async_write_some (buffers,
newWriteHandler (m_strand.wrap (handler)));
}
protected:
boost::asio::io_service::strand m_strand;
};
#endif

View File

@@ -53,6 +53,9 @@
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
// work-around for broken <boost/get_pointer.hpp>
#include "../../../beast/boost/get_pointer.h"
// Continuation hooks added in 1.54.0
#ifndef BEAST_ASIO_HAS_CONTINUATION_HOOKS
# if BOOST_VERSION >= 105400

View File

@@ -17,6 +17,8 @@
*/
//==============================================================================
namespace beast {
/** Test for showing information about the build of boost.
*/
class BoostUnitTests : public UnitTest
@@ -80,3 +82,5 @@ public:
};
static BoostUnitTests boostUnitTests;
}

View File

@@ -17,6 +17,9 @@
*/
//==============================================================================
namespace beast {
namespace asio {
PeerTest::Result::Result ()
: m_ec (TestPeerBasics::make_error (TestPeerBasics::errc::skipped))
, m_message (m_ec.message ())
@@ -98,3 +101,6 @@ bool PeerTest::Results::report (UnitTest& test, bool beginTestCase) const
success = false;
return success;
}
}
}

View File

@@ -20,8 +20,10 @@
#ifndef BEAST_ASIO_TESTS_PEERTEST_H_INCLUDED
#define BEAST_ASIO_TESTS_PEERTEST_H_INCLUDED
/** Performs a test of two peers defined by template parameters.
*/
namespace beast {
namespace asio {
/** Performs a test of two peers defined by template parameters. */
class PeerTest
{
public:
@@ -236,4 +238,7 @@ public:
}
};
}
}
#endif

View File

@@ -20,8 +20,10 @@
#ifndef BEAST_ASIO_TESTS_TESTPEER_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEER_H_INCLUDED
/** An abstract peer for unit tests.
*/
namespace beast {
namespace asio {
/** An abstract peer for unit tests. */
class TestPeer : public TestPeerBasics
{
public:
@@ -50,4 +52,7 @@ public:
virtual boost::system::error_code join () = 0;
};
}
}
#endif

View File

@@ -17,6 +17,9 @@
*/
//==============================================================================
namespace beast {
namespace asio {
TestPeerBasics::Model::Model (model_t model)
: m_model (model)
{
@@ -153,3 +156,6 @@ void TestPeerBasics::breakpoint (boost::system::error_code const& ec)
void TestPeerBasics::breakpoint (char const* const)
{
}
}
}

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERBASICS_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERBASICS_H_INCLUDED
namespace beast {
namespace asio {
/** Common declarations for TestPeer.
@see TestPeer
@@ -103,4 +106,7 @@ public:
static void breakpoint (char const* const message);
};
}
}
#endif

View File

@@ -20,8 +20,12 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERDETAILS_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERDETAILS_H_INCLUDED
/** Base class of all detail objects.
*/
#include "../../../beast/asio/abstract_socket.h"
namespace beast {
namespace asio {
/** Base class of all detail objects. */
class TestPeerDetails
{
public:
@@ -29,9 +33,9 @@ public:
virtual String name () const = 0;
virtual Socket& get_socket () = 0;
virtual abstract_socket& get_socket () = 0;
virtual Socket& get_acceptor () = 0;
virtual abstract_socket& get_acceptor () = 0;
boost::asio::io_service& get_io_service ()
{
@@ -42,4 +46,7 @@ private:
boost::asio::io_service m_io_service;
};
}
}
#endif

View File

@@ -20,8 +20,12 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERDETAILSTCP_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERDETAILSTCP_H_INCLUDED
/** Some predefined Detail classes for TestPeer
*/
#include "../../../beast/asio/socket_wrapper.h"
namespace beast {
namespace asio {
/** Some predefined Detail classes for TestPeer */
struct TcpDetails : public TestPeerDetails
{
protected:
@@ -59,12 +63,12 @@ public:
return getArgName (m_protocol);
}
Socket& get_socket ()
abstract_socket& get_socket ()
{
return m_socket_wrapper;
}
Socket& get_acceptor ()
abstract_socket& get_acceptor ()
{
return m_acceptor_wrapper;
}
@@ -101,8 +105,11 @@ 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;
socket_wrapper <socket_type&> m_socket_wrapper;
socket_wrapper <acceptor_type&> m_acceptor_wrapper;
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogic::TestPeerLogic (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogic::TestPeerLogic (abstract_socket& socket)
: m_socket (&socket)
{
}
@@ -37,7 +40,7 @@ TestPeerLogic::error_code const& TestPeerLogic::error (error_code const& ec) noe
return m_ec = ec;
}
Socket& TestPeerLogic::socket () noexcept
abstract_socket& TestPeerLogic::socket () noexcept
{
return *m_socket;
}
@@ -61,3 +64,6 @@ void TestPeerLogic::pure_virtual ()
{
fatal_error ("A TestPeerLogic function was called incorrectly");
}
}
}

View File

@@ -20,20 +20,22 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGIC_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGIC_H_INCLUDED
/** Interface for implementing the logic part of a peer test.
*/
namespace beast {
namespace asio {
/** Interface for implementing the logic part of a peer test. */
class TestPeerLogic : public TestPeerBasics
{
public:
typedef boost::system::error_code error_code;
explicit TestPeerLogic (Socket& socket);
explicit TestPeerLogic (abstract_socket& socket);
error_code& error () noexcept;
error_code const& error () const noexcept;
error_code const& error (error_code const& ec) noexcept; // assigns to m_ec
Socket& socket () noexcept;
abstract_socket& socket () noexcept;
virtual PeerRole get_role () const noexcept = 0;
@@ -51,7 +53,10 @@ public:
private:
error_code m_ec;
Socket* m_socket;
abstract_socket* m_socket;
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogicAsyncClient::TestPeerLogicAsyncClient (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogicAsyncClient::TestPeerLogicAsyncClient (abstract_socket& socket)
: TestPeerLogic (socket)
{
}
@@ -39,7 +42,7 @@ void TestPeerLogicAsyncClient::on_connect_async (error_code const& ec)
if (socket ().needs_handshake ())
{
socket ().async_handshake (Socket::client,
socket ().async_handshake (abstract_socket::client,
boost::bind (&TestPeerLogicAsyncClient::on_handshake, this,
boost::asio::placeholders::error));
}
@@ -108,7 +111,7 @@ void TestPeerLogicAsyncClient::on_read_final (error_code const& ec, std::size_t)
{
// on_shutdown will call finished ()
error_code ec;
on_shutdown (socket ().shutdown (Socket::shutdown_send, ec));
on_shutdown (socket ().shutdown (abstract_socket::shutdown_send, ec));
}
}
else
@@ -137,7 +140,7 @@ void TestPeerLogicAsyncClient::on_shutdown (error_code const& ec)
{
if (socket ().needs_handshake ())
{
socket ().shutdown (Socket::shutdown_send, error ());
socket ().shutdown (abstract_socket::shutdown_send, error ());
}
if (! error ())
@@ -153,3 +156,6 @@ void TestPeerLogicAsyncClient::on_shutdown (error_code const& ec)
finished ();
}
}
}

View File

@@ -20,10 +20,13 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGICASYNCCLIENT_H_INCLUDED
namespace beast {
namespace asio {
class TestPeerLogicAsyncClient : public TestPeerLogic
{
public:
explicit TestPeerLogicAsyncClient (Socket& socket);
explicit TestPeerLogicAsyncClient (abstract_socket& socket);
PeerRole get_role () const noexcept;
Model get_model () const noexcept;
void on_connect_async (error_code const& ec);
@@ -36,4 +39,7 @@ private:
boost::asio::streambuf m_buf;
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogicAsyncServer::TestPeerLogicAsyncServer (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogicAsyncServer::TestPeerLogicAsyncServer (abstract_socket& socket)
: TestPeerLogic (socket)
{
}
@@ -39,7 +42,7 @@ void TestPeerLogicAsyncServer::on_connect_async (error_code const& ec)
if (socket ().needs_handshake ())
{
socket ().async_handshake (Socket::server,
socket ().async_handshake (abstract_socket::server,
boost::bind (&TestPeerLogicAsyncServer::on_handshake, this,
boost::asio::placeholders::error));
}
@@ -90,7 +93,7 @@ void TestPeerLogicAsyncServer::on_write (error_code const& ec, std::size_t bytes
// on_shutdown will call finished ()
// we need another instance of ec so we can call on_shutdown()
error_code ec;
on_shutdown (socket ().shutdown (Socket::shutdown_receive, ec));
on_shutdown (socket ().shutdown (abstract_socket::shutdown_receive, ec));
}
}
@@ -102,7 +105,7 @@ void TestPeerLogicAsyncServer::on_shutdown (error_code const& ec)
{
if (socket ().needs_handshake ())
{
socket ().shutdown (Socket::shutdown_receive, error ());
socket ().shutdown (abstract_socket::shutdown_receive, error ());
}
if (success (socket ().close (error ())))
@@ -115,3 +118,7 @@ void TestPeerLogicAsyncServer::on_shutdown (error_code const& ec)
finished ();
}
}
}

View File

@@ -20,10 +20,13 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGICASYNCSERVER_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGICASYNCSERVER_H_INCLUDED
namespace beast {
namespace asio {
class TestPeerLogicAsyncServer : public TestPeerLogic
{
public:
explicit TestPeerLogicAsyncServer (Socket& socket);
explicit TestPeerLogicAsyncServer (abstract_socket& socket);
PeerRole get_role () const noexcept;
Model get_model () const noexcept;
void on_connect_async (error_code const& ec);
@@ -35,4 +38,7 @@ private:
boost::asio::streambuf m_buf;
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogicProxyClient::TestPeerLogicProxyClient (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogicProxyClient::TestPeerLogicProxyClient (abstract_socket& socket)
: TestPeerLogicSyncClient (socket)
{
}
@@ -33,3 +36,7 @@ void TestPeerLogicProxyClient::on_pre_handshake ()
boost::asio::write (socket (), boost::asio::buffer (line), error ());
}
}
}

View File

@@ -20,12 +20,18 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGICPROXYCLIENT_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGICPROXYCLIENT_H_INCLUDED
namespace beast {
namespace asio {
/** A synchronous client logic that sends a PROXY protocol pre-handshake. */
class TestPeerLogicProxyClient : public TestPeerLogicSyncClient
{
public:
explicit TestPeerLogicProxyClient (Socket& socket);
explicit TestPeerLogicProxyClient (abstract_socket& socket);
void on_pre_handshake ();
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogicSyncClient::TestPeerLogicSyncClient (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogicSyncClient::TestPeerLogicSyncClient (abstract_socket& socket)
: TestPeerLogic (socket)
{
}
@@ -97,7 +100,7 @@ void TestPeerLogicSyncClient::on_connect ()
error () = error_code ();
}
if (failure (socket ().shutdown (Socket::shutdown_send, error ())))
if (failure (socket ().shutdown (abstract_socket::shutdown_send, error ())))
return;
if (failure (socket ().close (error ())))
@@ -107,3 +110,6 @@ void TestPeerLogicSyncClient::on_connect ()
void TestPeerLogicSyncClient::on_pre_handshake ()
{
}
}
}

View File

@@ -20,14 +20,20 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGICSYNCCLIENT_H_INCLUDED
namespace beast {
namespace asio {
class TestPeerLogicSyncClient : public TestPeerLogic
{
public:
explicit TestPeerLogicSyncClient (Socket& socket);
explicit TestPeerLogicSyncClient (abstract_socket& socket);
PeerRole get_role () const noexcept;
Model get_model () const noexcept;
void on_connect ();
virtual void on_pre_handshake ();
};
}
}
#endif

View File

@@ -17,7 +17,10 @@
*/
//==============================================================================
TestPeerLogicSyncServer::TestPeerLogicSyncServer (Socket& socket)
namespace beast {
namespace asio {
TestPeerLogicSyncServer::TestPeerLogicSyncServer (abstract_socket& socket)
: TestPeerLogic (socket)
{
}
@@ -72,9 +75,12 @@ void TestPeerLogicSyncServer::on_connect ()
return;
}
if (failure (socket ().shutdown (Socket::shutdown_send, error ())))
if (failure (socket ().shutdown (abstract_socket::shutdown_send, error ())))
return;
if (failure (socket ().close (error ())))
return;
}
}
}

View File

@@ -20,13 +20,19 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERLOGICSYNCSERVER_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERLOGICSYNCSERVER_H_INCLUDED
namespace beast {
namespace asio {
class TestPeerLogicSyncServer : public TestPeerLogic
{
public:
explicit TestPeerLogicSyncServer (Socket& socket);
explicit TestPeerLogicSyncServer (abstract_socket& socket);
PeerRole get_role () const noexcept;
Model get_model () const noexcept;
void on_connect ();
};
}
}
#endif

View File

@@ -20,6 +20,9 @@
#ifndef BEAST_ASIO_TESTS_TESTPEERTYPE_H_INCLUDED
#define BEAST_ASIO_TESTS_TESTPEERTYPE_H_INCLUDED
namespace beast {
namespace asio {
template <typename Logic, typename Details>
class TestPeerType
: public Details
@@ -392,4 +395,7 @@ private:
int m_timeoutSeconds;
};
}
}
#endif

View File

@@ -17,8 +17,10 @@
*/
//==============================================================================
/** UnitTest for the TestPeer family of objects.
*/
namespace beast {
namespace asio {
/** UnitTest for the TestPeer family of objects. */
class TestPeerUnitTests : public UnitTest
{
public:
@@ -49,3 +51,6 @@ public:
};
static TestPeerUnitTests testPeerUnitTests;
}
}

View File

@@ -148,7 +148,6 @@ class FileOutputStream;
#include "maths/Math.h"
#include "logging/Logger.h"
#include "diagnostic/FPUFlags.h"
#include "memory/SharedFunction.h"
#include "text/Identifier.h"
#include "containers/Variant.h"
#include "containers/LinkedListPointer.h"

View File

@@ -1,334 +0,0 @@
//------------------------------------------------------------------------------
/*
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_CORE_SHAREDFUNCTION_H_INCLUDED
#define BEAST_CORE_SHAREDFUNCTION_H_INCLUDED
/** A reference counted, abstract function object. */
template <typename Signature, class Allocator = std::allocator <char> >
class SharedFunction;
//------------------------------------------------------------------------------
template <class R, class A>
class SharedFunction <R (void), A>
{
public:
struct Call : SharedObject
{ virtual R operator() () = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() ()
{ return (m_f)(); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
explicit SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() () const
{ return (*m_ptr)(); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class A>
class SharedFunction <R (P1), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1)
{ return (m_f)(p1); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1) const
{ return (*m_ptr)(p1); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class P2, class A>
class SharedFunction <R (P1, P2), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1, P2 const& p2) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1, P2 const& p2)
{ return (m_f)(p1, p2); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1, P2 const& p2) const
{ return (*m_ptr)(p1, p2); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class P2, class P3, class A>
class SharedFunction <R (P1, P2, P3), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1, P2 const& p2, P3 const& p3) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3)
{ return (m_f)(p1, p2, p3); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3) const
{ return (*m_ptr)(p1, p2, p3); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class P2, class P3, class P4, class A>
class SharedFunction <R (P1, P2, P3, P4), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4)
{ return (m_f)(p1, p2, p3, p4); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const
{ return (*m_ptr)(p1, p2, p3, p4); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class P2, class P3, class P4, class P5, class A>
class SharedFunction <R (P1, P2, P3, P4, P5), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5)
{ return (m_f)(p1, p2, p3, p4, p5); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5) const
{ return (*m_ptr)(p1, p2, p3, p4, p5); }
private:
SharedPtr <Call> m_ptr;
};
//------------------------------------------------------------------------------
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class A>
class SharedFunction <R (P1, P2, P3, P4, P5, P6), A>
{
public:
struct Call : public SharedObject
{ virtual R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5, P6 const& p6) = 0; };
template <typename F>
struct CallType : Call
{
typedef typename A:: template rebind <CallType <F> >::other Allocator;
CallType (BEAST_MOVE_ARG(F) f, A a = A ())
: m_f (BEAST_MOVE_CAST(F)(f)), m_a (a)
{ }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5, P6 const& p6)
{ return (m_f)(p1, p2, p3, p4, p5, p6); }
private:
F m_f;
Allocator m_a;
};
typedef R result_type;
template <typename F>
SharedFunction (F f, A a = A ())
: m_ptr (new (typename CallType <F>::Allocator (a).allocate (1))
CallType <F> (BEAST_MOVE_CAST(F)(f), a))
{ }
SharedFunction (SharedFunction const& other, A)
: m_ptr (other.m_ptr)
{ }
SharedFunction ()
{ }
bool empty () const
{ return m_ptr == nullptr; }
R operator() (P1 const& p1, P2 const& p2, P3 const& p3,
P4 const& p4, P5 const& p5, P6 const& p6) const
{ return (*m_ptr)(p1, p2, p3, p4, p5, p6); }
private:
SharedPtr <Call> m_ptr;
};
#endif