Refactor STParsedJSON to parse an object or array [RIPD-480]

The implementation of multi-sign has a SigningAccounts array as a
member of the outermost object.  This array could not be parsed
by the previous implementation of STParsedJSON, which only knew
how to parse objects.  This refactor supports the required parsing.

The refactor divides the parsing into three separate functions:

 o parseNoRecurse() which parses most rippled data types.
 o parseObject() which parses object types that may contain
   arbitrary other types.
 o parseArray() which parses object types that may contain
   arbitrary other types.

The change is required by the multi-sign implementation, but is
independent.  So the parsing change is going in as a separate
commit.

The parsing is still far from perfect.  But this was as much as
needs doing to accomplish the ends and mitigate risk of breaking
the parser.
This commit is contained in:
Scott Schurr
2014-10-09 15:12:02 -07:00
committed by Vinnie Falco
parent af24d541d1
commit 761902864a
7 changed files with 745 additions and 620 deletions

View File

@@ -1214,7 +1214,7 @@ bool ApplicationImp::loadOldLedger (
uIndex.SetHex (entry["index"].asString());
entry.removeMember ("index");
STParsedJSON stp ("sle", ledger.get()[index]);
STParsedJSONObject stp ("sle", ledger.get()[index]);
// m_journal.info << "json: " << stp.object->getJson(0);
if (stp.object && (uIndex.isNonZero()))

View File

@@ -395,7 +395,7 @@ public:
pass ();
}
STParsedJSON parsed ("test", j.getJson (0));
STParsedJSONObject parsed ("test", j.getJson (0));
std::unique_ptr <STObject> new_obj (std::move (parsed.object));
if (new_obj.get () == nullptr)

View File

@@ -942,7 +942,7 @@ public:
Json::Value faultyJson;
bool parsedOK (parseJSONString(faulty, faultyJson));
unexpected(!parsedOK, "failed to parse");
STParsedJSON parsed ("test", faultyJson);
STParsedJSONObject parsed ("test", faultyJson);
expect (parsed.object.get() == nullptr,
"It should have thrown. "
"Immediate children of STArray encoded as json must "
@@ -965,7 +965,7 @@ public:
bool parsedOK (parseJSONString(json, jsonObject));
if (parsedOK)
{
STParsedJSON parsed ("test", jsonObject);
STParsedJSONObject parsed ("test", jsonObject);
Json::FastWriter writer;
std::string const& serialized (
writer.write (parsed.object->getJson(0)));

File diff suppressed because it is too large Load Diff

View File

@@ -22,10 +22,10 @@
namespace ripple {
/** Holds the serialized result of parsing input JSON.
/** Holds the serialized result of parsing an input JSON object.
This does validation and checking on the provided JSON.
*/
class STParsedJSON
class STParsedJSONObject
{
public:
/** Parses and creates an STParsedJSON object.
@@ -35,50 +35,49 @@ public:
@param name The name of the JSON field, used in diagnostics.
@param json The JSON-RPC to parse.
*/
STParsedJSON (std::string const& name,
Json::Value const& json);
STParsedJSONObject (std::string const& name, Json::Value const& json);
STParsedJSONObject () = delete;
STParsedJSONObject (STParsedJSONObject const&) = delete;
STParsedJSONObject& operator= (STParsedJSONObject const&) = delete;
~STParsedJSONObject () = default;
/** The STObject if the parse was successful. */
std::unique_ptr <STObject> object;
/** On failure, an appropriate set of error values. */
Json::Value error;
private:
static std::string make_name (std::string const& object,
std::string const& field);
static Json::Value not_an_object (std::string const& object,
std::string const& field = std::string());
static Json::Value unknown_field (std::string const& object,
std::string const& field = std::string());
static Json::Value out_of_range (std::string const& object,
std::string const& field = std::string());
static Json::Value bad_type (std::string const& object,
std::string const& field = std::string());
static Json::Value invalid_data (std::string const& object,
std::string const& field = std::string());
static Json::Value array_expected (std::string const& object,
std::string const& field = std::string());
static Json::Value string_expected (std::string const& object,
std::string const& field = std::string());
static Json::Value too_deep (std::string const& object,
std::string const& field = std::string());
static Json::Value singleton_expected (
std::string const& object);
bool parse (std::string const& json_name, Json::Value const& json,
SField::ref inName, int depth, std::unique_ptr <STObject>& sub_object);
};
/** Holds the serialized result of parsing an input JSON array.
This does validation and checking on the provided JSON.
*/
class STParsedJSONArray
{
public:
/** Parses and creates an STParsedJSON array.
The result of the parsing is stored in array and error.
Exceptions:
Does not throw.
@param name The name of the JSON field, used in diagnostics.
@param json The JSON-RPC to parse.
*/
STParsedJSONArray (std::string const& name, Json::Value const& json);
STParsedJSONArray () = delete;
STParsedJSONArray (STParsedJSONArray const&) = delete;
STParsedJSONArray& operator= (STParsedJSONArray const&) = delete;
~STParsedJSONArray () = default;
/** The STArray if the parse was successful. */
std::unique_ptr <STArray> array;
/** On failure, an appropriate set of error values. */
Json::Value error;
};
} // ripple
#endif

View File

@@ -198,7 +198,7 @@ Json::Value doRipplePathFind (RPC::Context& context)
if (context.params_.isMember("paths"))
{
STParsedJSON paths ("paths", context.params_["paths"]);
STParsedJSONObject paths ("paths", context.params_["paths"]);
if (paths.object.get() == nullptr)
return paths.error;
else

View File

@@ -324,7 +324,7 @@ Json::Value transactionSign (
}
}
STParsedJSON parsed ("tx_json", tx_json);
STParsedJSONObject parsed ("tx_json", tx_json);
if (!parsed.object.get())
{
jvResult ["error"] = parsed.error ["error"];