From 8daecb543066040f27b2868e117a4f64677aaff0 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 1 Mar 2014 09:56:32 -0800 Subject: [PATCH] Add abstract streams module: * New basic_abstract_ostream template for generic output * New abstract_ostream, common type alias * basic_scoped_ostream, RAII output to abstract streams --- .../Builds/VisualStudio2013/beast.vcxproj | 4 + .../VisualStudio2013/beast.vcxproj.filters | 15 ++ src/beast/beast/streams/abstract_ostream.h | 32 ++++ .../beast/streams/basic_abstract_ostream.h | 118 ++++++++++++++ .../beast/streams/basic_scoped_ostream.h | 149 ++++++++++++++++++ src/beast/beast/streams/streams.cpp | 70 ++++++++ src/ripple/beast/ripple_beast.cpp | 1 + 7 files changed, 389 insertions(+) create mode 100644 src/beast/beast/streams/abstract_ostream.h create mode 100644 src/beast/beast/streams/basic_abstract_ostream.h create mode 100644 src/beast/beast/streams/basic_scoped_ostream.h create mode 100644 src/beast/beast/streams/streams.cpp 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"