diff --git a/src/ripple/rpc/Output.h b/src/ripple/rpc/Output.h index e39dd108b..1584afe70 100644 --- a/src/ripple/rpc/Output.h +++ b/src/ripple/rpc/Output.h @@ -20,15 +20,20 @@ #ifndef RIPPLED_RIPPLE_BASICS_TYPES_OUTPUT_H #define RIPPLED_RIPPLE_BASICS_TYPES_OUTPUT_H +#include + namespace ripple { +namespace RPC { -class Output +using Output = std::function ; + +inline +Output stringOutput (std::string& s) { -public: - virtual void output (char const* data, size_t length) = 0; - virtual ~Output() = default; -}; + return [&](boost::string_ref const& b) { s.append (b.data(), b.size()); }; +} +} // RPC } // ripple #endif diff --git a/src/ripple/rpc/impl/JsonWriter.cpp b/src/ripple/rpc/impl/JsonWriter.cpp index 870405c1a..5873db6e5 100644 --- a/src/ripple/rpc/impl/JsonWriter.cpp +++ b/src/ripple/rpc/impl/JsonWriter.cpp @@ -63,51 +63,50 @@ size_t lengthWithoutTrailingZeros (std::string const& s) class Writer::Impl { public: - Impl (Output& output) : output_(output) {} + Impl (Output output) : output_(output) {} Impl(Impl&&) = delete; Impl& operator=(Impl&&) = delete; - bool empty() const { return stack_.empty (); } void start (CollectionType ct) { char ch = (ct == array) ? openBracket : openBrace; - output (&ch, 1); + output ({&ch, 1}); stack_.push (Collection()); stack_.top().type = ct; } - void output (char const* data, size_t size) + void output (boost::string_ref const& bytes) { markStarted (); - output_.output (data, size); + output_ (bytes); } - void stringOutput (char const* data, size_t size) + void stringOutput (boost::string_ref const& bytes) { markStarted (); - size_t position = 0, writtenUntil = 0; + std::size_t position = 0, writtenUntil = 0; - output_.output ("e, 1); - for (; position < size; ++position) + output_ ({"e, 1}); + auto data = bytes.data(); + for (; position < bytes.size(); ++position) { auto i = jsonSpecialCharacterEscape.find (data[position]); if (i != jsonSpecialCharacterEscape.end ()) { if (writtenUntil < position) { - output_.output ( - data + writtenUntil, position - writtenUntil); + output_ ({data + writtenUntil, position - writtenUntil}); } - output_.output (i->second, jsonEscapeLength); + output_ ({i->second, jsonEscapeLength}); writtenUntil = position + 1; }; } if (writtenUntil < position) - output_.output (data + writtenUntil, position - writtenUntil); - output_.output ("e, 1); + output_ ({data + writtenUntil, position - writtenUntil}); + output_ ({"e, 1}); } void markStarted () @@ -129,7 +128,7 @@ public: if (stack_.top ().isFirst) stack_.top ().isFirst = false; else - output (&comma, 1); + output_ ({&comma, 1}); } void writeObjectTag (std::string const& tag) @@ -141,8 +140,8 @@ public: tags.insert (tag); #endif - stringOutput (tag.data(), tag.size()); - output (&colon, 1); + stringOutput (tag); + output_ ({&colon, 1}); } bool isFinished() const @@ -156,7 +155,7 @@ public: auto isArray = stack_.top().type == array; auto ch = isArray ? closeBracket : closeBrace; - output (&ch, 1); + output_ ({&ch, 1}); stack_.pop(); } @@ -188,13 +187,13 @@ private: using Stack = std::stack >; - Output& output_; + Output output_; Stack stack_; bool isStarted_ = false; }; -Writer::Writer (Output& output) : impl_(std::make_unique (output)) +Writer::Writer (Output output) : impl_(std::make_unique (output)) { } @@ -216,39 +215,38 @@ Writer& Writer::operator=(Writer&& w) void Writer::output (char const* s) { - impl_->stringOutput (s, strlen (s)); + impl_->stringOutput (s); } void Writer::output (std::string const& s) { - impl_->stringOutput (s.data(), s.size ()); + impl_->stringOutput (s); } template <> void Writer::output (float f) { auto s = to_string (f); - impl_->output (s.data (), lengthWithoutTrailingZeros (s)); + impl_->output ({s.data (), lengthWithoutTrailingZeros (s)}); } template <> void Writer::output (double f) { auto s = to_string (f); - impl_->output (s.data (), lengthWithoutTrailingZeros (s)); + impl_->output ({s.data (), lengthWithoutTrailingZeros (s)}); } template <> void Writer::output (std::nullptr_t) { - impl_->output ("null", strlen("null")); + impl_->output ("null"); } template void Writer::output (Type t) { - auto s = to_string (t); - impl_->output (s.data(), s.size()); + impl_->output (to_string (t)); } void Writer::finishAll () diff --git a/src/ripple/rpc/impl/JsonWriter.h b/src/ripple/rpc/impl/JsonWriter.h index 55f56ec5e..70f4591b1 100644 --- a/src/ripple/rpc/impl/JsonWriter.h +++ b/src/ripple/rpc/impl/JsonWriter.h @@ -127,7 +127,7 @@ class Writer public: enum CollectionType {array, object}; - explicit Writer (Output& output); + explicit Writer (Output output); Writer(Writer&&); Writer& operator=(Writer&&); diff --git a/src/ripple/rpc/impl/JsonWriter_test.cpp b/src/ripple/rpc/impl/JsonWriter_test.cpp index e8de1344b..9eb136a77 100644 --- a/src/ripple/rpc/impl/JsonWriter_test.cpp +++ b/src/ripple/rpc/impl/JsonWriter_test.cpp @@ -31,7 +31,7 @@ public: void testTrivial () { setup ("trivial"); - expect (output_.data.empty ()); + expect (output_.empty ()); writer_->output (0); expectResult("0"); } diff --git a/src/ripple/rpc/impl/TestOutputSuite.h b/src/ripple/rpc/impl/TestOutputSuite.h index 604b633b8..86e7561b9 100644 --- a/src/ripple/rpc/impl/TestOutputSuite.h +++ b/src/ripple/rpc/impl/TestOutputSuite.h @@ -20,6 +20,7 @@ #ifndef RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H #define RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H +#include #include #include @@ -27,36 +28,32 @@ namespace ripple { namespace RPC { namespace New { -struct TestOutput : public Output -{ - void output (char const* s, size_t length) override - { - data.append (s, length); - } - - std::string data; -}; - - class TestOutputSuite : public beast::unit_test::suite { protected: - TestOutput output_; + std::string output_; + std::unique_ptr writer_; void setup (std::string const& testName) { testcase (testName); - output_.data.clear (); - writer_ = std::make_unique (output_); + output_.clear (); + writer_ = std::make_unique (stringOutput (output_)); } // Test the result and report values. void expectResult (std::string const& expected) { - expect (output_.data == expected, - "\nresult: " + output_.data + - "\nexpected: " + expected); + expectResult (output_, expected); + } + + // Test the result and report values. + void expectResult (std::string const& result, std::string const& expected) + { + expect (result == expected, + "\n" "result: '" + result + "'" + + "\n" "expected: '" + expected + "'"); } };