20 #include <ripple/basics/StringUtilities.h>
21 #include <ripple/basics/contract.h>
22 #include <ripple/basics/safe_cast.h>
23 #include <ripple/beast/core/LexicalCast.h>
24 #include <ripple/protocol/ErrorCodes.h>
25 #include <ripple/protocol/LedgerFormats.h>
26 #include <ripple/protocol/STAccount.h>
27 #include <ripple/protocol/STAmount.h>
28 #include <ripple/protocol/STArray.h>
29 #include <ripple/protocol/STBitString.h>
30 #include <ripple/protocol/STBlob.h>
31 #include <ripple/protocol/STInteger.h>
32 #include <ripple/protocol/STParsedJSON.h>
33 #include <ripple/protocol/STPathSet.h>
34 #include <ripple/protocol/STVector256.h>
35 #include <ripple/protocol/TER.h>
36 #include <ripple/protocol/TxFormats.h>
37 #include <ripple/protocol/UintTypes.h>
38 #include <ripple/protocol/impl/STVar.h>
44 namespace STParsedJSONDetail {
45 template <
typename U,
typename S>
51 Throw<std::runtime_error>(
"Value out of range");
52 return static_cast<U
>(value);
55 template <
typename U1,
typename U2>
61 Throw<std::runtime_error>(
"Value out of range");
62 return static_cast<U1
>(value);
71 return object +
"." + field;
79 "Field '" +
make_name(
object, field) +
"' is not a JSON object.");
100 "Field '" +
make_name(
object, field) +
"' is unknown.");
108 "Field '" +
make_name(
object, field) +
"' is out of range.");
116 "Field '" +
make_name(
object, field) +
"' has bad type.");
124 "Field '" +
make_name(
object, field) +
"' has invalid data.");
138 "Field '" +
make_name(
object, field) +
"' must be a JSON array.");
146 "Field '" +
make_name(
object, field) +
"' must be a string.");
154 "Field '" +
object +
"' exceeds nesting depth limit.");
163 "]' must be an object with a single key/object value.");
171 "Object '" + sField.
getName() +
172 "' contents did not meet requirements for that type.");
181 " is not an object. Arrays may only contain objects.");
186 static boost::optional<detail::STVar>
194 boost::optional<detail::STVar> ret;
204 switch (field.fieldType)
209 constexpr
auto minValue =
211 constexpr
auto maxValue =
217 if (!strValue.
empty() &&
218 ((strValue[0] <
'0') || (strValue[0] >
'9')))
224 if (!ter ||
TERtoInt(*ter) < minValue ||
231 ret = detail::make_stvar<STUInt8>(
237 error =
bad_type(json_name, fieldName);
243 ret = detail::make_stvar<STUInt8>(
245 beast::lexicalCastThrow<std::uint8_t>(strValue));
248 else if (value.
isInt())
250 if (value.
asInt() < minValue || value.
asInt() > maxValue)
256 ret = detail::make_stvar<STUInt8>(
261 if (value.
asUInt() > maxValue)
267 ret = detail::make_stvar<STUInt8>(
272 error =
bad_type(json_name, fieldName);
290 if (!strValue.
empty() &&
291 ((strValue[0] <
'0') || (strValue[0] >
'9')))
300 Throw<std::runtime_error>(
301 "Invalid transaction format name");
302 ret = detail::make_stvar<STUInt16>(
322 Throw<std::runtime_error>(
323 "Invalid ledger entry type: out of range");
324 ret = detail::make_stvar<STUInt16>(
338 ret = detail::make_stvar<STUInt16>(
340 beast::lexicalCastThrow<std::uint16_t>(strValue));
343 else if (value.
isInt())
345 ret = detail::make_stvar<STUInt16>(
346 field, to_unsigned<std::uint16_t>(value.
asInt()));
350 ret = detail::make_stvar<STUInt16>(
351 field, to_unsigned<std::uint16_t>(value.
asUInt()));
355 error =
bad_type(json_name, fieldName);
372 ret = detail::make_stvar<STUInt32>(
374 beast::lexicalCastThrow<std::uint32_t>(
377 else if (value.
isInt())
379 ret = detail::make_stvar<STUInt32>(
380 field, to_unsigned<std::uint32_t>(value.
asInt()));
384 ret = detail::make_stvar<STUInt32>(
385 field, safe_cast<std::uint32_t>(value.
asUInt()));
389 error =
bad_type(json_name, fieldName);
406 ret = detail::make_stvar<STUInt64>(
409 else if (value.
isInt())
411 ret = detail::make_stvar<STUInt64>(
412 field, to_unsigned<std::uint64_t>(value.
asInt()));
416 ret = detail::make_stvar<STUInt64>(
417 field, safe_cast<std::uint64_t>(value.
asUInt()));
421 error =
bad_type(json_name, fieldName);
439 detail::make_stvar<STHash128>(field, value.
asString());
443 error =
bad_type(json_name, fieldName);
461 detail::make_stvar<STHash160>(field, value.
asString());
465 error =
bad_type(json_name, fieldName);
483 detail::make_stvar<STHash256>(field, value.
asString());
487 error =
bad_type(json_name, fieldName);
502 error =
bad_type(json_name, fieldName);
510 ret = detail::make_stvar<STBlob>(
511 field, vBlob->data(), vBlob->size());
515 Throw<std::invalid_argument>(
"invalid data");
553 s.
SetHex(value[i].asString());
556 ret = detail::make_stvar<STVector256>(std::move(tail));
581 if (!value[i].isArrayOrNull())
584 ss << fieldName <<
"[" << i <<
"]";
592 ss << fieldName <<
"[" << i <<
"][" << j <<
"]";
594 json_name +
"." + ss.
str());
610 bool hasCurrency =
false;
617 if (!account.isString())
629 parseBase58<AccountID>(account.asString());
676 parseBase58<AccountID>(issuer.
asString());
688 uAccount, uCurrency, uIssuer, hasCurrency);
693 ret = detail::make_stvar<STPathSet>(std::move(tail));
706 error =
bad_type(json_name, fieldName);
715 auto const account = parseHexOrBase58<AccountID>(strValue);
721 ret = detail::make_stvar<STAccount>(field, *account);
732 error =
bad_type(json_name, fieldName);
742 static boost::optional<detail::STVar>
750 static boost::optional<STObject>
786 switch (field.fieldType)
802 json_name +
"." + fieldName,
809 data.emplace_back(std::move(*ret));
824 json_name +
"." + fieldName,
829 if (array == boost::none)
831 data.emplace_back(std::move(*array));
844 parseLeaf(json_name, fieldName, &inName, value, error);
849 data.emplace_back(std::move(*leaf));
857 data.applyTemplateFromSField(inName);
872 static boost::optional<detail::STVar>
898 bool const isObjectOrNull(json[i].isObjectOrNull());
899 bool const singleKey(isObjectOrNull ? json[i].size() == 1 :
true);
901 if (!isObjectOrNull || !singleKey)
911 std::string const objectName(json[i].getMemberNames()[0]);
921 Json::Value const objectFields(json[i][objectName]);
924 ss << json_name <<
"."
925 <<
"[" << i <<
"]." << objectName;
928 ss.
str(), objectFields, nameField, depth + 1, error);
931 std::string errMsg = error[
"error_message"].asString();
932 error[
"error_message"] =
933 "Error at '" + ss.
str() +
"'. " + errMsg;
946 return detail::make_stvar<STArray>(std::move(tail));
963 using namespace STParsedJSONDetail;
973 using namespace STParsedJSONDetail;
979 auto p =
dynamic_cast<STArray*
>(&arr->get());
983 array = std::move(*p);