mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 23:15:52 +00:00
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:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,47 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
void SharedHandler::operator() ()
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
SSLContext::SSLContext (ContextType& context)
|
||||
: m_context (context)
|
||||
{
|
||||
@@ -26,3 +29,5 @@ SSLContext::~SSLContext ()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPField::HTTPField ()
|
||||
{
|
||||
}
|
||||
@@ -49,3 +51,5 @@ String HTTPField::value () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPHeaders::HTTPHeaders ()
|
||||
{
|
||||
}
|
||||
@@ -84,3 +86,4 @@ String HTTPHeaders::toString () const
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPRequest::HTTPRequest (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
@@ -40,3 +42,4 @@ String HTTPRequest::toString () const
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPResponse::HTTPResponse (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
@@ -40,3 +42,4 @@ String HTTPResponse::toString () const
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,4 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -163,10 +172,14 @@ private:
|
||||
// If postcondition fails, loop will never end
|
||||
if (meets_postcondition (available < needed))
|
||||
{
|
||||
typename BuffersType::mutable_buffers_type buffers (
|
||||
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 ()
|
||||
{
|
||||
return m_running
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
|| boost_asio_handler_cont_helpers::is_continuation (m_handler);
|
||||
#endif
|
||||
;
|
||||
if (m_continuation)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,436 +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_SOCKET_H_INCLUDED
|
||||
#define BEAST_ASIO_SOCKETS_SOCKET_H_INCLUDED
|
||||
|
||||
/** A high level socket abstraction.
|
||||
|
||||
This combines the capabilities of multiple socket interfaces such
|
||||
as listening, connecting, streaming, and handshaking. It brings
|
||||
everything together into a single abstract interface.
|
||||
|
||||
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
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
public:
|
||||
virtual ~Socket ();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Socket
|
||||
//
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <typename Object>
|
||||
Object& this_layer ()
|
||||
{
|
||||
Object* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const& this_layer () const
|
||||
{
|
||||
Object const* object (this->this_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object* this_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const* this_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->this_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* this_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
|
||||
/** Retrieve the native representation of the object.
|
||||
|
||||
Since we dont know the return type, and because almost every
|
||||
asio implementation passes the result by value, you need to provide
|
||||
a pointer to a default-constructed object of the matching type.
|
||||
|
||||
@note If the type doesn't match, an exception is thrown.
|
||||
*/
|
||||
template <typename Handle>
|
||||
void native_handle (Handle* dest)
|
||||
{
|
||||
if (! native_handle (typeid (Handle).name (), dest))
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual bool native_handle (char const* type_name, void* dest)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
|
||||
virtual boost::asio::io_service& get_io_service ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
|
||||
/** Retrieve the lowest layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <typename Object>
|
||||
Object& lowest_layer ()
|
||||
{
|
||||
Object* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (this->lowest_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->lowest_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* lowest_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (cancel (ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code cancel (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void shutdown (shutdown_type what)
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (shutdown (what, ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (shutdown_type what,
|
||||
error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void close ()
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (close (ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code close (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
|
||||
virtual error_code accept (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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
|
||||
/** Retrieve the next layer object.
|
||||
|
||||
@note If the type doesn't match, nullptr is returned or an
|
||||
exception is thrown if trying to acquire a reference.
|
||||
*/
|
||||
/** @{ */
|
||||
template <typename Object>
|
||||
Object& next_layer ()
|
||||
{
|
||||
Object* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const& next_layer () const
|
||||
{
|
||||
Object const* object (this->next_layer_ptr <Object> ());
|
||||
if (object == nullptr)
|
||||
Throw (std::bad_cast (), __FILE__, __LINE__);
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object* next_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
Object const* next_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
this->next_layer_ptr (typeid (Object).name ()));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* next_layer_ptr (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
/** Determines if the underlying stream requires a handshake.
|
||||
|
||||
If needs_handshake is true, it will be necessary to call handshake or
|
||||
async_handshake after the connection is established. Furthermore it
|
||||
will be necessary to call the shutdown member from the
|
||||
HandshakeInterface to close the connection. Do not close the underlying
|
||||
socket or else the closure will not be graceful. Only one side should
|
||||
initiate the handshaking shutdon. The other side should observe it.
|
||||
Which side does what is up to the user.
|
||||
|
||||
The default version returns false.
|
||||
*/
|
||||
virtual bool needs_handshake ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__verify_mode.html
|
||||
//
|
||||
virtual void set_verify_mode (int verify_mode) = 0;
|
||||
|
||||
// ssl::stream::handshake (1 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload1.html
|
||||
//
|
||||
void handshake (handshake_type type)
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (handshake (type, ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// 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)
|
||||
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)
|
||||
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)
|
||||
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__);
|
||||
}
|
||||
|
||||
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)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,42 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
boost::system::error_code SocketBase::pure_virtual_error ()
|
||||
{
|
||||
return boost::system::errc::make_error_code (
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
|
||||
boost::system::error_code SocketBase::pure_virtual_error (error_code& ec,
|
||||
char const* fileName, int lineNumber)
|
||||
{
|
||||
pure_virtual_called (fileName, lineNumber);
|
||||
return ec = pure_virtual_error ();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,49 +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_SOCKETBASE_H_INCLUDED
|
||||
#define BEAST_ASIO_SOCKETS_SOCKETBASE_H_INCLUDED
|
||||
|
||||
/** Common implementation details for Socket and related classes.
|
||||
Normally you wont need to use this.
|
||||
*/
|
||||
struct SocketBase
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
/** 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 ();
|
||||
|
||||
/** Convenience for taking a reference and returning the error_code. */
|
||||
static error_code pure_virtual_error (error_code& ec,
|
||||
char const* fileName, int lineNumber);
|
||||
|
||||
/** Called when a function doesn't support the interface. */
|
||||
static void pure_virtual_called (char const* fileName, int lineNumber);
|
||||
|
||||
/** Called when synchronous functions without error parameters get an error. */
|
||||
static void throw_error (error_code const& ec, char const* fileName, int lineNumber);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,838 +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_SOCKETWRAPPER_H_INCLUDED
|
||||
#define BEAST_ASIO_SOCKETS_SOCKETWRAPPER_H_INCLUDED
|
||||
|
||||
/** Wraps a reference to any object and exports all availble interfaces.
|
||||
|
||||
If the object does not support an interface, calling those
|
||||
member functions will behave as if a pure virtual was called.
|
||||
|
||||
Note that only a reference to the underlying is stored. Management
|
||||
of the lifetime of the object is controlled by the caller.
|
||||
|
||||
Examples of the type of Object:
|
||||
|
||||
asio::ip::tcp::socket
|
||||
asio::ip::tcp::socket&
|
||||
asio::ssl::stream <asio::ip::tcp::socket>
|
||||
asio::ssl::stream <asio::ip::tcp::socket&>
|
||||
explain arg must be an io_context
|
||||
explain SocketWrapper will create and take ownership of the tcp::socket
|
||||
explain this_layer_type will be tcp::socket
|
||||
explain next_layer () returns a asio::ip::tcp::socket&
|
||||
explain lowest_layer () returns a asio::ip::tcp::socket&
|
||||
|
||||
asio::ssl::stream <asio::buffered_stream <asio::ip::tcp::socket> > >
|
||||
This makes my head explode
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
namespace SocketWrapperMemberChecks
|
||||
{
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some);
|
||||
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake);
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown);
|
||||
|
||||
// Extracts the underlying socket type from the protocol of another asio object
|
||||
template <typename T, typename Enable = void>
|
||||
struct native_socket
|
||||
{
|
||||
typedef void* socket_type;
|
||||
inline native_socket (Socket&)
|
||||
: m_socket (nullptr)
|
||||
{
|
||||
SocketBase::pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
inline socket_type& get ()
|
||||
{
|
||||
SocketBase::pure_virtual_called (__FILE__, __LINE__);
|
||||
return m_socket;
|
||||
}
|
||||
inline socket_type& operator-> ()
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type m_socket;
|
||||
};
|
||||
|
||||
// Enabled if T::protocol_type::socket exists as a type
|
||||
template <typename T>
|
||||
struct native_socket <T, typename boost::enable_if <boost::is_class <
|
||||
typename T::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename T::protocol_type::socket socket_type;
|
||||
inline native_socket (Socket& peer)
|
||||
: m_socket_ptr (&peer.this_layer <socket_type> ())
|
||||
{
|
||||
}
|
||||
inline socket_type& get () noexcept
|
||||
{
|
||||
return *m_socket_ptr;
|
||||
}
|
||||
inline socket_type& operator-> () noexcept
|
||||
{
|
||||
return get ();
|
||||
}
|
||||
private:
|
||||
socket_type* m_socket_ptr;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Object>
|
||||
class SocketWrapper
|
||||
: public Socket
|
||||
, public Uncopyable
|
||||
{
|
||||
public:
|
||||
// Converts a static bool constexpr member named 'value' into
|
||||
// an IntegralConstant for SFINAE overload resolution.
|
||||
//
|
||||
template <class Cond>
|
||||
struct Enabled : public IntegralConstant <bool, Cond::value> { };
|
||||
|
||||
template <typename Arg>
|
||||
explicit SocketWrapper (Arg& arg)
|
||||
: m_object (arg)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Arg1, typename Arg2>
|
||||
SocketWrapper (Arg1& arg1, Arg2& arg2)
|
||||
: m_object (arg1, arg2)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// SocketWrapper
|
||||
//
|
||||
|
||||
/** The type of the object being wrapped. */
|
||||
typedef typename boost::remove_reference <Object>::type this_layer_type;
|
||||
|
||||
/** Get a reference to this layer. */
|
||||
this_layer_type& this_layer () noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
/** Get a const reference to this layer. */
|
||||
this_layer_type const& this_layer () const noexcept
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Socket
|
||||
//
|
||||
|
||||
void* this_layer_ptr (char const* type_name) const
|
||||
{
|
||||
char const* const name (typeid (this_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// native_handle
|
||||
//
|
||||
|
||||
#if 0
|
||||
// This is a potential work-around for the problem with
|
||||
// the has_type_native_handle_type template, but requires
|
||||
// Boost 1.54 or later.
|
||||
//
|
||||
// This include will be needed:
|
||||
//
|
||||
// boost/tti/has_type.hpp
|
||||
//
|
||||
//
|
||||
BOOST_TTI_HAS_TYPE(native_handle_type)
|
||||
|
||||
#else
|
||||
template <class T>
|
||||
struct has_type_native_handle_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::native_handle_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_native_handle_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T, bool Exists = has_type_native_handle_type <T>::value >
|
||||
struct extract_native_handle_type
|
||||
{
|
||||
typedef typename T::native_handle_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_native_handle_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if native_handle_type doesn't exist in Object
|
||||
typedef typename extract_native_handle_type <this_layer_type>::type native_handle_type;
|
||||
|
||||
bool native_handle (char const* type_name, void* dest)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return native_handle (type_name, dest,
|
||||
Enabled <has_type_native_handle_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
bool native_handle (char const* type_name, void* dest,
|
||||
TrueType)
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::native_handle_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
{
|
||||
native_handle_type* const p (reinterpret_cast <native_handle_type*> (dest));
|
||||
*p = m_object.native_handle ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool native_handle (char const*, void*,
|
||||
FalseType)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
//
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
#if 0
|
||||
// Apparently has_get_io_service always results in false
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return get_io_service (
|
||||
Enabled <has_get_io_service <this_layer_type,
|
||||
boost::asio::io_service&()> > ());
|
||||
#else
|
||||
return get_io_service (TrueType ());
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
TrueType)
|
||||
{
|
||||
return m_object.get_io_service ();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
FalseType)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket
|
||||
//
|
||||
|
||||
/*
|
||||
To forward the lowest_layer_type type, we need to make sure it
|
||||
exists in Object. This is a little more tricky than just figuring
|
||||
out if Object has a particular member function.
|
||||
|
||||
The problem is boost::asio::basic_socket_acceptor, which doesn't
|
||||
have lowest_layer () or lowest_layer_type ().
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
struct has_type_lowest_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::lowest_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_lowest_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_lowest_layer_type <T>::value >
|
||||
struct extract_lowest_layer_type
|
||||
{
|
||||
typedef typename T::lowest_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_lowest_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if lowest_layer_type doesn't exist in Object
|
||||
typedef typename extract_lowest_layer_type <this_layer_type>::type lowest_layer_type;
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name) const
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return lowest_layer_ptr (type_name,
|
||||
Enabled <has_type_lowest_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const* type_name,
|
||||
TrueType) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.lowest_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* lowest_layer_ptr (char const*,
|
||||
FalseType) const
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code cancel (error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return cancel (ec,
|
||||
Enabled <has_cancel <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.cancel (ec);
|
||||
}
|
||||
|
||||
error_code cancel (error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return shutdown (what, ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (shutdown_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
|
||||
error_code shutdown (shutdown_type what, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.shutdown (what, ec);
|
||||
}
|
||||
|
||||
error_code shutdown (shutdown_type, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code close (error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return close (ec,
|
||||
Enabled <has_close <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.close (ec);
|
||||
}
|
||||
|
||||
error_code close (error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
|
||||
error_code accept (Socket& peer, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
return accept (peer, ec,
|
||||
Enabled <has_accept <this_layer_type,
|
||||
error_code (socket_type&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code accept (Socket& peer, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return m_object.accept (
|
||||
native_socket <this_layer_type> (peer).get (), ec);
|
||||
}
|
||||
|
||||
error_code accept (Socket&, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_accept (Socket& peer, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
async_accept (peer, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_accept <this_layer_type,
|
||||
void (socket_type&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
m_object.async_accept (
|
||||
native_socket <this_layer_type> (peer).get (),
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_accept (Socket&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_stream_socket
|
||||
//
|
||||
|
||||
std::size_t read_some (MutableBuffers const& buffers, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return read_some (buffers, ec,
|
||||
Enabled <has_read_some <this_layer_type,
|
||||
std::size_t (MutableBuffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const&, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
std::size_t write_some (ConstBuffers const& buffers, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return write_some (buffers, ec,
|
||||
Enabled <has_write_some <this_layer_type,
|
||||
std::size_t (ConstBuffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const&, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
async_read_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_read_some <this_layer_type,
|
||||
void (MutableBuffers const&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_read_some (MutableBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
m_object.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_read_some (MutableBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
async_write_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_write_some <this_layer_type,
|
||||
void (ConstBuffers const&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_write_some (ConstBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
m_object.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_write_some (ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// ssl::stream
|
||||
//
|
||||
|
||||
template <class T>
|
||||
struct has_type_next_layer_type
|
||||
{
|
||||
typedef char yes;
|
||||
typedef struct {char dummy[2];} no;
|
||||
template <class C> static yes f(typename C::next_layer_type*);
|
||||
template <class C> static no f(...);
|
||||
#ifdef _MSC_VER
|
||||
static bool const value = sizeof(f<T>(0)) == 1;
|
||||
#else
|
||||
// This line fails to compile under Visual Studio 2012
|
||||
static bool const value = sizeof(has_type_next_layer_type<T>::f<T>(0)) == 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T, bool Exists = has_type_next_layer_type <T>::value >
|
||||
struct extract_next_layer_type
|
||||
{
|
||||
typedef typename T::next_layer_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_next_layer_type <T, false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// This will be void if next_layer_type doesn't exist in Object
|
||||
typedef typename extract_next_layer_type <this_layer_type>::type next_layer_type;
|
||||
|
||||
void* next_layer_ptr (char const* type_name) const
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return next_layer_ptr (type_name,
|
||||
Enabled <has_type_next_layer_type <this_layer_type> > ());
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const* type_name,
|
||||
TrueType) const
|
||||
{
|
||||
char const* const name (typeid (typename this_layer_type::next_layer_type).name ());
|
||||
if (strcmp (name, type_name) == 0)
|
||||
return const_cast <void*> (static_cast <void const*> (&m_object.next_layer ()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* next_layer_ptr (char const*,
|
||||
FalseType) const
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
bool needs_handshake ()
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return
|
||||
has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)>::value ||
|
||||
has_async_handshake <this_layer_type,
|
||||
void (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void set_verify_mode (int verify_mode)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
set_verify_mode (verify_mode,
|
||||
Enabled <has_set_verify_mode <this_layer_type,
|
||||
void (int)> > ());
|
||||
|
||||
}
|
||||
|
||||
void set_verify_mode (int verify_mode,
|
||||
TrueType)
|
||||
{
|
||||
m_object.set_verify_mode (verify_mode);
|
||||
}
|
||||
|
||||
void set_verify_mode (int,
|
||||
FalseType)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code handshake (handshake_type type, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return handshake (type, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code handshake (handshake_type type, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.handshake (type, ec);
|
||||
}
|
||||
|
||||
error_code handshake (handshake_type, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
async_handshake (type, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
m_object.async_handshake (type,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
|
||||
error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return handshake (type, buffers, ec,
|
||||
Enabled <has_handshake <this_layer_type,
|
||||
error_code (handshake_type, ConstBuffers const&, error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.handshake (type, buffers, ec);
|
||||
}
|
||||
|
||||
error_code handshake (handshake_type, ConstBuffers const&, error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_handshake <this_layer_type,
|
||||
void (handshake_type, ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
m_object.async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_handshake (handshake_type, ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code shutdown (error_code& ec)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
return shutdown (ec,
|
||||
Enabled <has_shutdown <this_layer_type,
|
||||
error_code (error_code&)> > ());
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
TrueType)
|
||||
{
|
||||
return m_object.shutdown (ec);
|
||||
}
|
||||
|
||||
error_code shutdown (error_code& ec,
|
||||
FalseType)
|
||||
{
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_shutdown (SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace detail::SocketWrapperMemberChecks;
|
||||
async_shutdown (BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
Enabled <has_async_shutdown <this_layer_type,
|
||||
void (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))> > ());
|
||||
}
|
||||
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
TrueType)
|
||||
{
|
||||
m_object.async_shutdown (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
FalseType)
|
||||
{
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
private:
|
||||
Object m_object;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user