20 #include <ripple/basics/contract.h>
21 #include <ripple/basics/safe_cast.h>
22 #include <ripple/basics/StringUtilities.h>
23 #include <ripple/protocol/ErrorCodes.h>
24 #include <ripple/protocol/LedgerFormats.h>
25 #include <ripple/protocol/STAccount.h>
26 #include <ripple/protocol/STAmount.h>
27 #include <ripple/protocol/STArray.h>
28 #include <ripple/protocol/STBitString.h>
29 #include <ripple/protocol/STBlob.h>
30 #include <ripple/protocol/STVector256.h>
31 #include <ripple/protocol/STInteger.h>
32 #include <ripple/protocol/STParsedJSON.h>
33 #include <ripple/protocol/STPathSet.h>
34 #include <ripple/protocol/TER.h>
35 #include <ripple/protocol/TxFormats.h>
36 #include <ripple/protocol/UintTypes.h>
37 #include <ripple/protocol/impl/STVar.h>
38 #include <ripple/beast/core/LexicalCast.h>
44 namespace STParsedJSONDetail
46 template <
typename U,
typename S>
52 Throw<std::runtime_error> (
"Value out of range");
53 return static_cast<U
> (value);
56 template <
typename U1,
typename U2>
62 Throw<std::runtime_error> (
"Value out of range");
63 return static_cast<U1
> (value);
72 return object +
"." + field;
79 "Field '" +
make_name (
object, field) +
"' is not a JSON object.");
90 "Field '" +
object +
"' is not a JSON array.");
97 "Field '" +
make_name (
object, field) +
"' is unknown.");
104 "Field '" +
make_name (
object, field) +
"' is out of range.");
111 "Field '" +
make_name (
object, field) +
"' has bad type.");
118 "Field '" +
make_name (
object, field) +
"' has invalid data.");
130 "Field '" +
make_name (
object, field) +
"' must be a JSON array.");
137 "Field '" +
make_name (
object, field) +
"' must be a string.");
143 "Field '" +
object +
"' exceeds nesting depth limit.");
151 "]' must be an object with a single key/object value.");
157 "Object '" + sField.
getName () +
158 "' contents did not meet requirements for that type.");
166 " is not an object. Arrays may only contain objects.");
178 boost::optional <detail::STVar> ret;
188 switch (field.fieldType)
199 if (!strValue.
empty() &&
200 ((strValue[0] <
'0') || (strValue[0] >
'9')))
214 ret = detail::make_stvar<STUInt8>(field,
219 error =
bad_type(json_name, fieldName);
225 ret = detail::make_stvar <STUInt8>(field,
226 beast::lexicalCastThrow <std::uint8_t>(strValue));
229 else if (value.
isInt ())
231 if (value.
asInt () < minValue || value.
asInt () > maxValue)
237 ret = detail::make_stvar <STUInt8> (field,
242 if (value.
asUInt () > maxValue)
248 ret = detail::make_stvar <STUInt8> (field,
253 error =
bad_type (json_name, fieldName);
271 if (! strValue.
empty () &&
272 ((strValue[0] <
'0') || (strValue[0] >
'9')))
277 findTypeByName (strValue));
280 Throw<std::runtime_error>(
281 "Invalid transaction format name");
282 ret = detail::make_stvar <STUInt16> (field,
292 findTypeByName (strValue));
295 type <= std::min<unsigned>(
299 Throw<std::runtime_error>(
300 "Invalid ledger entry type: out of range");
301 ret = detail::make_stvar <STUInt16> (field,
315 ret = detail::make_stvar <STUInt16> (field,
316 beast::lexicalCastThrow <std::uint16_t> (strValue));
319 else if (value.
isInt ())
321 ret = detail::make_stvar <STUInt16> (field,
322 to_unsigned <std::uint16_t> (value.
asInt ()));
326 ret = detail::make_stvar <STUInt16> (field,
327 to_unsigned <std::uint16_t> (value.
asUInt ()));
331 error =
bad_type (json_name, fieldName);
348 ret = detail::make_stvar <STUInt32> (field,
349 beast::lexicalCastThrow <std::uint32_t> (
352 else if (value.
isInt ())
354 ret = detail::make_stvar <STUInt32> (field,
355 to_unsigned <std::uint32_t> (value.
asInt ()));
359 ret = detail::make_stvar <STUInt32> (field,
360 safe_cast <std::uint32_t> (value.
asUInt ()));
364 error =
bad_type (json_name, fieldName);
381 ret = detail::make_stvar <STUInt64> (field,
384 else if (value.
isInt ())
386 ret = detail::make_stvar <STUInt64> (field,
387 to_unsigned<std::uint64_t> (value.
asInt ()));
391 ret = detail::make_stvar <STUInt64> (field,
392 safe_cast <std::uint64_t> (value.
asUInt ()));
396 error =
bad_type (json_name, fieldName);
413 ret = detail::make_stvar <STHash128> (field, value.
asString ());
417 error =
bad_type (json_name, fieldName);
434 ret = detail::make_stvar <STHash160> (field, value.
asString ());
438 error =
bad_type (json_name, fieldName);
455 ret = detail::make_stvar <STHash256> (field, value.
asString ());
459 error =
bad_type (json_name, fieldName);
474 error =
bad_type (json_name, fieldName);
482 ret = detail::make_stvar<STBlob>(
483 field, vBlob->data(), vBlob->size());
487 Throw<std::invalid_argument> (
"invalid data");
501 ret = detail::make_stvar <STAmount> (
amountFromJson (field, value));
524 s.
SetHex (value[i].asString ());
527 ret = detail::make_stvar <STVector256> (std::move (tail));
552 if (!value[i].isArrayOrNull ())
555 ss << fieldName <<
"[" << i <<
"]";
563 ss << fieldName <<
"[" << i <<
"][" << j <<
"]";
565 json_name +
"." + ss.
str());
581 bool hasCurrency =
false;
588 if (! account.isString ())
598 auto const a = parseBase58<AccountID>(
641 auto const a = parseBase58<AccountID>(
652 p.
emplace_back (uAccount, uCurrency, uIssuer, hasCurrency);
657 ret = detail::make_stvar <STPathSet> (std::move (tail));
671 error =
bad_type (json_name, fieldName);
681 parseHexOrBase58<AccountID>(
688 ret = detail::make_stvar <STAccount>(
700 error =
bad_type (json_name, fieldName);
710 static boost::optional <detail::STVar>
parseArray (
755 switch (field.fieldType)
771 auto ret =
parseObject (json_name +
"." + fieldName,
772 value, field, depth + 1, error);
775 data.emplace_back (std::move (*ret));
789 auto array =
parseArray (json_name +
"." + fieldName,
790 value, field, depth + 1, error);
791 if (array == boost::none)
793 data.emplace_back (std::move (*array));
807 parseLeaf (json_name, fieldName, &inName, value, error);
812 data.emplace_back (std::move (*leaf));
820 data.applyTemplateFromSField (inName);
860 bool const isObjectOrNull (json[i].isObjectOrNull());
861 bool const singleKey (isObjectOrNull ? json[i].size() == 1 :
true);
863 if (!isObjectOrNull || !singleKey)
873 std::string const objectName (json[i].getMemberNames()[0]);;
882 Json::Value const objectFields (json[i][objectName]);
885 ss << json_name <<
"." <<
886 "[" << i <<
"]." << objectName;
889 nameField, depth + 1, error);
892 std::string errMsg = error[
"error_message"].asString ();
893 error[
"error_message"] =
"Error at '" + ss.
str () +
907 return detail::make_stvar <STArray> (std::move (tail));
924 using namespace STParsedJSONDetail;
934 using namespace STParsedJSONDetail;
940 auto p =
dynamic_cast <STArray*
> (&arr->get());
944 array = std::move (*p);