diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index 0b56b695d9..15beb86587 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -131,6 +131,8 @@ + + @@ -174,8 +176,6 @@ - - @@ -466,6 +466,12 @@ true true + + true + true + true + true + true true @@ -511,12 +517,6 @@ true true - - true - true - true - true - true true diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index 35e528918d..64a5a2197a 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -902,9 +902,6 @@ beast_asio\protocol - - beast_asio\basics - beast_asio\http @@ -935,9 +932,6 @@ beast_asio\basics - - beast_asio\basics - beast_core\memory @@ -1215,6 +1209,12 @@ beast + + beast\net + + + beast\net + @@ -1610,9 +1610,6 @@ beast_asio\protocol - - beast_asio\basics - beast_asio\http @@ -1748,6 +1745,9 @@ beast\utility\impl + + beast\net\impl + diff --git a/beast/Net.h b/beast/Net.h index 3d96d20229..091c940f05 100644 --- a/beast/Net.h +++ b/beast/Net.h @@ -20,6 +20,9 @@ #ifndef BEAST_NET_H_INCLUDED #define BEAST_NET_H_INCLUDED +#include "net/BufferType.h" +#include "net/DynamicBuffer.h" + #include "net/IPEndpoint.h" #endif diff --git a/modules/beast_asio/basics/BufferType.h b/beast/net/BufferType.h similarity index 95% rename from modules/beast_asio/basics/BufferType.h rename to beast/net/BufferType.h index 722fe4befc..4e3ab14785 100644 --- a/modules/beast_asio/basics/BufferType.h +++ b/beast/net/BufferType.h @@ -17,8 +17,12 @@ */ //============================================================================== -#ifndef BEAST_ASIO_BASICS_BUFFERTYPE_H_INCLUDED -#define BEAST_ASIO_BASICS_BUFFERTYPE_H_INCLUDED +#ifndef BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED +#define BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED + +#include "../mpl/IfCond.h" + +namespace beast { /** General linear memory buffer. This wraps the underlying buffer type and provides additional methods @@ -99,4 +103,6 @@ private: }; /** @} */ +} + #endif diff --git a/beast/net/DynamicBuffer.h b/beast/net/DynamicBuffer.h new file mode 100644 index 0000000000..34d2a6d749 --- /dev/null +++ b/beast/net/DynamicBuffer.h @@ -0,0 +1,125 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_NET_DYNAMICBUFFER_H_INCLUDED +#define BEAST_NET_DYNAMICBUFFER_H_INCLUDED + +#include + +namespace beast { + +/** Disjoint, but efficient buffer storage for network operations. + This is designed to not require asio in order to compile. +*/ +class DynamicBuffer +{ +public: + enum + { + defaultBlocksize = 32 * 1024 + }; + + typedef std::size_t size_type; + + /** Create the dynamic buffer with the specified block size. */ + explicit DynamicBuffer (size_type blocksize = defaultBlocksize); + + DynamicBuffer (DynamicBuffer const& other); + + ~DynamicBuffer (); + + DynamicBuffer& operator= (DynamicBuffer const& other); + + /** Swap the contents of this buffer with another. + This is the preferred way to transfer ownership. + */ + void swapWith (DynamicBuffer& other); + + /** Returns the size of the input sequence. */ + size_type size () const; + + /** Returns a buffer to the input sequence. + ConstBufferType must be constructible with this signature: + ConstBufferType (void const* buffer, size_type bytes); + */ + template + std::vector data () const + { + std::vector buffers; + buffers.reserve (m_buffers.size()); + size_type amount (m_size); + for (typename Buffers::const_iterator iter (m_buffers.begin()); + amount > 0 && iter != m_buffers.end(); ++iter) + { + size_type const n (std::min (amount, m_blocksize)); + buffers.push_back (ConstBufferType (*iter, n)); + amount -= n; + } + return buffers; + } + + /** Reserve space in the output sequence. + This also returns a buffer suitable for writing. + MutableBufferType must be constructible with this signature: + MutableBufferType (void* buffer, size_type bytes); + */ + template + std::vector prepare (size_type amount) + { + std::vector buffers; + buffers.reserve (m_buffers.size()); + reserve (amount); + size_type offset (m_size % m_blocksize); + for (Buffers::iterator iter = m_buffers.begin () + (m_size / m_blocksize); + amount > 0 && iter != m_buffers.end (); ++iter) + { + size_type const n (std::min (amount, m_blocksize - offset)); + buffers.push_back (MutableBufferType ( + ((static_cast (*iter)) + offset), n)); + amount -= n; + offset = 0; + } + return buffers; + } + + /** Reserve space in the output sequence. */ + void reserve (size_type n); + + /** Move bytes from the output to the input sequence. */ + void commit (size_type n); + + /** Release memory while preserving the input sequence. */ + void shrink_to_fit (); + + /** Convert the entire buffer into a single string. + This is mostly for diagnostics, it defeats the purpose of the class! + */ + std::string to_string () const; + +private: + typedef std::vector Buffers; + + size_type m_blocksize; + size_type m_size; + Buffers m_buffers; +}; + +} + +#endif diff --git a/beast/net/Net.cpp b/beast/net/Net.cpp index 1c045fd65d..6a84e21858 100644 --- a/beast/net/Net.cpp +++ b/beast/net/Net.cpp @@ -23,4 +23,5 @@ #include "../../modules/beast_core/beast_core.h" // for UnitTest +#include "impl/DynamicBuffer.cpp" #include "impl/IPEndpoint.cpp" diff --git a/beast/net/impl/DynamicBuffer.cpp b/beast/net/impl/DynamicBuffer.cpp new file mode 100644 index 0000000000..4dec2d5dfb --- /dev/null +++ b/beast/net/impl/DynamicBuffer.cpp @@ -0,0 +1,91 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include + +#include "../DynamicBuffer.h" + +namespace beast { + +DynamicBuffer::DynamicBuffer (size_type blocksize) + : m_blocksize (blocksize) + , m_size (0) +{ +} + +DynamicBuffer::~DynamicBuffer () +{ + for (Buffers::iterator iter (m_buffers.begin()); + iter != m_buffers.end(); ++iter) + free (*iter); +} + +void DynamicBuffer::swapWith (DynamicBuffer& other) +{ + std::swap (m_blocksize, other.m_blocksize); + std::swap (m_size, other.m_size); + m_buffers.swap (other.m_buffers); +} + +void DynamicBuffer::commit (size_type n) +{ + m_size += n; + bassert (m_size <= m_buffers.size () * m_blocksize); +} + +DynamicBuffer::size_type DynamicBuffer::size () const +{ + return m_size; +} + +void DynamicBuffer::reserve (size_type n) +{ + size_type count ((m_size + n + m_blocksize - 1) / m_blocksize); + if (count > m_buffers.size ()) + for (count -= m_buffers.size (); count-- > 0;) + m_buffers.push_back (malloc (m_blocksize)); +} + +void DynamicBuffer::shrink_to_fit () +{ + size_type const count ((m_size + m_blocksize - 1) / m_blocksize); + while (m_buffers.size () > count) + { + free (m_buffers.back ()); + m_buffers.erase (m_buffers.end () - 1); + } +} + +std::string DynamicBuffer::to_string () const +{ + std::string (s); + s.reserve (m_size); + std::size_t amount (m_size); + for (Buffers::const_iterator iter (m_buffers.begin()); + amount > 0 && iter != m_buffers.end(); ++iter) + { + char const* p (static_cast (*iter)); + size_type const n (std::min (amount, m_blocksize)); + s.append (p, p + n); + amount -= n; + } + return s; +} + +} diff --git a/modules/beast_asio/basics/BuffersType.h b/modules/beast_asio/basics/BuffersType.h index 770c1b47ab..a14890e1b6 100644 --- a/modules/beast_asio/basics/BuffersType.h +++ b/modules/beast_asio/basics/BuffersType.h @@ -121,11 +121,9 @@ private: //------------------------------------------------------------------------------ /** A single linear read-only buffer. */ -//typedef BufferType ConstBuffer; typedef boost::asio::const_buffer ConstBuffer; /** A single linear writable buffer. */ -//typedef BufferType MutableBuffer; typedef boost::asio::mutable_buffer MutableBuffer; /** Meets the requirements of ConstBufferSequence */ diff --git a/modules/beast_asio/beast_asio.cpp b/modules/beast_asio/beast_asio.cpp index 624bafaf3f..3236c33aa1 100644 --- a/modules/beast_asio/beast_asio.cpp +++ b/modules/beast_asio/beast_asio.cpp @@ -29,7 +29,6 @@ namespace beast { #include "async/SharedHandler.cpp" -#include "basics/ContentBodyBuffer.cpp" #include "basics/PeerRole.cpp" #include "basics/SSLContext.cpp" diff --git a/modules/beast_asio/beast_asio.h b/modules/beast_asio/beast_asio.h index 67eebfc1d5..e00b609314 100644 --- a/modules/beast_asio/beast_asio.h +++ b/modules/beast_asio/beast_asio.h @@ -70,9 +70,7 @@ namespace beast { #include "async/SharedHandlerAllocator.h" #include "async/AsyncObject.h" -# include "basics/BufferType.h" # include "basics/BuffersType.h" -#include "basics/ContentBodyBuffer.h" #include "basics/FixedInputBuffer.h" #include "basics/PeerRole.h" #include "basics/SSLContext.h" diff --git a/modules/beast_asio/http/HTTPMessage.cpp b/modules/beast_asio/http/HTTPMessage.cpp index c08c549bf1..698ec0dcc9 100644 --- a/modules/beast_asio/http/HTTPMessage.cpp +++ b/modules/beast_asio/http/HTTPMessage.cpp @@ -19,7 +19,7 @@ HTTPMessage::HTTPMessage (HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body) + DynamicBuffer& body) : m_version (version_) , m_headers (fields) { @@ -36,7 +36,7 @@ HTTPHeaders const& HTTPMessage::headers () const return m_headers; } -ContentBodyBuffer const& HTTPMessage::body () const +DynamicBuffer const& HTTPMessage::body () const { return m_body; } diff --git a/modules/beast_asio/http/HTTPMessage.h b/modules/beast_asio/http/HTTPMessage.h index 0280b0fb3a..f2ca3e5756 100644 --- a/modules/beast_asio/http/HTTPMessage.h +++ b/modules/beast_asio/http/HTTPMessage.h @@ -40,7 +40,7 @@ public: */ HTTPMessage (HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body); + DynamicBuffer& body); /** Returns the HTTP version of this message. */ HTTPVersion const& version () const; @@ -49,7 +49,7 @@ public: HTTPHeaders const& headers () const; /** Returns the content-body. */ - ContentBodyBuffer const& body () const; + DynamicBuffer const& body () const; /** Outputs all the HTTPMessage data excluding the body into a string. */ String toString () const; @@ -57,7 +57,7 @@ public: private: HTTPVersion m_version; HTTPHeaders m_headers; - ContentBodyBuffer m_body; + DynamicBuffer m_body; }; #endif diff --git a/modules/beast_asio/http/HTTPParserImpl.h b/modules/beast_asio/http/HTTPParserImpl.h index 344785907c..dfd8b1d8ee 100644 --- a/modules/beast_asio/http/HTTPParserImpl.h +++ b/modules/beast_asio/http/HTTPParserImpl.h @@ -125,7 +125,7 @@ public: return m_headersComplete; } - ContentBodyBuffer& body () + DynamicBuffer& body () { return m_body; } @@ -188,8 +188,9 @@ private: int onBody (char const* at, std::size_t length) { - m_body.commit (boost::asio::buffer_copy (m_body.prepare (length), - boost::asio::buffer (at, length))); + m_body.commit (boost::asio::buffer_copy ( + m_body.prepare (length), + boost::asio::buffer (at, length))); return 0; } @@ -258,7 +259,7 @@ private: std::string m_field; std::string m_value; bool m_headersComplete; - ContentBodyBuffer m_body; + DynamicBuffer m_body; }; #endif diff --git a/modules/beast_asio/http/HTTPRequest.cpp b/modules/beast_asio/http/HTTPRequest.cpp index 1d3efee961..f5a61c947e 100644 --- a/modules/beast_asio/http/HTTPRequest.cpp +++ b/modules/beast_asio/http/HTTPRequest.cpp @@ -20,7 +20,7 @@ HTTPRequest::HTTPRequest ( HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body, + DynamicBuffer& body, unsigned short method_) : HTTPMessage (version_, fields, body) , m_method (method_) diff --git a/modules/beast_asio/http/HTTPRequest.h b/modules/beast_asio/http/HTTPRequest.h index 0ae1a2594c..f21c30879a 100644 --- a/modules/beast_asio/http/HTTPRequest.h +++ b/modules/beast_asio/http/HTTPRequest.h @@ -30,7 +30,7 @@ public: HTTPRequest ( HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body, + DynamicBuffer& body, unsigned short method_); unsigned short method () const; diff --git a/modules/beast_asio/http/HTTPResponse.cpp b/modules/beast_asio/http/HTTPResponse.cpp index a4cd89a302..503a2eb208 100644 --- a/modules/beast_asio/http/HTTPResponse.cpp +++ b/modules/beast_asio/http/HTTPResponse.cpp @@ -20,7 +20,7 @@ HTTPResponse::HTTPResponse ( HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body, + DynamicBuffer& body, unsigned short status_) : HTTPMessage (version_, fields, body) , m_status (status_) diff --git a/modules/beast_asio/http/HTTPResponse.h b/modules/beast_asio/http/HTTPResponse.h index 7c7d80ff43..2edfc99f17 100644 --- a/modules/beast_asio/http/HTTPResponse.h +++ b/modules/beast_asio/http/HTTPResponse.h @@ -30,7 +30,7 @@ public: HTTPResponse ( HTTPVersion const& version_, StringPairArray& fields, - ContentBodyBuffer& body, + DynamicBuffer& body, unsigned short status_); unsigned short status () const;