Change Output to be a generic std::function.

This commit is contained in:
Tom Ritchford
2014-12-01 17:11:04 -05:00
committed by Vinnie Falco
parent 029c143922
commit 192cdd028e
5 changed files with 51 additions and 51 deletions

View File

@@ -20,15 +20,20 @@
#ifndef RIPPLED_RIPPLE_BASICS_TYPES_OUTPUT_H
#define RIPPLED_RIPPLE_BASICS_TYPES_OUTPUT_H
#include <boost/utility/string_ref.hpp>
namespace ripple {
namespace RPC {
class Output
using Output = std::function <void (boost::string_ref const&)>;
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

View File

@@ -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 (&quote, 1);
for (; position < size; ++position)
output_ ({&quote, 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 (&quote, 1);
output_ ({data + writtenUntil, position - writtenUntil});
output_ ({&quote, 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 <Collection, std::vector<Collection>>;
Output& output_;
Output output_;
Stack stack_;
bool isStarted_ = false;
};
Writer::Writer (Output& output) : impl_(std::make_unique <Impl> (output))
Writer::Writer (Output output) : impl_(std::make_unique <Impl> (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 <typename Type>
void Writer::output (Type t)
{
auto s = to_string (t);
impl_->output (s.data(), s.size());
impl_->output (to_string (t));
}
void Writer::finishAll ()

View File

@@ -127,7 +127,7 @@ class Writer
public:
enum CollectionType {array, object};
explicit Writer (Output& output);
explicit Writer (Output output);
Writer(Writer&&);
Writer& operator=(Writer&&);

View File

@@ -31,7 +31,7 @@ public:
void testTrivial ()
{
setup ("trivial");
expect (output_.data.empty ());
expect (output_.empty ());
writer_->output (0);
expectResult("0");
}

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
#define RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
#include <ripple/rpc/Output.h>
#include <ripple/rpc/impl/JsonWriter.h>
#include <beast/unit_test/suite.h>
@@ -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> writer_;
void setup (std::string const& testName)
{
testcase (testName);
output_.data.clear ();
writer_ = std::make_unique <Writer> (output_);
output_.clear ();
writer_ = std::make_unique <Writer> (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 + "'");
}
};