mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-26 22:15:52 +00:00
Better interoperation between Json::Value and JsonObject.
* Generic functions to add entries to both object models. * Add Json::Value into JsonObjects. * Write Json::Value to string incrementally. * Get rid of ripple::RPC::New namespace
This commit is contained in:
committed by
Vinnie Falco
parent
7cfac1a91a
commit
8053598069
@@ -2812,6 +2812,8 @@
|
||||
</ClInclude>
|
||||
<None Include="..\..\src\ripple\resource\README.md">
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\Coroutine.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\ErrorCodes.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\handlers\AccountCurrencies.cpp">
|
||||
@@ -3008,6 +3010,12 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Context.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\DoPrint.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\ErrorCodes.cpp">
|
||||
@@ -3028,7 +3036,7 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonObject.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.cpp">
|
||||
@@ -3036,7 +3044,7 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonWriter.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\LegacyPathFind.cpp">
|
||||
@@ -3063,7 +3071,7 @@
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\TestOutputSuite.h">
|
||||
@@ -3075,10 +3083,15 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Tuning.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield_test.cpp">
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\WriteJson.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\InternalHandler.h">
|
||||
|
||||
@@ -3906,6 +3906,9 @@
|
||||
<None Include="..\..\src\ripple\resource\README.md">
|
||||
<Filter>ripple\resource</Filter>
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\Coroutine.h">
|
||||
<Filter>ripple\rpc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\ErrorCodes.h">
|
||||
<Filter>ripple\rpc</Filter>
|
||||
</ClInclude>
|
||||
@@ -4107,6 +4110,12 @@
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Context.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Coroutine.test.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\DoPrint.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
@@ -4131,7 +4140,7 @@
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonObject.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonObject.test.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.cpp">
|
||||
@@ -4140,7 +4149,7 @@
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\JsonWriter.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\JsonWriter.test.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\LegacyPathFind.cpp">
|
||||
@@ -4170,7 +4179,7 @@
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status_test.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Status.test.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\TestOutputSuite.h">
|
||||
@@ -4185,10 +4194,16 @@
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Tuning.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield_test.cpp">
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\WriteJson.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.test.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Yield.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\InternalHandler.h">
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
/** Status represents the results of an operation that might fail.
|
||||
|
||||
@@ -114,7 +113,6 @@ private:
|
||||
Strings messages_;
|
||||
};
|
||||
|
||||
} // namespace New
|
||||
} // namespace RPC
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/JsonObject.h>
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
Collection::Collection (Collection* parent, Writer* writer)
|
||||
: parent_ (parent), writer_ (writer), enabled_ (true)
|
||||
@@ -71,31 +69,9 @@ void Collection::checkWritable (std::string const& label)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Scalar>
|
||||
Array& Array::append (Scalar value)
|
||||
{
|
||||
checkWritable ("append");
|
||||
if (writer_)
|
||||
writer_->append (value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Object::Root::Root (Writer& w) : Object (nullptr, &w)
|
||||
{
|
||||
writer_->startRoot (Writer::object); // writer_ can't be null.
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Scalar>
|
||||
Object& Object::set (std::string const& key, Scalar value)
|
||||
{
|
||||
checkWritable ("set");
|
||||
if (writer_)
|
||||
writer_->set (key, value);
|
||||
return *this;
|
||||
writer_->startRoot (Writer::object);
|
||||
}
|
||||
|
||||
Object Object::makeObject (std::string const& key)
|
||||
@@ -113,6 +89,8 @@ Array Object::makeArray (std::string const& key) {
|
||||
return Array (this, writer_);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Object Array::makeObject ()
|
||||
{
|
||||
checkWritable ("Array::makeObject");
|
||||
@@ -139,9 +117,44 @@ Object::Proxy::Proxy (Object& object, std::string const& key)
|
||||
|
||||
Object::Proxy Object::operator[] (std::string const& key)
|
||||
{
|
||||
return {*this, key};
|
||||
return Proxy (*this, key);
|
||||
}
|
||||
|
||||
Object::Proxy Object::operator[] (Json::StaticString const& key)
|
||||
{
|
||||
return Proxy (*this, std::string (key));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <class Object>
|
||||
void doCopyFrom (Object& to, Json::Value const& from)
|
||||
{
|
||||
auto members = from.getMemberNames();
|
||||
for (auto& m: members)
|
||||
to[m] = from[m];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void copyFrom (Json::Value& to, Json::Value const& from)
|
||||
{
|
||||
if (to.empty()) // Short circuit this very common case.
|
||||
to = from;
|
||||
else
|
||||
doCopyFrom (to, from);
|
||||
}
|
||||
|
||||
void copyFrom (Object& to, Json::Value const& from)
|
||||
{
|
||||
doCopyFrom (to, from);
|
||||
}
|
||||
|
||||
|
||||
WriterObject stringWriterObject (std::string& s)
|
||||
{
|
||||
return WriterObject (stringOutput (s));
|
||||
}
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
#ifndef RIPPLED_RIPPLE_RPC_IMPL_JSONCOLLECTIONS_H
|
||||
#define RIPPLED_RIPPLE_RPC_IMPL_JSONCOLLECTIONS_H
|
||||
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
class Writer;
|
||||
|
||||
/**
|
||||
Collection is a base class for Array and Object, classes which provide the
|
||||
@@ -32,8 +31,8 @@ class Writer;
|
||||
heap memory and only a very small amount of stack.
|
||||
|
||||
From http://json.org, JSON has two types of collection: array, and object.
|
||||
Everything else is a *scalar* - a number, a string, a boolean or the special
|
||||
value null.
|
||||
Everything else is a *scalar* - a number, a string, a boolean, the special
|
||||
value null, or a legacy Json::Value.
|
||||
|
||||
Collections must write JSON "as-it-goes" in order to get the strong
|
||||
performance guarantees. This puts restrictions upon API users:
|
||||
@@ -182,7 +181,8 @@ public:
|
||||
|
||||
/** Set a scalar value in the Object for a key.
|
||||
|
||||
A JSON scalar is a single value - a number, string, boolean or null.
|
||||
A JSON scalar is a single value - a number, string, boolean, nullptr or
|
||||
a Json::Value.
|
||||
|
||||
`set()` throws an exception if this object is disabled (which means that
|
||||
one of its children is enabled).
|
||||
@@ -193,11 +193,13 @@ public:
|
||||
An operator[] is provided to allow writing `object["key"] = scalar;`.
|
||||
*/
|
||||
template <typename Scalar>
|
||||
Object& set (std::string const& key, Scalar);
|
||||
Object& set (std::string const& key, Scalar const&);
|
||||
|
||||
// Detail class and method used to implement operator[].
|
||||
class Proxy;
|
||||
|
||||
Proxy operator[] (std::string const& key);
|
||||
Proxy operator[] (Json::StaticString const& key);
|
||||
|
||||
/** Make a new Object at a key and return it.
|
||||
|
||||
@@ -218,8 +220,6 @@ protected:
|
||||
Object (Collection* parent, Writer* w) : Collection (parent, w) {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class Object::Root : public Object
|
||||
{
|
||||
public:
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
its sub-collections is enabled).
|
||||
*/
|
||||
template <typename Scalar>
|
||||
Array& append (Scalar);
|
||||
Array& append (const Scalar&);
|
||||
|
||||
/** Append a new Object and return it.
|
||||
|
||||
@@ -262,12 +262,71 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Generic accessor functions to allow Json::Value and Collection to
|
||||
// interoperate.
|
||||
|
||||
/** Add a new subarray at a named key in a Json object. */
|
||||
Json::Value& addArray (Json::Value&, Json::StaticString const& key);
|
||||
|
||||
/** Add a new subarray at a named key in a Json object. */
|
||||
Array addArray (Object&, Json::StaticString const& key);
|
||||
|
||||
/** Add a new subobject at a named key in a Json object. */
|
||||
Json::Value& addObject (Json::Value&, Json::StaticString const& key);
|
||||
|
||||
/** Add a new subobject at a named key in a Json object. */
|
||||
Object addObject (Object&, Json::StaticString const& key);
|
||||
|
||||
/** Copy all the keys and values from one object into another. */
|
||||
void copyFrom (Json::Value& to, Json::Value const& from);
|
||||
|
||||
/** Copy all the keys and values from one object into another. */
|
||||
void copyFrom (Object& to, Json::Value const& from);
|
||||
|
||||
/** An Object that contains its own Writer. */
|
||||
class WriterObject
|
||||
{
|
||||
public:
|
||||
WriterObject (Output const& output)
|
||||
: writer_ (std::make_unique<Writer> (output)),
|
||||
object_ (std::make_unique<Object::Root> (*writer_))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
WriterObject (WriterObject&& other)
|
||||
: writer_ (std::move (other.writer_)),
|
||||
object_ (std::move (other.object_))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
Object* operator->()
|
||||
{
|
||||
return object_.get();
|
||||
}
|
||||
|
||||
Object& operator*()
|
||||
{
|
||||
return *object_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr <Writer> writer_;
|
||||
std::unique_ptr<Object::Root> object_;
|
||||
};
|
||||
|
||||
WriterObject stringWriterObject (std::string&);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Implementation details.
|
||||
|
||||
// Detail class for Object::operator[].
|
||||
class Object::Proxy
|
||||
{
|
||||
private:
|
||||
Object& object_;
|
||||
std::string const& key_;
|
||||
std::string const key_;
|
||||
|
||||
public:
|
||||
Proxy (Object& object, std::string const& key);
|
||||
@@ -280,7 +339,50 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // New
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Scalar>
|
||||
Array& Array::append (Scalar const& value)
|
||||
{
|
||||
checkWritable ("append");
|
||||
if (writer_)
|
||||
writer_->append (value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
Object& Object::set (std::string const& key, Scalar const& value)
|
||||
{
|
||||
checkWritable ("set");
|
||||
if (writer_)
|
||||
writer_->set (key, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Json::Value& addArray (Json::Value& json, Json::StaticString const& key)
|
||||
{
|
||||
return (json[key] = Json::arrayValue);
|
||||
}
|
||||
|
||||
inline
|
||||
Array addArray (Object& json, Json::StaticString const& key)
|
||||
{
|
||||
return json.makeArray (std::string (key));
|
||||
}
|
||||
|
||||
inline
|
||||
Json::Value& addObject (Json::Value& json, Json::StaticString const& key)
|
||||
{
|
||||
return (json[key] = Json::objectValue);
|
||||
}
|
||||
|
||||
inline
|
||||
Object addObject (Object& object, Json::StaticString const& key)
|
||||
{
|
||||
return object.makeObject (std::string (key));
|
||||
}
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -23,17 +23,37 @@
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
class JsonObject_test : public TestOutputSuite
|
||||
{
|
||||
void setup (std::string const& testName)
|
||||
{
|
||||
testcase (testName);
|
||||
output_.clear ();
|
||||
}
|
||||
|
||||
std::unique_ptr<WriterObject> writerObject_;
|
||||
|
||||
Object& makeRoot()
|
||||
{
|
||||
writerObject_ = std::make_unique<WriterObject> (
|
||||
stringWriterObject (output_));
|
||||
return **writerObject_;
|
||||
}
|
||||
|
||||
void expectResult (std::string const& expected)
|
||||
{
|
||||
writerObject_.reset();
|
||||
TestOutputSuite::expectResult (expected);
|
||||
}
|
||||
|
||||
public:
|
||||
void testTrivial ()
|
||||
{
|
||||
setup ("trivial");
|
||||
|
||||
{
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
(void) root;
|
||||
}
|
||||
expectResult ("{}");
|
||||
@@ -43,7 +63,7 @@ public:
|
||||
{
|
||||
setup ("simple");
|
||||
{
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
root["hello"] = "world";
|
||||
root["skidoo"] = 23;
|
||||
root["awake"] = false;
|
||||
@@ -60,7 +80,7 @@ public:
|
||||
void testSimpleShort ()
|
||||
{
|
||||
setup ("simpleShort");
|
||||
Object::Root (*writer_)
|
||||
makeRoot()
|
||||
.set ("hello", "world")
|
||||
.set ("skidoo", 23)
|
||||
.set ("awake", false)
|
||||
@@ -77,7 +97,7 @@ public:
|
||||
{
|
||||
setup ("oneSub");
|
||||
{
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
root.makeArray ("ar");
|
||||
}
|
||||
expectResult ("{\"ar\":[]}");
|
||||
@@ -87,7 +107,7 @@ public:
|
||||
{
|
||||
setup ("subs");
|
||||
{
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
|
||||
{
|
||||
// Add an array with three entries.
|
||||
@@ -122,7 +142,7 @@ public:
|
||||
setup ("subsShort");
|
||||
|
||||
{
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
|
||||
// Add an array with three entries.
|
||||
root.makeArray ("ar")
|
||||
@@ -163,19 +183,19 @@ public:
|
||||
{
|
||||
{
|
||||
setup ("object failure assign");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeObject ("o1");
|
||||
expectException ([&]() { root["fail"] = "complete"; });
|
||||
}
|
||||
{
|
||||
setup ("object failure object");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeObject ("o1");
|
||||
expectException ([&] () { root.makeObject ("o2"); });
|
||||
}
|
||||
{
|
||||
setup ("object failure Array");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeArray ("o1");
|
||||
expectException ([&] () { root.makeArray ("o2"); });
|
||||
}
|
||||
@@ -185,7 +205,7 @@ public:
|
||||
{
|
||||
{
|
||||
setup ("array failure append");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.append ("fail"); };
|
||||
@@ -193,7 +213,7 @@ public:
|
||||
}
|
||||
{
|
||||
setup ("array failure makeArray");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.makeArray (); };
|
||||
@@ -201,7 +221,7 @@ public:
|
||||
}
|
||||
{
|
||||
setup ("array failure makeObject");
|
||||
Object::Root root (*writer_);
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.makeObject (); };
|
||||
@@ -213,7 +233,7 @@ public:
|
||||
{
|
||||
#ifdef DEBUG
|
||||
setup ("repeating keys");
|
||||
Object::Root root(*writer_);
|
||||
auto& root = makeRoot();
|
||||
root.set ("foo", "bar")
|
||||
.set ("baz", 0);
|
||||
auto fail = [&]() { root.set ("foo", "bar"); };
|
||||
@@ -223,6 +243,7 @@ public:
|
||||
|
||||
void run () override
|
||||
{
|
||||
testTrivial ();
|
||||
testSimple ();
|
||||
testSimpleShort ();
|
||||
|
||||
@@ -238,6 +259,5 @@ public:
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(JsonObject, ripple_basics, ripple);
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -18,11 +18,11 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
#include <ripple/rpc/impl/WriteJson.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -37,7 +37,7 @@ std::map <char, const char*> jsonSpecialCharacterEscape = {
|
||||
{'\t', "\\t"}
|
||||
};
|
||||
|
||||
static int const jsonEscapeLength = 2;
|
||||
static size_t const jsonEscapeLength = 2;
|
||||
|
||||
// All other JSON punctuation.
|
||||
const char closeBrace = '}';
|
||||
@@ -50,12 +50,24 @@ const char quote = '"';
|
||||
|
||||
const std::string none;
|
||||
|
||||
static auto const integralFloatsBecomeInts = false;
|
||||
|
||||
size_t lengthWithoutTrailingZeros (std::string const& s)
|
||||
{
|
||||
if (s.find ('.') == std::string::npos)
|
||||
auto dotPos = s.find ('.');
|
||||
if (dotPos == std::string::npos)
|
||||
return s.size();
|
||||
|
||||
return s.find_last_not_of ('0') + 1;
|
||||
auto lastNonZero = s.find_last_not_of ('0');
|
||||
auto hasDecimals = dotPos != lastNonZero;
|
||||
|
||||
if (hasDecimals)
|
||||
return lastNonZero + 1;
|
||||
|
||||
if (integralFloatsBecomeInts || lastNonZero + 2 > s.size())
|
||||
return lastNonZero;
|
||||
|
||||
return lastNonZero + 2;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -63,7 +75,8 @@ size_t lengthWithoutTrailingZeros (std::string const& s)
|
||||
class Writer::Impl
|
||||
{
|
||||
public:
|
||||
Impl (Output output) : output_(output) {}
|
||||
Impl (Output const& output) : output_(output) {}
|
||||
~Impl() = default;
|
||||
|
||||
Impl(Impl&&) = delete;
|
||||
Impl& operator=(Impl&&) = delete;
|
||||
@@ -168,6 +181,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Output const& getOutput() const { return output_; }
|
||||
|
||||
private:
|
||||
// JSON collections are either arrrays, or objects.
|
||||
struct Collection
|
||||
@@ -193,12 +208,14 @@ private:
|
||||
bool isStarted_ = false;
|
||||
};
|
||||
|
||||
Writer::Writer (Output output) : impl_(std::make_unique <Impl> (output))
|
||||
Writer::Writer (Output const &output)
|
||||
: impl_(std::make_unique <Impl> (output))
|
||||
{
|
||||
}
|
||||
|
||||
Writer::~Writer()
|
||||
{
|
||||
if (impl_)
|
||||
impl_->finishAll ();
|
||||
}
|
||||
|
||||
@@ -223,6 +240,12 @@ void Writer::output (std::string const& s)
|
||||
impl_->stringOutput (s);
|
||||
}
|
||||
|
||||
void Writer::output (Json::Value const& value)
|
||||
{
|
||||
impl_->markStarted();
|
||||
writeJson (value, impl_->getOutput());
|
||||
}
|
||||
|
||||
template <>
|
||||
void Writer::output (float f)
|
||||
{
|
||||
@@ -243,37 +266,32 @@ void Writer::output (std::nullptr_t)
|
||||
impl_->output ("null");
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Writer::output (Type t)
|
||||
void Writer::implOutput (std::string const& s)
|
||||
{
|
||||
impl_->output (to_string (t));
|
||||
impl_->output (s);
|
||||
}
|
||||
|
||||
void Writer::finishAll ()
|
||||
{
|
||||
if (impl_)
|
||||
impl_->finishAll ();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Writer::append (Type t)
|
||||
void Writer::rawAppend()
|
||||
{
|
||||
impl_->nextCollectionEntry (array, "append");
|
||||
output (t);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Writer::set (std::string const& tag, Type t)
|
||||
void Writer::rawSet (std::string const& tag)
|
||||
{
|
||||
check (!tag.empty(), "Tag can't be empty");
|
||||
|
||||
impl_->nextCollectionEntry (object, "set");
|
||||
impl_->writeObjectTag (tag);
|
||||
output (t);
|
||||
}
|
||||
|
||||
void Writer::startRoot (CollectionType type)
|
||||
{
|
||||
check (impl_->empty(), "stack_ not empty() in start");
|
||||
impl_->start (type);
|
||||
}
|
||||
|
||||
@@ -292,9 +310,9 @@ void Writer::startSet (CollectionType type, std::string const& key)
|
||||
|
||||
void Writer::finish ()
|
||||
{
|
||||
if (impl_)
|
||||
impl_->finish ();
|
||||
}
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include <ripple/basics/ToString.h>
|
||||
#include <ripple/rpc/Output.h>
|
||||
#include <ripple/rpc/ErrorCodes.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
/**
|
||||
* Writer implements an O(1)-space, O(1)-granular output JSON writer.
|
||||
@@ -127,13 +127,13 @@ class Writer
|
||||
public:
|
||||
enum CollectionType {array, object};
|
||||
|
||||
explicit Writer (Output output);
|
||||
explicit Writer (Output const& output);
|
||||
Writer(Writer&&);
|
||||
Writer& operator=(Writer&&);
|
||||
|
||||
~Writer();
|
||||
|
||||
/** Start a new collection at the root level. May only be called once. */
|
||||
/** Start a new collection at the root level. */
|
||||
void startRoot (CollectionType);
|
||||
|
||||
/** Start a new collection inside an array. */
|
||||
@@ -152,10 +152,18 @@ public:
|
||||
/** Append a value to an array.
|
||||
*
|
||||
* Scalar must be a scalar - that is, a number, boolean, string, string
|
||||
* literal, or nullptr.
|
||||
* literal, nullptr or Json::Value
|
||||
*/
|
||||
template <typename Scalar>
|
||||
void append (Scalar);
|
||||
void append (Scalar t)
|
||||
{
|
||||
rawAppend();
|
||||
output (t);
|
||||
}
|
||||
|
||||
/** Add a comma before this next item if not the first item in an array.
|
||||
Useful if you are writing the actual array yourself. */
|
||||
void rawAppend();
|
||||
|
||||
/** Add a key, value assignment to an object.
|
||||
*
|
||||
@@ -168,8 +176,16 @@ public:
|
||||
* If CHECK_JSON_WRITER is defined, this function throws an exception if if
|
||||
* the tag you use has already been used in this object.
|
||||
*/
|
||||
template <typename Scalar>
|
||||
void set (std::string const& key, Scalar value);
|
||||
template <typename Type>
|
||||
void set (std::string const& tag, Type t)
|
||||
{
|
||||
rawSet (tag);
|
||||
output (t);
|
||||
}
|
||||
|
||||
/** Emit just "tag": as part of an object. Useful if you are writing the
|
||||
actual value data yourself. */
|
||||
void rawSet (std::string const& key);
|
||||
|
||||
// You won't need to call anything below here until you are writing single
|
||||
// items (numbers, strings, bools, null) to a JSON stream.
|
||||
@@ -180,13 +196,32 @@ public:
|
||||
/*** Output a literal constant or C string. */
|
||||
void output (char const*);
|
||||
|
||||
/*** Output a literal constant or C string. */
|
||||
void output (Json::Value const&);
|
||||
|
||||
/** Output numbers, booleans, or nullptr. */
|
||||
template <typename Scalar>
|
||||
void output (Scalar t);
|
||||
template <typename Type>
|
||||
void output (Type t)
|
||||
{
|
||||
implOutput (to_string (t));
|
||||
}
|
||||
|
||||
/** Output an error code. */
|
||||
void output (error_code_i t)
|
||||
{
|
||||
output (int(t));
|
||||
}
|
||||
|
||||
void output (Json::StaticString const& t)
|
||||
{
|
||||
output (t.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr <Impl> impl_;
|
||||
|
||||
void implOutput (std::string const&);
|
||||
};
|
||||
|
||||
class JsonException : public std::exception
|
||||
@@ -208,7 +243,6 @@ inline void check (bool condition, std::string const& message)
|
||||
throw JsonException (message);
|
||||
}
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/json/json_writer.h>
|
||||
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
class JsonWriter_test : public TestOutputSuite
|
||||
{
|
||||
@@ -32,6 +33,13 @@ public:
|
||||
{
|
||||
setup ("trivial");
|
||||
expect (output_.empty ());
|
||||
expectResult("");
|
||||
}
|
||||
|
||||
void testNearTrivial ()
|
||||
{
|
||||
setup ("near trivial");
|
||||
expect (output_.empty ());
|
||||
writer_->output (0);
|
||||
expectResult("0");
|
||||
}
|
||||
@@ -50,6 +58,10 @@ public:
|
||||
writer_->output (23);
|
||||
expectResult ("23");
|
||||
|
||||
setup ("23.0");
|
||||
writer_->output (23.0);
|
||||
expectResult ("23.0");
|
||||
|
||||
setup ("23.5");
|
||||
writer_->output (23.5);
|
||||
expectResult ("23.5");
|
||||
@@ -161,9 +173,22 @@ public:
|
||||
"\"subarray\":[23.5]}]]}");
|
||||
}
|
||||
|
||||
void testJson ()
|
||||
{
|
||||
setup ("object");
|
||||
Json::Value value (Json::objectValue);
|
||||
value["foo"] = 23;
|
||||
writer_->startRoot (Writer::object);
|
||||
writer_->set ("hello", value);
|
||||
writer_->finish ();
|
||||
|
||||
expectResult ("{\"hello\":{\"foo\":23}}");
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
testTrivial ();
|
||||
testNearTrivial ();
|
||||
testPrimitives ();
|
||||
testEmpty ();
|
||||
testEscaping ();
|
||||
@@ -172,11 +197,11 @@ public:
|
||||
testEmbeddedArraySimple ();
|
||||
testObject ();
|
||||
testComplexObject ();
|
||||
testJson();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(JsonWriter, ripple_basics, ripple);
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
std::string Status::codeString () const
|
||||
{
|
||||
@@ -72,6 +71,5 @@ void Status::fillJson (Json::Value& value)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace New
|
||||
} // namespace RPC
|
||||
} // ripple
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
class codeString_test : public beast::unit_test::suite
|
||||
{
|
||||
@@ -209,6 +208,5 @@ public:
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (fillJson, Status, RPC);
|
||||
|
||||
} // namespace New
|
||||
} // namespace RPC
|
||||
} // ripple
|
||||
@@ -26,13 +26,11 @@
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
namespace New {
|
||||
|
||||
class TestOutputSuite : public beast::unit_test::suite
|
||||
{
|
||||
protected:
|
||||
std::string output_;
|
||||
|
||||
std::unique_ptr <Writer> writer_;
|
||||
|
||||
void setup (std::string const& testName)
|
||||
@@ -46,6 +44,7 @@ protected:
|
||||
void expectResult (std::string const& expected)
|
||||
{
|
||||
writer_.reset ();
|
||||
|
||||
expectEquals (output_, expected);
|
||||
}
|
||||
|
||||
@@ -58,7 +57,6 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
} // New
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
|
||||
112
src/ripple/rpc/impl/WriteJson.cpp
Normal file
112
src/ripple/rpc/impl/WriteJson.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/WriteJson.h>
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
namespace {
|
||||
|
||||
void writeJson (Json::Value const& value, Writer& writer)
|
||||
{
|
||||
switch (value.type())
|
||||
{
|
||||
case Json::nullValue:
|
||||
{
|
||||
writer.output (nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::intValue:
|
||||
{
|
||||
writer.output (value.asInt());
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::uintValue:
|
||||
{
|
||||
writer.output (value.asUInt());
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::realValue:
|
||||
{
|
||||
writer.output (value.asDouble());
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::stringValue:
|
||||
{
|
||||
writer.output (value.asString());
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::booleanValue:
|
||||
{
|
||||
writer.output (value.asBool());
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::arrayValue:
|
||||
{
|
||||
writer.startRoot (Writer::array);
|
||||
for (auto const& i: value)
|
||||
{
|
||||
writer.rawAppend();
|
||||
writeJson (i, writer);
|
||||
}
|
||||
writer.finish();
|
||||
break;
|
||||
}
|
||||
|
||||
case Json::objectValue:
|
||||
{
|
||||
writer.startRoot (Writer::object);
|
||||
auto members = value.getMemberNames ();
|
||||
for (auto const& tag: members)
|
||||
{
|
||||
writer.rawSet (tag);
|
||||
writeJson (value[tag], writer);
|
||||
}
|
||||
writer.finish();
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void writeJson (Json::Value const& value, Output const& out)
|
||||
{
|
||||
Writer writer (out);
|
||||
writeJson (value, writer);
|
||||
}
|
||||
|
||||
std::string jsonAsString (Json::Value const& value)
|
||||
{
|
||||
std::string s;
|
||||
Writer writer (stringOutput (s));
|
||||
writeJson (value, writer);
|
||||
return s;
|
||||
}
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
43
src/ripple/rpc/impl/WriteJson.h
Normal file
43
src/ripple/rpc/impl/WriteJson.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
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 RIPPLED_RIPPLE_RPC_IMPL_WRITELEGACYJSON_H
|
||||
#define RIPPLED_RIPPLE_RPC_IMPL_WRITELEGACYJSON_H
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
/** Writes a minimal representation of a Json value to an Output in O(n) time.
|
||||
|
||||
Data is streamed right to the output, so only a marginal amount of memory is
|
||||
used. This can be very important for a very large Json::Value.
|
||||
*/
|
||||
void writeJson (Json::Value const&, Output const&);
|
||||
|
||||
/** Return the minimal string representation of a Json::Value in O(n) time.
|
||||
|
||||
This requires a memory allocation for the full size of the output.
|
||||
If possible, use write().
|
||||
*/
|
||||
std::string jsonAsString (Json::Value const&);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
73
src/ripple/rpc/impl/WriteJson.test.cpp
Normal file
73
src/ripple/rpc/impl/WriteJson.test.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/WriteJson.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
struct WriteJson_test : TestOutputSuite
|
||||
{
|
||||
void runTest (std::string const& name, std::string const& valueDesc)
|
||||
{
|
||||
setup (name);
|
||||
Json::Value value;
|
||||
expect (Json::Reader().parse (valueDesc, value));
|
||||
auto out = stringOutput (output_);
|
||||
writeJson (value, out);
|
||||
|
||||
// Compare with the original version.
|
||||
auto expected = Json::FastWriter().write (value);
|
||||
expected.resize (expected.size() - 1);
|
||||
// For some reason, the FastWriter puts a carriage return on the end of
|
||||
// every piece of Json it outputs.
|
||||
|
||||
expectResult (expected);
|
||||
expectResult (valueDesc);
|
||||
expectResult (jsonAsString (value));
|
||||
}
|
||||
|
||||
void runTest (std::string const& name)
|
||||
{
|
||||
runTest (name, name);
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
runTest ("null");
|
||||
runTest ("true");
|
||||
runTest ("0");
|
||||
runTest ("23.5");
|
||||
runTest ("string", "\"a string\"");
|
||||
runTest ("empty dict", "{}");
|
||||
runTest ("empty array", "[]");
|
||||
runTest ("array", "[23,4.25,true,null,\"string\"]");
|
||||
runTest ("dict", "{\"hello\":\"world\"}");
|
||||
runTest ("array dict", "[{}]");
|
||||
runTest ("array array", "[[]]");
|
||||
runTest ("more complex",
|
||||
"{\"array\":[{\"12\":23},{},null,false,0.5]}");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(WriteJson, ripple_basics, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -30,14 +30,15 @@
|
||||
#include <ripple/overlay/Overlay.h>
|
||||
#include <tuple>
|
||||
|
||||
#include <ripple/rpc/impl/Coroutine.cpp>
|
||||
#include <ripple/rpc/impl/ErrorCodes.cpp>
|
||||
#include <ripple/rpc/impl/JsonObject.cpp>
|
||||
#include <ripple/rpc/impl/JsonWriter.cpp>
|
||||
#include <ripple/rpc/impl/WriteJson.cpp>
|
||||
#include <ripple/rpc/impl/Manager.cpp>
|
||||
#include <ripple/rpc/impl/RPCHandler.cpp>
|
||||
#include <ripple/rpc/impl/Status.cpp>
|
||||
#include <ripple/rpc/impl/Yield.cpp>
|
||||
#include <ripple/rpc/impl/Status_test.cpp>
|
||||
|
||||
#include <ripple/rpc/handlers/Handlers.h>
|
||||
#include <ripple/rpc/handlers/AccountCurrencies.cpp>
|
||||
|
||||
Reference in New Issue
Block a user