Improvements to BuffersType

This commit is contained in:
Vinnie Falco
2013-09-09 08:47:51 -07:00
parent 2b132ae892
commit d2d946204c
6 changed files with 202 additions and 105 deletions

View File

@@ -84,8 +84,9 @@
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerAllocator.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerPtr.h" />
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerType.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\BuffersType.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\FixedInputBuffer.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\PeerRole.h" />
<ClInclude Include="..\..\modules\beast_asio\basics\SSLContext.h" />

View File

@@ -911,9 +911,6 @@
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerType.h">
<Filter>beast_asio\async</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\FixedInputBuffer.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
@@ -1025,6 +1022,12 @@
<ClInclude Include="..\..\beast\mpl\IfCond.h">
<Filter>beast\mpl</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\BuffersType.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h">
<Filter>beast_asio\basics</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">

View File

@@ -20,128 +20,83 @@
#ifndef BEAST_ASIO_BASICS_BUFFERTYPE_H_INCLUDED
#define BEAST_ASIO_BASICS_BUFFERTYPE_H_INCLUDED
/** Storage for a BufferSequence.
Meets these requirements:
BufferSequence
ConstBufferSequence (when Buffer is mutable_buffer)
MutableBufferSequence (when Buffer is const_buffer)
/** General linear memory buffer.
This wraps the underlying buffer type and provides additional methods
to create a uniform interface. Specializations allow asio-compatible
buffers without having to include boost/asio.h.
*/
template <class Buffer>
/** @{ */
template <bool IsConst>
class BufferType
{
private:
typedef typename mpl::IfCond <IsConst,
void const*,
void*>::type pointer_type;
typedef typename mpl::IfCond <IsConst,
uint8 const,
uint8>::type byte_type;
public:
typedef Buffer value_type;
typedef std::vector <Buffer> container_type;
typedef typename container_type::const_iterator const_iterator;
typedef std::size_t size_type;
/** Construct a null buffer.
This is the equivalent of @ref asio::null_buffers.
*/
BufferType ()
: m_size (0)
: m_data (nullptr)
, m_size (0)
{
}
/** Construct from a container.
Ownership of the container is transferred, the caller's
value becomes undefined, but valid.
*/
explicit BufferType (container_type& container)
: m_size (0)
template <bool OtherIsConst>
BufferType (BufferType <OtherIsConst> const& other)
: m_data (other.cast <pointer_type> ())
, m_size (other.size ())
{
m_buffers.swap (container);
for (typename container_type::const_iterator iter (m_buffers.begin ());
iter != m_buffers.end (); ++iter)
m_size += boost::asio::buffer_size (*iter);
}
/** Construct a BufferType from an existing BufferSequence.
@see assign
*/
template <class BufferSequence>
BufferType (BufferSequence const& buffers)
BufferType (pointer_type data, std::size_t size) noexcept
: m_data (data)
, m_size (size)
{
assign (buffers);
}
/** Assign a BufferType from an existing BufferSequence.
@see assign
*/
template <class BufferSequence>
BufferType <Buffer>& operator= (BufferSequence const& buffers)
BufferType& operator= (BufferType const& other) noexcept
{
return assign (buffers);
}
/** Assign a BufferType 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>
BufferType <Buffer>& assign (BufferSequence const& buffers)
{
m_size = 0;
m_buffers.clear ();
m_buffers.reserve (std::distance (buffers.begin (), buffers.end ()));
BOOST_FOREACH (typename BufferSequence::value_type buffer, buffers)
{
m_size += boost::asio::buffer_size (buffer);
m_buffers.push_back (buffer);
}
m_data = other.cast <pointer_type> ();
m_size = other.size ();
return *this;
}
/** Determine the total size of all buffers.
This is faster than calling boost::asio::buffer_size.
*/
std::size_t size () const noexcept
template <bool OtherIsConst>
BufferType& operator= (
BufferType <OtherIsConst> const& other) noexcept
{
m_data = other.cast <pointer_type> ();
m_size = other.size ();
return *this;
}
template <typename T>
T cast () const noexcept
{
return static_cast <T> (m_data);
}
size_type size () const
{
return m_size;
}
const_iterator begin () const noexcept
BufferType operator+ (size_type n) const noexcept
{
return m_buffers.begin ();
}
const_iterator end () const noexcept
{
return m_buffers.end ();
}
/** Retrieve a consumed BufferSequence. */
BufferType consumed (std::size_t bytes) const
{
BufferType result;
result.m_buffers.reserve (m_buffers.size ());
BOOST_FOREACH (Buffer buffer, m_buffers)
{
std::size_t const have = boost::asio::buffer_size (buffer);
std::size_t const reduce = std::min (bytes, have);
bytes -= reduce;
if (have > reduce)
result.m_buffers.push_back (buffer + reduce);
}
return result;
return BufferType (cast <byte_type*> (),
size () - std::min (size(), n));
}
private:
pointer_type m_data;
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 BufferType <ConstBuffer> ConstBuffers;
/** Meets the requirements of MutableBufferSequence */
typedef BufferType <MutableBuffer> MutableBuffers;
/** @} */
#endif

View File

@@ -0,0 +1,137 @@
//------------------------------------------------------------------------------
/*
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 BufferType <true> ConstBuffer;
typedef boost::asio::const_buffer ConstBuffer;
/** A single linear writable buffer. */
//typedef BufferType <false> MutableBuffer;
typedef boost::asio::mutable_buffer MutableBuffer;
/** Meets the requirements of ConstBufferSequence */
typedef BuffersType <ConstBuffer> ConstBuffers;
/** Meets the requirements of MutableBufferSequence */
typedef BuffersType <MutableBuffer> MutableBuffers;
#endif

View File

@@ -63,7 +63,8 @@ namespace beast
# include "async/ComposedAsyncOperation.h"
#include "async/SharedHandlerAllocator.h"
# include "basics/BufferType.h"
# include "basics/BufferType.h"
# include "basics/BuffersType.h"
#include "basics/ContentBodyBuffer.h"
#include "basics/FixedInputBuffer.h"
#include "basics/PeerRole.h"

View File

@@ -57,7 +57,7 @@ public:
error_code detect (Stream& stream,
boost::asio::basic_streambuf <Allocator>& buffer)
{
typedef boost::asio::basic_streambuf <Allocator> BufferType;
typedef boost::asio::basic_streambuf <Allocator> BuffersType;
error_code ec;
@@ -80,7 +80,7 @@ public:
// If postcondition fails, loop will never end
if (meets_postcondition (available < needed))
{
typename BufferType::mutable_buffers_type buffers (
typename BuffersType::mutable_buffers_type buffers (
buffer.prepare (needed - available));
buffer.commit (stream.read_some (buffers, ec));
}
@@ -125,10 +125,10 @@ private:
template <typename Allocator>
struct AsyncOp : ComposedAsyncOperation
{
typedef boost::asio::basic_streambuf <Allocator> BufferType;
typedef boost::asio::basic_streambuf <Allocator> BuffersType;
AsyncOp (HandshakeDetectLogicType <Logic>& logic, Stream& stream,
BufferType& buffer, SharedHandlerPtr const& handler)
BuffersType& buffer, SharedHandlerPtr const& handler)
: ComposedAsyncOperation (sizeof (*this), handler)
, m_logic (logic)
, m_stream (stream)
@@ -163,7 +163,7 @@ private:
// If postcondition fails, loop will never end
if (meets_postcondition (available < needed))
{
typename BufferType::mutable_buffers_type buffers (
typename BuffersType::mutable_buffers_type buffers (
m_buffer.prepare (needed - available));
m_stream.async_read_some (buffers, SharedHandlerPtr (this));
@@ -194,7 +194,7 @@ private:
private:
HandshakeDetectLogicType <Logic>& m_logic;
Stream& m_stream;
BufferType& m_buffer;
BuffersType& m_buffer;
SharedHandlerPtr m_handler;
bool m_running;
};