diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj b/src/beast/Builds/VisualStudio2013/beast.vcxproj
index fdd8dc978..40f4a29a1 100644
--- a/src/beast/Builds/VisualStudio2013/beast.vcxproj
+++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj
@@ -204,6 +204,9 @@
+
+
+
@@ -681,6 +684,7 @@
true
+
true
true
diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
index 3a52abd38..080bb8b70 100644
--- a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
+++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
@@ -318,6 +318,9 @@
{84acd0d5-5531-470e-b9a7-42af9003aa64}
+
+ {899ea9a6-1969-4cde-b26d-8ad60acebfa4}
+
@@ -1332,6 +1335,15 @@
beast\workaround
+
+ beast\streams
+
+
+ beast\streams
+
+
+ beast\streams
+
@@ -1925,6 +1937,9 @@
beast\http\impl
+
+ beast\streams
+
diff --git a/src/beast/beast/streams/abstract_ostream.h b/src/beast/beast/streams/abstract_ostream.h
new file mode 100644
index 000000000..2063f219e
--- /dev/null
+++ b/src/beast/beast/streams/abstract_ostream.h
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+/*
+ 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_UTILITY_ABSTRACT_OSTREAM_H_INCLUDED
+#define BEAST_UTILITY_ABSTRACT_OSTREAM_H_INCLUDED
+
+#include "basic_abstract_ostream.h"
+
+namespace beast {
+
+/** An abstract ostream for `char`. */
+typedef basic_abstract_ostream abstract_ostream;
+
+}
+
+#endif
diff --git a/src/beast/beast/streams/basic_abstract_ostream.h b/src/beast/beast/streams/basic_abstract_ostream.h
new file mode 100644
index 000000000..00da5ed66
--- /dev/null
+++ b/src/beast/beast/streams/basic_abstract_ostream.h
@@ -0,0 +1,118 @@
+//------------------------------------------------------------------------------
+/*
+ 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_STREAMS_BASIC_ABSTRACT_OSTREAM_H_INCLUDED
+#define BEAST_STREAMS_BASIC_ABSTRACT_OSTREAM_H_INCLUDED
+
+#include "basic_scoped_ostream.h"
+
+#include
+#include
+#include
+
+namespace beast {
+
+/** Abstraction for an output stream similar to std::basic_ostream. */
+template <
+ class CharT,
+ class Traits = std::char_traits
+>
+class basic_abstract_ostream
+{
+public:
+ typedef std::basic_string string_type;
+ typedef basic_scoped_ostream scoped_stream_type;
+
+ basic_abstract_ostream() = default;
+
+ virtual
+ ~basic_abstract_ostream() = default;
+
+ basic_abstract_ostream (basic_abstract_ostream const&) = default;
+ basic_abstract_ostream& operator= (
+ basic_abstract_ostream const&) = default;
+
+ /** Returns `true` if the stream is active.
+ Inactive streams do not produce output.
+ */
+ /** @{ */
+ virtual
+ bool
+ active() const
+ {
+ return true;
+ }
+
+ explicit
+ operator bool() const
+ {
+ return active();
+ }
+ /** @} */
+
+ /** Returns a basic_scoped_ostream without appending anything.
+ This can be used if the caller wants to put the scoped stream
+ on the stack to build up output in a thread-safe fashion.
+ */
+#if 0
+ scoped_stream_type
+ scoped_stream ()
+ {
+#if 0
+ return scoped_stream_type (
+ [this](string_type const& s)
+ {
+ this->write (s);
+ });
+#else
+ return scoped_stream_type (*this);
+#endif
+ }
+#endif
+
+ /** Called to output each string. */
+ virtual
+ void
+ write (string_type const& s) = 0;
+
+ scoped_stream_type
+ operator<< (std::ostream& manip (std::ostream&))
+ {
+ return scoped_stream_type (manip,
+ [this](string_type const& s)
+ {
+ this->write (s);
+ });
+ }
+
+ template
+ scoped_stream_type
+ operator<< (T const& t)
+ {
+ return scoped_stream_type (t,
+ [this](string_type const& s)
+ {
+ this->write (s);
+ });
+ }
+};
+
+}
+
+#endif
diff --git a/src/beast/beast/streams/basic_scoped_ostream.h b/src/beast/beast/streams/basic_scoped_ostream.h
new file mode 100644
index 000000000..71f97bb30
--- /dev/null
+++ b/src/beast/beast/streams/basic_scoped_ostream.h
@@ -0,0 +1,149 @@
+//------------------------------------------------------------------------------
+/*
+ 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_STREAMS_BASIC_SCOPED_OSTREAM_H_INCLUDED
+#define BEAST_STREAMS_BASIC_SCOPED_OSTREAM_H_INCLUDED
+
+#include "../cxx14/memory.h" //
+#include
+#include
+#include
+
+// gcc libstd++ doesn't have move constructors for basic_ostringstream
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316
+//
+#ifndef BEAST_NO_STDLIB_STREAM_MOVE
+# ifdef __GLIBCXX__
+# define BEAST_NO_STDLIB_STREAM_MOVE 1
+# else
+# define BEAST_NO_STDLIB_STREAM_MOVE 0
+# endif
+#endif
+
+namespace beast {
+
+template <
+ class CharT,
+ class Traits
+>
+class basic_abstract_ostream;
+
+/** Scoped output stream that forwards to a functor upon destruction. */
+template <
+ class CharT,
+ class Traits = std::char_traits ,
+ class Allocator = std::allocator
+>
+class basic_scoped_ostream
+{
+private:
+ typedef std::function const&)> handler_t;
+
+ typedef std::basic_ostringstream <
+ CharT, Traits, Allocator> stream_type;
+
+ handler_t m_handler;
+
+#if BEAST_NO_STDLIB_STREAM_MOVE
+ std::unique_ptr m_ss;
+
+ stream_type& stream()
+ {
+ return *m_ss;
+ }
+
+#else
+ stream_type m_ss;
+
+ stream_type& stream()
+ {
+ return m_ss;
+ }
+
+#endif
+
+public:
+ typedef std::basic_string string_type;
+
+ // Disallow copy since that would duplicate the output
+ basic_scoped_ostream (basic_scoped_ostream const&) = delete;
+ basic_scoped_ostream& operator= (basic_scoped_ostream const) = delete;
+
+ template
+ explicit basic_scoped_ostream (Handler&& handler)
+ : m_handler (std::forward (handler))
+ #if BEAST_NO_STDLIB_STREAM_MOVE
+ , m_ss (std::make_unique ())
+ #endif
+ {
+ }
+
+ template
+ basic_scoped_ostream (T const& t, Handler&& handler)
+ : m_handler (std::forward (handler))
+ #if BEAST_NO_STDLIB_STREAM_MOVE
+ , m_ss (std::make_unique ())
+ #endif
+ {
+ stream() << t;
+ }
+
+ basic_scoped_ostream (basic_abstract_ostream <
+ CharT, Traits>& ostream)
+ : m_handler (
+ [&](string_type const& s)
+ {
+ ostream.write (s);
+ })
+ {
+ }
+
+ basic_scoped_ostream (basic_scoped_ostream&& other)
+ : m_handler (std::move (other.m_handler))
+ , m_ss (std::move (other.m_ss))
+ {
+ }
+
+ ~basic_scoped_ostream()
+ {
+ auto const& s (stream().str());
+ if (! s.empty())
+ m_handler (s);
+ }
+
+ basic_scoped_ostream&
+ operator<< (std::ostream& manip (std::ostream&))
+ {
+ stream() << manip;
+ return *this;
+ }
+
+ template
+ basic_scoped_ostream&
+ operator<< (T const& t)
+ {
+ stream() << t;
+ return *this;
+ }
+};
+
+}
+
+#endif
diff --git a/src/beast/beast/streams/streams.cpp b/src/beast/beast/streams/streams.cpp
new file mode 100644
index 000000000..a38a0f11d
--- /dev/null
+++ b/src/beast/beast/streams/streams.cpp
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+/*
+ 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.
+*/
+//==============================================================================
+
+#if BEAST_INCLUDE_BEASTCONFIG
+#include "../../BeastConfig.h"
+#endif
+
+#include "../../modules/beast_core/beast_core.h"
+
+#include "basic_abstract_ostream.h"
+
+namespace beast {
+
+class streams_Tests : public UnitTest
+{
+public:
+ class test_stream : public basic_abstract_ostream
+ {
+ public:
+ explicit test_stream (UnitTest& test)
+ : m_test (test)
+ {
+ }
+
+ void write (string_type const& s) override
+ {
+ m_test.logMessage (s);
+ }
+
+ test_stream& operator= (test_stream const&) = delete;
+
+ private:
+ UnitTest& m_test;
+ };
+
+ void runTest()
+ {
+ beginTestCase ("stream");
+
+ test_stream ts (*this);
+
+ ts << "Hello";
+
+ pass();
+ }
+
+ streams_Tests() : UnitTest ("streams", "beast")
+ {
+ }
+};
+
+static streams_Tests streams_tests;
+
+}
diff --git a/src/ripple/beast/ripple_beast.cpp b/src/ripple/beast/ripple_beast.cpp
index 36eb156f1..d50e1854d 100644
--- a/src/ripple/beast/ripple_beast.cpp
+++ b/src/ripple/beast/ripple_beast.cpp
@@ -41,6 +41,7 @@
#include "../beast/beast/insight/Insight.cpp"
#include "../beast/beast/net/Net.cpp"
#include "../beast/beast/smart_ptr/SmartPtr.cpp"
+#include "../beast/beast/streams/streams.cpp"
#include "../beast/beast/strings/Strings.cpp"
#include "../beast/beast/threads/Threads.cpp"
#include "../beast/beast/utility/Utility.cpp"