mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Change Output to be a generic std::function.
This commit is contained in:
committed by
Vinnie Falco
parent
029c143922
commit
192cdd028e
@@ -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
|
||||
|
||||
@@ -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 <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 ()
|
||||
|
||||
@@ -127,7 +127,7 @@ class Writer
|
||||
public:
|
||||
enum CollectionType {array, object};
|
||||
|
||||
explicit Writer (Output& output);
|
||||
explicit Writer (Output output);
|
||||
Writer(Writer&&);
|
||||
Writer& operator=(Writer&&);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
void testTrivial ()
|
||||
{
|
||||
setup ("trivial");
|
||||
expect (output_.data.empty ());
|
||||
expect (output_.empty ());
|
||||
writer_->output (0);
|
||||
expectResult("0");
|
||||
}
|
||||
|
||||
@@ -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 + "'");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user