mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Improvements to STParsedJSON:
* Cleanups and reduction of copying * Add STArray::back, operator[], push_back(&&) * Add make_stvar * Rework STParsedJSON * Fix code and unit tests that use STParsedJSON * STTx move constructor
This commit is contained in:
@@ -112,12 +112,11 @@ STTx
|
|||||||
parseTransaction(TestAccount& account, Json::Value const& tx_json, bool sign)
|
parseTransaction(TestAccount& account, Json::Value const& tx_json, bool sign)
|
||||||
{
|
{
|
||||||
STParsedJSONObject parsed("tx_json", tx_json);
|
STParsedJSONObject parsed("tx_json", tx_json);
|
||||||
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
|
if (!parsed.object)
|
||||||
if (sopTrans == nullptr)
|
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"sopTrans == nullptr");
|
"object not parseable");
|
||||||
sopTrans->setFieldVL(sfSigningPubKey, account.pk.getAccountPublic());
|
parsed.object->setFieldVL(sfSigningPubKey, account.pk.getAccountPublic());
|
||||||
auto tx = STTx(*sopTrans);
|
auto tx = STTx(std::move (*parsed.object));
|
||||||
if (sign)
|
if (sign)
|
||||||
tx.sign(account.sk);
|
tx.sign(account.sk);
|
||||||
return tx;
|
return tx;
|
||||||
|
|||||||
@@ -71,11 +71,37 @@ public:
|
|||||||
return emplace(n, buf, std::move(*this));
|
return emplace(n, buf, std::move(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_back (const STObject & object)
|
STObject& operator[] (std::size_t j)
|
||||||
|
{
|
||||||
|
return v_[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
STObject const& operator[] (std::size_t j) const
|
||||||
|
{
|
||||||
|
return v_[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
STObject& back() { return v_.back(); }
|
||||||
|
|
||||||
|
STObject const& back() const { return v_.back(); }
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
void
|
||||||
|
emplace_back(Args&&... args)
|
||||||
|
{
|
||||||
|
v_.emplace_back(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back (STObject const& object)
|
||||||
{
|
{
|
||||||
v_.push_back(object);
|
v_.push_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void push_back (STObject&& object)
|
||||||
|
{
|
||||||
|
v_.push_back(std::move(object));
|
||||||
|
}
|
||||||
|
|
||||||
iterator begin ()
|
iterator begin ()
|
||||||
{
|
{
|
||||||
return v_.begin ();
|
return v_.begin ();
|
||||||
@@ -101,11 +127,6 @@ public:
|
|||||||
return v_.size ();
|
return v_.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
STObject& back ()
|
|
||||||
{
|
|
||||||
return v_.back ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty () const
|
bool empty () const
|
||||||
{
|
{
|
||||||
return v_.empty ();
|
return v_.empty ();
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include <ripple/protocol/SOTemplate.h>
|
#include <ripple/protocol/SOTemplate.h>
|
||||||
#include <ripple/protocol/impl/STVar.h>
|
#include <ripple/protocol/impl/STVar.h>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
#include <boost/ptr_container/ptr_vector.hpp>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <beast/streams/debug_ostream.h>
|
#include <beast/streams/debug_ostream.h>
|
||||||
@@ -99,7 +98,6 @@ public:
|
|||||||
STObject(STObject const&) = default;
|
STObject(STObject const&) = default;
|
||||||
STObject (const SOTemplate & type, SField const& name);
|
STObject (const SOTemplate & type, SField const& name);
|
||||||
STObject (const SOTemplate & type, SerialIter & sit, SField const& name);
|
STObject (const SOTemplate & type, SerialIter & sit, SField const& name);
|
||||||
STObject (SField const& name, boost::ptr_vector<STBase>& data);
|
|
||||||
STObject (SerialIter& sit, SField const& name);
|
STObject (SerialIter& sit, SField const& name);
|
||||||
STObject& operator= (STObject const&) = default;
|
STObject& operator= (STObject const&) = default;
|
||||||
STObject& operator= (STObject&& other);
|
STObject& operator= (STObject&& other);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define RIPPLE_PROTOCOL_STPARSEDJSON_H_INCLUDED
|
#define RIPPLE_PROTOCOL_STPARSEDJSON_H_INCLUDED
|
||||||
|
|
||||||
#include <ripple/protocol/STArray.h>
|
#include <ripple/protocol/STArray.h>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ public:
|
|||||||
~STParsedJSONObject () = default;
|
~STParsedJSONObject () = default;
|
||||||
|
|
||||||
/** The STObject if the parse was successful. */
|
/** The STObject if the parse was successful. */
|
||||||
std::unique_ptr <STObject> object;
|
boost::optional <STObject> object;
|
||||||
|
|
||||||
/** On failure, an appropriate set of error values. */
|
/** On failure, an appropriate set of error values. */
|
||||||
Json::Value error;
|
Json::Value error;
|
||||||
@@ -72,7 +73,7 @@ public:
|
|||||||
~STParsedJSONArray () = default;
|
~STParsedJSONArray () = default;
|
||||||
|
|
||||||
/** The STArray if the parse was successful. */
|
/** The STArray if the parse was successful. */
|
||||||
std::unique_ptr <STArray> array;
|
boost::optional <STArray> array;
|
||||||
|
|
||||||
/** On failure, an appropriate set of error values. */
|
/** On failure, an appropriate set of error values. */
|
||||||
Json::Value error;
|
Json::Value error;
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ public:
|
|||||||
explicit STTx (SerialIter& sit);
|
explicit STTx (SerialIter& sit);
|
||||||
explicit STTx (TxType type);
|
explicit STTx (TxType type);
|
||||||
|
|
||||||
// Only called from ripple::RPC::transactionSign - can we eliminate this?
|
explicit STTx (STObject&& object);
|
||||||
explicit STTx (STObject const& object);
|
|
||||||
|
|
||||||
STBase*
|
STBase*
|
||||||
copy (std::size_t n, void* buf) const override
|
copy (std::size_t n, void* buf) const override
|
||||||
|
|||||||
@@ -71,16 +71,6 @@ STObject::STObject (SOTemplate const& type,
|
|||||||
setType (type);
|
setType (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
STObject::STObject (SField const& name,
|
|
||||||
boost::ptr_vector<STBase>& data)
|
|
||||||
: STBase (name)
|
|
||||||
, mType (nullptr)
|
|
||||||
{
|
|
||||||
v_.reserve(data.size());
|
|
||||||
for (auto const& b : data)
|
|
||||||
v_.emplace_back(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
STObject::STObject (SerialIter& sit, SField const& name)
|
STObject::STObject (SerialIter& sit, SField const& name)
|
||||||
: STBase(name)
|
: STBase(name)
|
||||||
, mType(nullptr)
|
, mType(nullptr)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <ripple/protocol/STParsedJSON.h>
|
#include <ripple/protocol/STParsedJSON.h>
|
||||||
#include <ripple/protocol/STPathSet.h>
|
#include <ripple/protocol/STPathSet.h>
|
||||||
#include <ripple/protocol/TxFormats.h>
|
#include <ripple/protocol/TxFormats.h>
|
||||||
|
#include <ripple/protocol/impl/STVar.h>
|
||||||
#include <beast/module/core/text/LexicalCast.h>
|
#include <beast/module/core/text/LexicalCast.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <beast/cxx14/memory.h> // <memory>
|
#include <beast/cxx14/memory.h> // <memory>
|
||||||
@@ -140,14 +141,14 @@ static Json::Value singleton_expected (std::string const& object,
|
|||||||
|
|
||||||
// This function is used by parseObject to parse any JSON type that doesn't
|
// This function is used by parseObject to parse any JSON type that doesn't
|
||||||
// recurse. Everything represented here is a leaf-type.
|
// recurse. Everything represented here is a leaf-type.
|
||||||
static std::unique_ptr <STBase> parseLeaf (
|
static boost::optional<detail::STVar> parseLeaf (
|
||||||
std::string const& json_name,
|
std::string const& json_name,
|
||||||
std::string const& fieldName,
|
std::string const& fieldName,
|
||||||
SField const* name,
|
SField const* name,
|
||||||
Json::Value const& value,
|
Json::Value const& value,
|
||||||
Json::Value& error)
|
Json::Value& error)
|
||||||
{
|
{
|
||||||
std::unique_ptr <STBase> ret;
|
boost::optional <detail::STVar> ret;
|
||||||
|
|
||||||
auto const& field = SField::getField (fieldName);
|
auto const& field = SField::getField (fieldName);
|
||||||
|
|
||||||
@@ -174,7 +175,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = std::make_unique <STUInt8> (field,
|
ret = detail::make_stvar <STUInt8> (field,
|
||||||
range_check_cast <unsigned char> (
|
range_check_cast <unsigned char> (
|
||||||
value.asInt (), 0, 255));
|
value.asInt (), 0, 255));
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = std::make_unique <STUInt8> (field,
|
ret = detail::make_stvar <STUInt8> (field,
|
||||||
range_check_cast <unsigned char> (
|
range_check_cast <unsigned char> (
|
||||||
value.asUInt (), 0, 255));
|
value.asUInt (), 0, 255));
|
||||||
}
|
}
|
||||||
@@ -218,7 +219,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
TxType const txType (TxFormats::getInstance().
|
TxType const txType (TxFormats::getInstance().
|
||||||
findTypeByName (strValue));
|
findTypeByName (strValue));
|
||||||
|
|
||||||
ret = std::make_unique <STUInt16> (field,
|
ret = detail::make_stvar <STUInt16> (field,
|
||||||
static_cast <std::uint16_t> (txType));
|
static_cast <std::uint16_t> (txType));
|
||||||
|
|
||||||
if (*name == sfGeneric)
|
if (*name == sfGeneric)
|
||||||
@@ -230,7 +231,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
LedgerFormats::getInstance().
|
LedgerFormats::getInstance().
|
||||||
findTypeByName (strValue));
|
findTypeByName (strValue));
|
||||||
|
|
||||||
ret = std::make_unique <STUInt16> (field,
|
ret = detail::make_stvar <STUInt16> (field,
|
||||||
static_cast <std::uint16_t> (type));
|
static_cast <std::uint16_t> (type));
|
||||||
|
|
||||||
if (*name == sfGeneric)
|
if (*name == sfGeneric)
|
||||||
@@ -244,19 +245,19 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt16> (field,
|
ret = detail::make_stvar <STUInt16> (field,
|
||||||
beast::lexicalCastThrow <std::uint16_t> (strValue));
|
beast::lexicalCastThrow <std::uint16_t> (strValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (value.isInt ())
|
else if (value.isInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt16> (field,
|
ret = detail::make_stvar <STUInt16> (field,
|
||||||
range_check_cast <std::uint16_t> (
|
range_check_cast <std::uint16_t> (
|
||||||
value.asInt (), 0, 65535));
|
value.asInt (), 0, 65535));
|
||||||
}
|
}
|
||||||
else if (value.isUInt ())
|
else if (value.isUInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt16> (field,
|
ret = detail::make_stvar <STUInt16> (field,
|
||||||
range_check_cast <std::uint16_t> (
|
range_check_cast <std::uint16_t> (
|
||||||
value.asUInt (), 0, 65535));
|
value.asUInt (), 0, 65535));
|
||||||
}
|
}
|
||||||
@@ -279,19 +280,19 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
if (value.isString ())
|
if (value.isString ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt32> (field,
|
ret = detail::make_stvar <STUInt32> (field,
|
||||||
beast::lexicalCastThrow <std::uint32_t> (
|
beast::lexicalCastThrow <std::uint32_t> (
|
||||||
value.asString ()));
|
value.asString ()));
|
||||||
}
|
}
|
||||||
else if (value.isInt ())
|
else if (value.isInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt32> (field,
|
ret = detail::make_stvar <STUInt32> (field,
|
||||||
range_check_cast <std::uint32_t> (
|
range_check_cast <std::uint32_t> (
|
||||||
value.asInt (), 0u, 4294967295u));
|
value.asInt (), 0u, 4294967295u));
|
||||||
}
|
}
|
||||||
else if (value.isUInt ())
|
else if (value.isUInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt32> (field,
|
ret = detail::make_stvar <STUInt32> (field,
|
||||||
static_cast <std::uint32_t> (value.asUInt ()));
|
static_cast <std::uint32_t> (value.asUInt ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -313,18 +314,18 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
if (value.isString ())
|
if (value.isString ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt64> (field,
|
ret = detail::make_stvar <STUInt64> (field,
|
||||||
uintFromHex (value.asString ()));
|
uintFromHex (value.asString ()));
|
||||||
}
|
}
|
||||||
else if (value.isInt ())
|
else if (value.isInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt64> (field,
|
ret = detail::make_stvar <STUInt64> (field,
|
||||||
range_check_cast<std::uint64_t> (
|
range_check_cast<std::uint64_t> (
|
||||||
value.asInt (), 0, 18446744073709551615ull));
|
value.asInt (), 0, 18446744073709551615ull));
|
||||||
}
|
}
|
||||||
else if (value.isUInt ())
|
else if (value.isUInt ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STUInt64> (field,
|
ret = detail::make_stvar <STUInt64> (field,
|
||||||
static_cast <std::uint64_t> (value.asUInt ()));
|
static_cast <std::uint64_t> (value.asUInt ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -346,7 +347,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
if (value.isString ())
|
if (value.isString ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STHash128> (field, value.asString ());
|
ret = detail::make_stvar <STHash128> (field, value.asString ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -367,7 +368,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
if (value.isString ())
|
if (value.isString ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STHash160> (field, value.asString ());
|
ret = detail::make_stvar <STHash160> (field, value.asString ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -388,7 +389,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
if (value.isString ())
|
if (value.isString ())
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STHash256> (field, value.asString ());
|
ret = detail::make_stvar <STHash256> (field, value.asString ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -418,7 +419,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
if (!vBlob.second)
|
if (!vBlob.second)
|
||||||
throw std::invalid_argument ("invalid data");
|
throw std::invalid_argument ("invalid data");
|
||||||
|
|
||||||
ret = std::make_unique <STBlob> (field, vBlob.first.data (),
|
ret = detail::make_stvar <STBlob> (field, vBlob.first.data (),
|
||||||
vBlob.first.size ());
|
vBlob.first.size ());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -432,7 +433,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
case STI_AMOUNT:
|
case STI_AMOUNT:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ret = std::make_unique <STAmount> (amountFromJson (field, value));
|
ret = detail::make_stvar <STAmount> (amountFromJson (field, value));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -451,15 +452,14 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr <STVector256> tail =
|
STVector256 tail (field);
|
||||||
std::make_unique <STVector256> (field);
|
|
||||||
for (Json::UInt i = 0; value.isValidIndex (i); ++i)
|
for (Json::UInt i = 0; value.isValidIndex (i); ++i)
|
||||||
{
|
{
|
||||||
uint256 s;
|
uint256 s;
|
||||||
s.SetHex (value[i].asString ());
|
s.SetHex (value[i].asString ());
|
||||||
tail->push_back (s);
|
tail.push_back (s);
|
||||||
}
|
}
|
||||||
ret = std::move (tail);
|
ret = detail::make_stvar <STVector256> (std::move (tail));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -478,8 +478,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr <STPathSet> tail =
|
STPathSet tail (field);
|
||||||
std::make_unique <STPathSet> (field);
|
|
||||||
|
|
||||||
for (Json::UInt i = 0; value.isValidIndex (i); ++i)
|
for (Json::UInt i = 0; value.isValidIndex (i); ++i)
|
||||||
{
|
{
|
||||||
@@ -597,9 +596,9 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
p.emplace_back (uAccount, uCurrency, uIssuer, hasCurrency);
|
p.emplace_back (uAccount, uCurrency, uIssuer, hasCurrency);
|
||||||
}
|
}
|
||||||
|
|
||||||
tail->push_back (p);
|
tail.push_back (p);
|
||||||
}
|
}
|
||||||
ret = std::move (tail);
|
ret = detail::make_stvar <STPathSet> (std::move (tail));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -625,7 +624,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
{
|
{
|
||||||
Account account;
|
Account account;
|
||||||
account.SetHex (strValue);
|
account.SetHex (strValue);
|
||||||
ret = std::make_unique <STAccount> (field, account);
|
ret = detail::make_stvar <STAccount> (field, account);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -639,7 +638,7 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
std::make_unique <STAccount> (field, a.getAccountID ());
|
detail::make_stvar <STAccount> (field, a.getAccountID ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -661,42 +660,37 @@ static std::unique_ptr <STBase> parseLeaf (
|
|||||||
static const int maxDepth = 64;
|
static const int maxDepth = 64;
|
||||||
|
|
||||||
// Forward declaration since parseObject() and parseArray() call each other.
|
// Forward declaration since parseObject() and parseArray() call each other.
|
||||||
static bool parseArray (
|
static boost::optional <detail::STVar> parseArray (
|
||||||
std::string const& json_name,
|
std::string const& json_name,
|
||||||
Json::Value const& json,
|
Json::Value const& json,
|
||||||
SField const& inName,
|
SField const& inName,
|
||||||
int depth,
|
int depth,
|
||||||
std::unique_ptr <STArray>& sub_array,
|
|
||||||
Json::Value& error);
|
Json::Value& error);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool parseObject (
|
static boost::optional <STObject> parseObject (
|
||||||
std::string const& json_name,
|
std::string const& json_name,
|
||||||
Json::Value const& json,
|
Json::Value const& json,
|
||||||
SField const& inName,
|
SField const& inName,
|
||||||
int depth,
|
int depth,
|
||||||
std::unique_ptr <STObject>& sub_object,
|
|
||||||
Json::Value& error)
|
Json::Value& error)
|
||||||
{
|
{
|
||||||
if (! json.isObject ())
|
if (! json.isObject ())
|
||||||
{
|
{
|
||||||
error = not_an_object (json_name);
|
error = not_an_object (json_name);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth > maxDepth)
|
if (depth > maxDepth)
|
||||||
{
|
{
|
||||||
error = too_deep (json_name);
|
error = too_deep (json_name);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name (&inName);
|
STObject data (inName);
|
||||||
|
|
||||||
boost::ptr_vector<STBase> data;
|
for (auto const& fieldName : json.getMemberNames ())
|
||||||
Json::Value::Members members (json.getMemberNames ());
|
|
||||||
|
|
||||||
for (auto const& fieldName : members)
|
|
||||||
{
|
{
|
||||||
Json::Value const& value = json [fieldName];
|
Json::Value const& value = json [fieldName];
|
||||||
|
|
||||||
@@ -705,7 +699,7 @@ static bool parseObject (
|
|||||||
if (field == sfInvalid)
|
if (field == sfInvalid)
|
||||||
{
|
{
|
||||||
error = unknown_field (json_name, fieldName);
|
error = unknown_field (json_name, fieldName);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (field.fieldType)
|
switch (field.fieldType)
|
||||||
@@ -719,22 +713,21 @@ static bool parseObject (
|
|||||||
if (! value.isObject ())
|
if (! value.isObject ())
|
||||||
{
|
{
|
||||||
error = not_an_object (json_name, fieldName);
|
error = not_an_object (json_name, fieldName);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr <STObject> sub_object_;
|
auto ret = parseObject (json_name + "." + fieldName,
|
||||||
bool const success (parseObject (json_name + "." + fieldName,
|
value, field, depth + 1, error);
|
||||||
value, field, depth + 1, sub_object_, error));
|
if (! ret)
|
||||||
if (! success)
|
return boost::none;
|
||||||
return false;
|
data.emplace_back (std::move (*ret));
|
||||||
data.push_back (sub_object_.release ());
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
error = invalid_data (json_name, fieldName);
|
error = invalid_data (json_name, fieldName);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -743,17 +736,16 @@ static bool parseObject (
|
|||||||
case STI_ARRAY:
|
case STI_ARRAY:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr <STArray> sub_array_;
|
auto array = parseArray (json_name + "." + fieldName,
|
||||||
bool const success (parseArray (json_name + "." + fieldName,
|
value, field, depth + 1, error);
|
||||||
value, field, depth + 1, sub_array_, error));
|
if (array == boost::none)
|
||||||
if (! success)
|
return boost::none;
|
||||||
return false;
|
data.emplace_back (std::move (*array));
|
||||||
data.push_back (sub_array_.release ());
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
error = invalid_data (json_name, fieldName);
|
error = invalid_data (json_name, fieldName);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -761,46 +753,44 @@ static bool parseObject (
|
|||||||
// Everything else (types that don't recurse).
|
// Everything else (types that don't recurse).
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
std::unique_ptr <STBase> serTyp =
|
auto leaf =
|
||||||
parseLeaf (json_name, fieldName, name, value, error);
|
parseLeaf (json_name, fieldName, &inName, value, error);
|
||||||
|
|
||||||
if (!serTyp)
|
if (!leaf)
|
||||||
return false;
|
return boost::none;
|
||||||
|
|
||||||
data.push_back (serTyp.release ());
|
data.emplace_back (std::move (*leaf));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub_object = std::make_unique <STObject> (*name, data);
|
return std::move (data);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseArray (
|
static boost::optional <detail::STVar> parseArray (
|
||||||
std::string const& json_name,
|
std::string const& json_name,
|
||||||
Json::Value const& json,
|
Json::Value const& json,
|
||||||
SField const& inName,
|
SField const& inName,
|
||||||
int depth,
|
int depth,
|
||||||
std::unique_ptr <STArray>& sub_array,
|
|
||||||
Json::Value& error)
|
Json::Value& error)
|
||||||
{
|
{
|
||||||
if (! json.isArray ())
|
if (! json.isArray ())
|
||||||
{
|
{
|
||||||
error = not_an_array (json_name);
|
error = not_an_array (json_name);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth > maxDepth)
|
if (depth > maxDepth)
|
||||||
{
|
{
|
||||||
error = too_deep (json_name);
|
error = too_deep (json_name);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::unique_ptr <STArray> tail = std::make_unique <STArray> (inName);
|
STArray tail (inName);
|
||||||
|
|
||||||
for (Json::UInt i = 0; json.isValidIndex (i); ++i)
|
for (Json::UInt i = 0; json.isValidIndex (i); ++i)
|
||||||
{
|
{
|
||||||
@@ -810,7 +800,7 @@ static bool parseArray (
|
|||||||
if (!isObject || !singleKey)
|
if (!isObject || !singleKey)
|
||||||
{
|
{
|
||||||
error = singleton_expected (json_name, i);
|
error = singleton_expected (json_name, i);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There doesn't seem to be a nice way to get just the
|
// TODO: There doesn't seem to be a nice way to get just the
|
||||||
@@ -822,35 +812,34 @@ static bool parseArray (
|
|||||||
if (nameField == sfInvalid)
|
if (nameField == sfInvalid)
|
||||||
{
|
{
|
||||||
error = unknown_field (json_name, objectName);
|
error = unknown_field (json_name, objectName);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value const objectFields (json[i][objectName]);
|
Json::Value const objectFields (json[i][objectName]);
|
||||||
|
|
||||||
std::unique_ptr <STObject> sub_object_;
|
std::stringstream ss;
|
||||||
{
|
ss << json_name << "." <<
|
||||||
std::stringstream ss;
|
"[" << i << "]." << objectName;
|
||||||
ss << json_name << "." <<
|
|
||||||
"[" << i << "]." << objectName;
|
|
||||||
bool const success (parseObject (ss.str (), objectFields,
|
|
||||||
nameField, depth + 1, sub_object_, error));
|
|
||||||
|
|
||||||
if (! success ||
|
auto ret = parseObject (ss.str (), objectFields,
|
||||||
(sub_object_->getFName().fieldType != STI_OBJECT))
|
nameField, depth + 1, error);
|
||||||
{
|
|
||||||
return false;
|
if (! ret ||
|
||||||
}
|
(ret->getFName().fieldType != STI_OBJECT))
|
||||||
}
|
{
|
||||||
tail->push_back (*sub_object_);
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail.push_back (std::move (*ret));
|
||||||
}
|
}
|
||||||
sub_array = std::move (tail);
|
|
||||||
|
return detail::make_stvar <STArray> (std::move (tail));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
error = invalid_data (json_name);
|
error = invalid_data (json_name);
|
||||||
return false;
|
return boost::none;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // STParsedJSONDetail
|
} // STParsedJSONDetail
|
||||||
@@ -862,7 +851,7 @@ STParsedJSONObject::STParsedJSONObject (
|
|||||||
Json::Value const& json)
|
Json::Value const& json)
|
||||||
{
|
{
|
||||||
using namespace STParsedJSONDetail;
|
using namespace STParsedJSONDetail;
|
||||||
parseObject (name, json, sfGeneric, 0, object, error);
|
object = std::move (parseObject (name, json, sfGeneric, 0, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -872,7 +861,17 @@ STParsedJSONArray::STParsedJSONArray (
|
|||||||
Json::Value const& json)
|
Json::Value const& json)
|
||||||
{
|
{
|
||||||
using namespace STParsedJSONDetail;
|
using namespace STParsedJSONDetail;
|
||||||
parseArray (name, json, sfGeneric, 0, array, error);
|
auto arr = parseArray (name, json, sfGeneric, 0, error);
|
||||||
|
if (!arr)
|
||||||
|
array = boost::none;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto p = dynamic_cast <STArray*> (&arr->get());
|
||||||
|
if (p == nullptr)
|
||||||
|
array = boost::none;
|
||||||
|
else
|
||||||
|
array = std::move (*p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <ripple/protocol/STAccount.h>
|
#include <ripple/protocol/STAccount.h>
|
||||||
#include <ripple/protocol/STArray.h>
|
#include <ripple/protocol/STArray.h>
|
||||||
#include <ripple/protocol/STTx.h>
|
#include <ripple/protocol/STTx.h>
|
||||||
#include <ripple/protocol/STParsedJSON.h>
|
|
||||||
#include <ripple/protocol/TxFlags.h>
|
#include <ripple/protocol/TxFlags.h>
|
||||||
#include <ripple/basics/StringUtilities.h>
|
#include <ripple/basics/StringUtilities.h>
|
||||||
#include <ripple/json/to_string.h>
|
#include <ripple/json/to_string.h>
|
||||||
@@ -54,8 +53,8 @@ STTx::STTx (TxType type)
|
|||||||
setFieldU16 (sfTransactionType, format->getType ());
|
setFieldU16 (sfTransactionType, format->getType ());
|
||||||
}
|
}
|
||||||
|
|
||||||
STTx::STTx (STObject const& object)
|
STTx::STTx (STObject&& object)
|
||||||
: STObject (object)
|
: STObject (std::move (object))
|
||||||
, sig_state_ (boost::indeterminate)
|
, sig_state_ (boost::indeterminate)
|
||||||
{
|
{
|
||||||
tx_type_ = static_cast <TxType> (getFieldU16 (sfTransactionType));
|
tx_type_ = static_cast <TxType> (getFieldU16 (sfTransactionType));
|
||||||
|
|||||||
@@ -88,7 +88,14 @@ public:
|
|||||||
STBase const& operator*() const { return get(); }
|
STBase const& operator*() const { return get(); }
|
||||||
STBase const* operator->() const { return &get(); }
|
STBase const* operator->() const { return &get(); }
|
||||||
|
|
||||||
|
template <class T, class... Args>
|
||||||
|
friend
|
||||||
|
STVar
|
||||||
|
make_stvar(Args&&... args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
STVar() = default;
|
||||||
|
|
||||||
STVar (SerializedTypeID id, SField const& name);
|
STVar (SerializedTypeID id, SField const& name);
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
@@ -113,6 +120,16 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T, class... Args>
|
||||||
|
inline
|
||||||
|
STVar
|
||||||
|
make_stvar(Args&&... args)
|
||||||
|
{
|
||||||
|
STVar st;
|
||||||
|
st.construct<T>(std::forward<Args>(args)...);
|
||||||
|
return std::move(st);
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
operator== (STVar const& lhs, STVar const& rhs)
|
operator== (STVar const& lhs, STVar const& rhs)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
bool parsedOK (parseJSONString(faulty, faultyJson));
|
bool parsedOK (parseJSONString(faulty, faultyJson));
|
||||||
unexpected(!parsedOK, "failed to parse");
|
unexpected(!parsedOK, "failed to parse");
|
||||||
STParsedJSONObject parsed ("test", faultyJson);
|
STParsedJSONObject parsed ("test", faultyJson);
|
||||||
expect (parsed.object.get() == nullptr,
|
expect (! parsed.object,
|
||||||
"It should have thrown. "
|
"It should have thrown. "
|
||||||
"Immediate children of STArray encoded as json must "
|
"Immediate children of STArray encoded as json must "
|
||||||
"have one key only.");
|
"have one key only.");
|
||||||
|
|||||||
@@ -61,15 +61,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
STParsedJSONObject parsed ("test", j.getJson (0));
|
STParsedJSONObject parsed ("test", j.getJson (0));
|
||||||
std::unique_ptr <STObject> new_obj (std::move (parsed.object));
|
if (!parsed.object)
|
||||||
|
|
||||||
if (new_obj.get () == nullptr)
|
|
||||||
fail ("Unable to build object from json");
|
fail ("Unable to build object from json");
|
||||||
|
|
||||||
if (STObject (j) != *new_obj)
|
if (STObject (j) != parsed.object)
|
||||||
{
|
{
|
||||||
log << "ORIG: " << j.getJson (0);
|
log << "ORIG: " << j.getJson (0);
|
||||||
log << "BUILT " << new_obj->getJson (0);
|
log << "BUILT " << parsed.object->getJson (0);
|
||||||
fail ("Built a different transaction");
|
fail ("Built a different transaction");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -249,11 +249,11 @@ ripplePathFind(RippleLineCache::pointer const& cache,
|
|||||||
Json::Value pathSet = Json::objectValue;
|
Json::Value pathSet = Json::objectValue;
|
||||||
pathSet[jss::Paths] = contextPaths.get();
|
pathSet[jss::Paths] = contextPaths.get();
|
||||||
STParsedJSONObject paths("pathSet", pathSet);
|
STParsedJSONObject paths("pathSet", pathSet);
|
||||||
if (paths.object.get() == nullptr)
|
if (! paths.object)
|
||||||
return std::make_pair(false, paths.error);
|
return std::make_pair(false, paths.error);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spsComputed = paths.object.get()->getFieldPathSet(sfPaths);
|
spsComputed = paths.object->getFieldPathSet(sfPaths);
|
||||||
WriteLog(lsTRACE, RPCHandler) << "ripple_path_find: Paths: " <<
|
WriteLog(lsTRACE, RPCHandler) << "ripple_path_find: Paths: " <<
|
||||||
spsComputed.getJson(0);
|
spsComputed.getJson(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -445,15 +445,14 @@ transactionSign (
|
|||||||
}
|
}
|
||||||
|
|
||||||
STParsedJSONObject parsed (std::string (jss::tx_json), tx_json);
|
STParsedJSONObject parsed (std::string (jss::tx_json), tx_json);
|
||||||
if (!parsed.object.get())
|
if (! parsed.object)
|
||||||
{
|
{
|
||||||
jvResult [jss::error] = parsed.error [jss::error];
|
jvResult [jss::error] = parsed.error [jss::error];
|
||||||
jvResult [jss::error_code] = parsed.error [jss::error_code];
|
jvResult [jss::error_code] = parsed.error [jss::error_code];
|
||||||
jvResult [jss::error_message] = parsed.error [jss::error_message];
|
jvResult [jss::error_message] = parsed.error [jss::error_message];
|
||||||
return jvResult;
|
return jvResult;
|
||||||
}
|
}
|
||||||
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
|
parsed.object->setFieldVL (
|
||||||
sopTrans->setFieldVL (
|
|
||||||
sfSigningPubKey,
|
sfSigningPubKey,
|
||||||
keypair.publicKey.getAccountPublic());
|
keypair.publicKey.getAccountPublic());
|
||||||
|
|
||||||
@@ -461,7 +460,7 @@ transactionSign (
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
stpTrans = std::make_shared<STTx> (*sopTrans);
|
stpTrans = std::make_shared<STTx> (std::move (*parsed.object));
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user