diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
index d640a10e5..ebe6f0fe0 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -84,6 +84,7 @@
+
diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index a782b727c..a29fdd4db 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -158,6 +158,9 @@
{ccdc0c8e-f77a-486e-ba2f-29c10ec97f18}
+
+ {dfa79046-33ef-4653-a6f9-83954b76a10f}
+
@@ -845,6 +848,9 @@
beast_asio\protocol
+
+ beast_asio\streams
+
diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.h b/Subtrees/beast/modules/beast_asio/beast_asio.h
index 8b5ab9dc8..4006b8110 100644
--- a/Subtrees/beast/modules/beast_asio/beast_asio.h
+++ b/Subtrees/beast/modules/beast_asio/beast_asio.h
@@ -65,6 +65,8 @@ namespace beast
#include "protocol/beast_HandshakeDetectorType.h"
#include "protocol/beast_StreamHandshakeDetectorType.h"
+#include "streams/beast_prefilled_read_stream.h"
+
#include "tests/beast_TestPeerBasics.h"
#include "tests/beast_TestPeer.h"
#include "tests/beast_TestPeerDetails.h"
diff --git a/Subtrees/beast/modules/beast_asio/streams/beast_prefilled_read_stream.h b/Subtrees/beast/modules/beast_asio/streams/beast_prefilled_read_stream.h
new file mode 100644
index 000000000..a9ca192b3
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/streams/beast_prefilled_read_stream.h
@@ -0,0 +1,204 @@
+//------------------------------------------------------------------------------
+/*
+ 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_PREFILLEDREADSTREAM_H_INCLUDED
+#define BEAST_PREFILLEDREADSTREAM_H_INCLUDED
+
+/** Front-ends a stream with a provided block of data.
+
+ When read operations are performed on this object, bytes will first be
+ returned from the buffer provided on construction. When those bytes
+ are exhausted, read operations will then pass through to the underlying
+ stream.
+
+ Write operations are all simply passed through.
+*/
+template
+class PrefilledReadStream : public Uncopyable
+{
+protected:
+ typedef boost::system::error_code error_code;
+
+ void throw_error (error_code const& ec, char const* fileName, int lineNumber)
+ {
+ Throw (boost::system::system_error (ec), fileName, lineNumber);
+ }
+
+public:
+ typedef typename boost::remove_reference ::type 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
+ explicit PrefilledReadStream (Arg& arg)
+ : m_next_layer (arg)
+ {
+ }
+
+ /** Construct with the buffer, and argument passed through.
+ This creates a copy of the data. The argument is passed through
+ to the constructor of Stream.
+ */
+ template
+ PrefilledReadStream (Arg& arg, ConstBufferSequence const& buffers)
+ : m_next_layer (arg)
+ {
+ fill (buffers);
+ }
+
+ /** Place some input into the prefilled buffer.
+ Note that this is in no way thread safe. The only reason this function
+ 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
+ void fill (ConstBufferSequence const& buffers)
+ {
+ using namespace boost;
+ // We don't assume the caller's buffers will
+ // remain valid for the lifetime of this object.
+ //
+ m_buffer.commit (asio::buffer_copy (
+ m_buffer.prepare (asio::buffer_size (buffers)),
+ buffers));
+ }
+
+ next_layer_type& next_layer()
+ {
+ return m_next_layer;
+ }
+
+ next_layer_type const& next_layer() const
+ {
+ return m_next_layer;
+ }
+
+ lowest_layer_type& lowest_layer()
+ {
+ return m_next_layer.lowest_layer();
+ }
+
+ const lowest_layer_type& lowest_layer() const
+ {
+ return m_next_layer.lowest_layer();
+ }
+
+ boost::asio::io_service& get_io_service()
+ {
+ return m_next_layer.get_io_service();
+ }
+
+ void close()
+ {
+ m_next_layer.close();
+ }
+
+ error_code close(error_code& ec)
+ {
+ return m_next_layer.close(ec);
+ }
+
+ template
+ std::size_t write_some (ConstBufferSequence const& buffers)
+ {
+ return m_next_layer.write_some (buffers);
+ }
+
+ template
+ std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec)
+ {
+ return m_next_layer.write_some (buffers, ec);
+ }
+
+ template
+ std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec)
+ {
+ ec = error_code ();
+ if (m_buffer.size () > 0)
+ {
+ std::size_t const bytes_transferred = boost::asio::buffer_copy (
+ buffers, m_buffer.data ());
+ m_buffer.consume (bytes_transferred);
+ return bytes_transferred;
+ }
+ return m_next_layer.read_some (buffers, ec);
+ }
+
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void (error_code, std::size_t))
+ async_read_some (MutableBufferSequence const& buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ {
+ using namespace boost;
+ if (m_buffer.size () > 0)
+ {
+ std::size_t const bytes_transferred = asio::buffer_copy (
+ buffers, m_buffer.data ());
+ m_buffer.consume (bytes_transferred);
+
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ asio::detail::async_result_init <
+ ReadHandler, void (error_code, std::size_t)> init (
+ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+
+ get_io_service ().post (CompletionCall (
+ ReadHandler(init.handler), // handler is copied
+ error_code (), bytes_transferred));
+
+ return init.result.get();
+
+#else
+ return get_io_service ().post (CompletionCall (
+ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler),
+ error_code (), bytes_transferred));
+
+#endif
+ }
+
+ return m_next_layer.async_read_some (buffers,
+ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ }
+
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (error_code, std::size_t))
+ async_write_some (ConstBufferSequence const& buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+ {
+ return m_next_layer.async_write_some (buffers,
+ BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ }
+
+ template
+ 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__);
+ return amount;
+ }
+
+private:
+ Stream m_next_layer;
+ boost::asio::streambuf m_buffer;
+};
+
+#endif