1#include <xrpl/json/json_reader.h>
3#include <xrpl/basics/contract.h>
4#include <xrpl/json/json_value.h>
29 result[0] =
static_cast<char>(cp);
34 result[1] =
static_cast<char>(0x80 | (0x3f & cp));
35 result[0] =
static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
37 else if (cp <= 0xFFFF)
40 result[2] =
static_cast<char>(0x80 | (0x3f & cp));
41 result[1] = 0x80 |
static_cast<char>((0x3f & (cp >> 6)));
42 result[0] = 0xE0 |
static_cast<char>((0xf & (cp >> 12)));
44 else if (cp <= 0x10FFFF)
47 result[3] =
static_cast<char>(0x80 | (0x3f & cp));
48 result[2] =
static_cast<char>(0x80 | (0x3f & (cp >> 6)));
49 result[1] =
static_cast<char>(0x80 | (0x3f & (cp >> 12)));
50 result[0] =
static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
64 char const* end = begin +
document_.length();
65 return parse(begin, end, root);
80 return parse(doc, root);
101 if (!root.isNull() && !root.isArray() && !root.isObject())
106 token.
start = beginDoc;
108 addError(
"A valid JSON document must be either an array or an object value.", token);
121 return addError(
"Syntax error: maximum nesting depth exceeded", token);
122 bool successful =
true;
159 return addError(
"Syntax error: value, object or array expected.", token);
179 if (token.
type != type)
237 ok =
match(
"rue", 3);
242 ok =
match(
"alse", 4);
247 ok =
match(
"ull", 3);
281 if (c ==
' ' || c ==
'\t' || c ==
'\r' || c ==
'\n')
298 int index = patternLength;
300 while ((index--) != 0)
302 if (
current_[index] != pattern[index])
345 if (c ==
'\r' || c ==
'\n')
355 static char const kExtendedTokens[] = {
'.',
'e',
'E',
'+',
'-'};
366 if (std::isdigit(
static_cast<unsigned char>(*
current_)) == 0)
370 if (ret ==
std::end(kExtendedTokens))
414 bool initialTokenOk =
true;
443 return addError(
"Key '" + name +
"' appears twice.", tokenName);
463 bool finalizeTokenOk =
true;
509 bool const badTokenType =
512 if (!ok || badTokenType)
529 bool const isNegative = *current ==
'-';
534 if (current == token.
end)
546 "The JSON integer overflow logic will need to be reworked.");
550 Char const c = *current++;
552 if (c <
'0' || c >
'9')
558 value = (value * 10) + (c -
'0');
562 if (current != token.
end)
608 int const bufferSize = 32;
610 int const length = int(token.
end - token.
start);
614 return addError(
"Unable to parse token length", token);
621 char format[] =
"%lf";
622 if (length <= bufferSize)
624 Char buffer[bufferSize + 1];
625 memcpy(buffer, token.
start, length);
627 count = sscanf(buffer, format, &value);
632 count = sscanf(buffer.
c_str(), format, &value);
659 while (current != end)
661 Char const c = *current++;
670 return addError(
"Empty escape sequence in string", token, current);
672 Char const escape = *current++;
709 unsigned int unicode = 0;
719 return addError(
"Bad escape sequence in string", token, current);
737 if (unicode >= 0xD800 && unicode <= 0xDBFF)
740 if (end - current < 6)
743 "additional six characters expected to parse unicode surrogate "
749 unsigned int surrogatePair = 0;
751 if (*current !=
'\\' || *(current + 1) !=
'u')
754 "expecting another \\u token to begin the second half of a unicode surrogate pair",
764 unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
775 unsigned int& unicode)
777 if (end - current < 4)
780 "Bad unicode escape sequence in string: four digits expected.", token, current);
785 for (
int index = 0; index < 4; ++index)
787 Char const c = *current++;
790 if (c >=
'0' && c <=
'9')
794 else if (c >=
'a' && c <=
'f')
796 unicode += c -
'a' + 10;
798 else if (c >=
'A' && c <=
'F')
800 unicode += c -
'A' + 10;
805 "Bad unicode escape sequence in string: hexadecimal digit "
829 int const errorCount = int(
errors_.size());
874 while (current < location && current !=
end_)
876 Char const c = *current++;
880 if (*current ==
'\n')
883 lastLineStart = current;
888 lastLineStart = current;
894 column = int(location - lastLineStart) + 1;
901 int line = 0, column = 0;
911 for (Errors::const_iterator itError =
errors_.begin(); itError !=
errors_.end(); ++itError)
915 formattedMessage +=
" " + error.
message +
"\n";
917 if (error.
extra !=
nullptr)
921 return formattedMessage;
928 bool const ok = reader.
parse(sin, root);
Unserialize a JSON document into a Value.
bool addError(std::string const &message, Token &token, Location extra=0)
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
bool recoverFromError(TokenType skipUntilToken)
bool decodeUnicodeCodePoint(Token &token, Location ¤t, Location end, unsigned int &unicode)
bool readObject(Token &token, unsigned depth)
std::string getFormattedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
void skipCommentTokens(Token &token)
bool decodeDouble(Token &token)
static constexpr unsigned kNestLimit
bool readArray(Token &token, unsigned depth)
Reader::TokenType readNumber()
void getLocationLineAndColumn(Location location, int &line, int &column) const
bool decodeNumber(Token &token)
bool readValue(unsigned depth)
bool readCppStyleComment()
bool expectToken(TokenType type, Token &token, char const *message)
bool decodeUnicodeEscapeSequence(Token &token, Location ¤t, Location end, unsigned int &unicode)
bool addErrorAndRecover(std::string const &message, Token &token, TokenType skipUntilToken)
bool match(Location pattern, int patternLength)
bool readToken(Token &token)
bool decodeString(Token &token)
static constexpr Int kMaxInt
static constexpr UInt kMaxUInt
JSON (JavaScript Object Notation).
std::istream & operator>>(std::istream &, Value &)
Read from 'sin' into 'root'.
static std::string codePointToUTF8(unsigned int cp)
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)