20 #include <ripple/basics/contract.h>
21 #include <ripple/json/json_reader.h>
43 result[0] =
static_cast<char>(cp);
48 result[1] =
static_cast<char>(0x80 | (0x3f & cp));
49 result[0] =
static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
51 else if (cp <= 0xFFFF)
54 result[2] =
static_cast<char>(0x80 | (0x3f & cp));
55 result[1] = 0x80 |
static_cast<char>((0x3f & (cp >> 6)));
56 result[0] = 0xE0 |
static_cast<char>((0xf & (cp >> 12)));
58 else if (cp <= 0x10FFFF)
61 result[3] =
static_cast<char>(0x80 | (0x3f & cp));
62 result[2] =
static_cast<char>(0x80 | (0x3f & (cp >> 6)));
63 result[1] =
static_cast<char>(0x80 | (0x3f & (cp >> 12)));
64 result[0] =
static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
79 return parse(begin, end, root);
94 return parse(doc, root);
115 if (!root.isNull() && !root.isArray() && !root.isObject())
123 "A valid JSON document must be either an array or an object value.",
137 return addError(
"Syntax error: maximum nesting depth exceeded", token);
138 bool successful =
true;
176 "Syntax error: value, object or array expected.", token);
196 if (token.
type_ != type)
254 ok =
match(
"rue", 3);
259 ok =
match(
"alse", 4);
264 ok =
match(
"ull", 3);
298 if (c ==
' ' || c ==
'\t' || c ==
'\r' || c ==
'\n')
311 int index = patternLength;
314 if (
current_[index] != pattern[index])
356 if (c ==
'\r' || c ==
'\n')
366 static char const extended_tokens[] = {
'.',
'e',
'E',
'+',
'-'};
377 if (!std::isdigit(
static_cast<unsigned char>(*
current_)))
384 if (ret ==
std::end(extended_tokens))
424 bool initialTokenOk =
true;
453 return addError(
"Key '" + name +
"' appears twice.", tokenName);
470 "Missing ',' or '}' in object declaration",
475 bool finalizeTokenOk =
true;
526 if (!ok || badTokenType)
529 "Missing ',' or ']' in array declaration",
545 bool isNegative = *current ==
'-';
550 if (current == token.
end_)
554 "' is not a valid number.",
564 "The JSON integer overflow logic will need to be reworked.");
570 if (c < '0' || c >
'9')
574 "' is not a number.",
578 value = (value * 10) + (c -
'0');
582 if (current != token.
end_)
586 "' exceeds the allowable range.",
598 "' exceeds the allowable range.",
610 "' exceeds the allowable range.",
628 const int bufferSize = 32;
634 return addError(
"Unable to parse token length", token);
641 char format[] =
"%lf";
642 if (length <= bufferSize)
644 Char buffer[bufferSize + 1];
645 memcpy(buffer, token.
start_, length);
647 count = sscanf(buffer, format, &value);
652 count = sscanf(buffer.
c_str(), format, &value);
681 while (current != end)
691 "Empty escape sequence in string", token, current);
693 Char escape = *current++;
730 unsigned int unicode;
741 "Bad escape sequence in string", token, current);
758 unsigned int& unicode)
763 if (unicode >= 0xD800 && unicode <= 0xDBFF)
766 if (end - current < 6)
768 "additional six characters expected to parse unicode surrogate "
773 unsigned int surrogatePair;
775 if (*(current++) ==
'\\' && *(current++) ==
'u')
779 unicode = 0x10000 + ((unicode & 0x3FF) << 10) +
780 (surrogatePair & 0x3FF);
787 "expecting another \\u token to begin the second half of a "
788 "unicode surrogate pair",
801 unsigned int& unicode)
803 if (end - current < 4)
805 "Bad unicode escape sequence in string: four digits expected.",
811 for (
int index = 0; index < 4; ++index)
816 if (c >=
'0' && c <=
'9')
818 else if (c >=
'a' && c <=
'f')
819 unicode += c -
'a' + 10;
820 else if (c >=
'A' && c <=
'F')
821 unicode += c -
'A' + 10;
824 "Bad unicode escape sequence in string: hexadecimal digit "
896 while (current < location && current !=
end_)
902 if (*current ==
'\n')
905 lastLineStart = current;
910 lastLineStart = current;
916 column = int(location - lastLineStart) + 1;
925 char buffer[18 + 16 + 16 + 1];
926 sprintf(buffer,
"Line %d, Column %d", line, column);
942 formattedMessage +=
" " +
error.message_ +
"\n";
945 formattedMessage +=
"See " +
949 return formattedMessage;
956 bool ok = reader.
parse(sin, root);
bool addError(std::string const &message, Token &token, Location extra=0)
void skipCommentTokens(Token &token)
@ arrayValue
array value (ordered list)
bool decodeDouble(Token &token)
bool decodeString(Token &token)
bool readObject(Token &token, unsigned depth)
Unserialize a JSON document into a Value.
bool expectToken(TokenType type, Token &token, const char *message)
bool readValue(unsigned depth)
JSON (JavaScript Object Notation).
bool decodeNumber(Token &token)
@ objectValue
object value (collection of name/value pairs).
bool match(Location pattern, int patternLength)
bool decodeUnicodeCodePoint(Token &token, Location ¤t, Location end, unsigned int &unicode)
void getLocationLineAndColumn(Location location, int &line, int &column) const
bool decodeUnicodeEscapeSequence(Token &token, Location ¤t, Location end, unsigned int &unicode)
static const UInt maxUInt
static std::string codePointToUTF8(unsigned int cp)
std::istream & operator>>(std::istream &sin, Value &root)
Read from 'sin' into 'root'.
static constexpr unsigned nest_limit
bool readToken(Token &token)
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
bool recoverFromError(TokenType skipUntilToken)
bool readArray(Token &token, unsigned depth)
Reader::TokenType readNumber()
bool readCppStyleComment()
bool addErrorAndRecover(std::string const &message, Token &token, TokenType skipUntilToken)