19#include <boost/filesystem/fstream.hpp>
21namespace fc {
namespace json_relaxed
23 template<
typename T,
bool strict>
29 std::stringstream token;
36 switch( c = in.peek() )
50 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
51 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
52 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
54 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
55 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
56 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
58 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
60 case '_':
case '-':
case '.':
case '+':
case '/':
72 catch(
const fc::eof_exception& eof )
76 catch (
const std::ios_base::failure&)
82 (
"token", token.str() ) );
85 template<
typename T,
bool strict,
bool allow_escape>
88 std::stringstream token;
96 FC_THROW_EXCEPTION( parse_error_exception,
"expected: '\"' at beginning of string, got '\''" );
104 FC_THROW_EXCEPTION( parse_error_exception,
"expected: '\"' | '\\\'' at beginning of string" );
110 return std::string();
114 FC_THROW_EXCEPTION( parse_error_exception,
"triple quote unsupported in strict mode" );
141 else if( c ==
'\x04' )
143 (
"token", token.str() ) );
144 else if( allow_escape && (c ==
'\\') )
168 else if( c ==
'\x04' )
170 (
"token", token.str() ) );
171 else if( allow_escape && (c ==
'\\') )
173 else if( (c ==
'\r') | (c ==
'\n') )
175 (
"token", token.str() ) );
184 (
"token", token.str() ) );
187 template<
typename T,
bool strict>
192 char c = in.peek(), c2;
198 FC_THROW_EXCEPTION( parse_error_exception,
"expected: '\"' at beginning of string, got '\''" );
204 FC_THROW_EXCEPTION( parse_error_exception,
"raw strings not supported in strict mode" );
213 FC_THROW_EXCEPTION( parse_error_exception,
"raw strings not supported in strict mode" );
217 FC_THROW_EXCEPTION( parse_error_exception,
"unquoted strings not supported in strict mode" );
221 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
222 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
223 case 'q':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
225 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
226 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
227 case 'Q':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
229 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
231 case '_':
case '-':
case '.':
case '+':
case '/':
233 FC_THROW_EXCEPTION( parse_error_exception,
"unquoted strings not supported in strict mode" );
249 for(
size_t i=0; i<0x100; i++ )
251 c2v[(
unsigned char)
'0'] = 0;
252 c2v[(
unsigned char)
'1'] = 1;
253 c2v[(
unsigned char)
'2'] = 2;
254 c2v[(
unsigned char)
'3'] = 3;
255 c2v[(
unsigned char)
'4'] = 4;
256 c2v[(
unsigned char)
'5'] = 5;
257 c2v[(
unsigned char)
'6'] = 6;
258 c2v[(
unsigned char)
'7'] = 7;
259 c2v[(
unsigned char)
'8'] = 8;
260 c2v[(
unsigned char)
'9'] = 9;
261 c2v[(
unsigned char)
'a'] =
c2v[(
unsigned char)
'A'] = 10;
262 c2v[(
unsigned char)
'b'] =
c2v[(
unsigned char)
'B'] = 11;
263 c2v[(
unsigned char)
'c'] =
c2v[(
unsigned char)
'C'] = 12;
264 c2v[(
unsigned char)
'd'] =
c2v[(
unsigned char)
'D'] = 13;
265 c2v[(
unsigned char)
'e'] =
c2v[(
unsigned char)
'E'] = 14;
266 c2v[(
unsigned char)
'f'] =
c2v[(
unsigned char)
'F'] = 15;
267 c2v[(
unsigned char)
'g'] =
c2v[(
unsigned char)
'G'] = 16;
268 c2v[(
unsigned char)
'h'] =
c2v[(
unsigned char)
'H'] = 17;
269 c2v[(
unsigned char)
'i'] =
c2v[(
unsigned char)
'I'] = 18;
270 c2v[(
unsigned char)
'j'] =
c2v[(
unsigned char)
'J'] = 19;
271 c2v[(
unsigned char)
'k'] =
c2v[(
unsigned char)
'K'] = 20;
272 c2v[(
unsigned char)
'l'] =
c2v[(
unsigned char)
'L'] = 21;
273 c2v[(
unsigned char)
'm'] =
c2v[(
unsigned char)
'M'] = 22;
274 c2v[(
unsigned char)
'n'] =
c2v[(
unsigned char)
'N'] = 23;
275 c2v[(
unsigned char)
'o'] =
c2v[(
unsigned char)
'O'] = 24;
276 c2v[(
unsigned char)
'p'] =
c2v[(
unsigned char)
'P'] = 25;
277 c2v[(
unsigned char)
'q'] =
c2v[(
unsigned char)
'Q'] = 26;
278 c2v[(
unsigned char)
'r'] =
c2v[(
unsigned char)
'R'] = 27;
279 c2v[(
unsigned char)
's'] =
c2v[(
unsigned char)
'S'] = 28;
280 c2v[(
unsigned char)
't'] =
c2v[(
unsigned char)
'T'] = 29;
281 c2v[(
unsigned char)
'u'] =
c2v[(
unsigned char)
'U'] = 30;
282 c2v[(
unsigned char)
'v'] =
c2v[(
unsigned char)
'V'] = 31;
283 c2v[(
unsigned char)
'w'] =
c2v[(
unsigned char)
'W'] = 32;
284 c2v[(
unsigned char)
'x'] =
c2v[(
unsigned char)
'X'] = 33;
285 c2v[(
unsigned char)
'y'] =
c2v[(
unsigned char)
'Y'] = 34;
286 c2v[(
unsigned char)
'z'] =
c2v[(
unsigned char)
'Z'] = 35;
295 template<u
int8_t base>
301 size_t i = start, n = token.length();
313 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character ${c} in integer of base ${b}", (
"c", c)(
"b", base) );
325 if( token[0] ==
'-' )
327 if( val > INT64_MAX_PLUS_ONE )
330 if( val == INT64_MAX_PLUS_ONE )
337 template<
bool strict, u
int8_t base>
344 catch(
const parse_error_exception &e )
353 template<
bool strict>
357 size_t i = 0, n = token.length();
359 FC_THROW_EXCEPTION( parse_error_exception,
"expected: non-empty token, got: empty token" );
384 FC_THROW_EXCEPTION( parse_error_exception,
"binary numeric literals not supported in strict mode" );
392 FC_THROW_EXCEPTION( parse_error_exception,
"octal numeric literals not supported in strict mode" );
397 FC_THROW_EXCEPTION( parse_error_exception,
"hex numeric literals not supported in strict mode" );
406 FC_THROW_EXCEPTION( parse_error_exception,
"expected '.'|'e'|'E' parsing number, got '${c}'",
410 case '1':
case '2':
case '3':
case '4':
411 case '5':
case '6':
case '7':
case '8':
case '9':
413 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
414 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
415 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
417 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
418 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
419 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
421 case '_':
case '-':
case '.':
case '+':
case '/':
423 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' parsing number", (
"c", c ) );
426 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c ) );
441 case '0':
case '1':
case '2':
case '3':
case '4':
442 case '5':
case '6':
case '7':
case '8':
case '9':
452 FC_THROW_EXCEPTION( parse_error_exception,
"number cannot end with '.' in strict mode" );
461 case '0':
case '1':
case '2':
case '3':
case '4':
462 case '5':
case '6':
case '7':
case '8':
case '9':
469 case 'a':
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
470 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
471 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
473 case 'A':
case 'B':
case 'C':
case 'D':
case 'F':
case 'G':
case 'H':
474 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
475 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
477 case '_':
case '-':
case '.':
case '+':
case '/':
482 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c )(
"i",
int(c)) );
497 FC_THROW_EXCEPTION( parse_error_exception,
"expected exponent after 'e'|'E' parsing number" );
511 case '0':
case '1':
case '2':
case '3':
case '4':
512 case '5':
case '6':
case '7':
case '8':
case '9':
514 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
515 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
516 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
518 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
519 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
520 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
522 case '_':
case '.':
case '/':
524 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
527 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in token", (
"c", c ) );
536 case '0':
case '1':
case '2':
case '3':
case '4':
537 case '5':
case '6':
case '7':
case '8':
case '9':
539 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
540 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
541 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
543 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
544 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
545 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
547 case '_':
case '-':
case '.':
case '+':
case '/':
549 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
554 case 'a':
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
case 'h':
555 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
556 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
558 case 'A':
case 'B':
case 'C':
case 'D':
case 'F':
case 'G':
case 'H':
559 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
560 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
562 case '_':
case '-':
case '+':
case '/':
564 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' parsing number", (
"c", c ) );
567 FC_THROW_EXCEPTION( parse_error_exception,
"illegal character '${c}' in number", (
"c", c ) );
572 template<
typename T,
bool strict>
581 "Expected '{', but read '${char}'",
582 (
"char",
string(&c, &c + 1)) );
585 while( in.peek() !=
'}' )
587 if( in.peek() ==
',' )
595 if( in.peek() !=
':' )
603 obj(std::move(key),std::move(val));
606 if( in.peek() ==
'}' )
611 FC_THROW_EXCEPTION( parse_error_exception,
"Expected '}' after ${variant}", (
"variant", obj ) );
613 catch(
const fc::eof_exception& e )
615 FC_THROW_EXCEPTION( parse_error_exception,
"Unexpected EOF: ${e}", (
"e", e.to_detail_string() ) );
617 catch(
const std::ios_base::failure& e )
619 FC_THROW_EXCEPTION( parse_error_exception,
"Unexpected EOF: ${e}", (
"e", e.what() ) );
623 template<
typename T,
bool strict>
629 if( in.peek() !=
'[' )
634 while( in.peek() !=
']' )
636 if( in.peek() ==
',' )
645 if( in.peek() !=
']' )
655 template<
typename T,
bool strict>
660 if( strict && !(result.is_int64() || result.is_uint64() || result.is_double()) )
665 template<
typename T,
bool strict>
675 if( token ==
"null" )
679 if( token ==
"true" )
683 if( token ==
"false" )
696 template<
typename T,
bool strict>
701 while(
signed char c = in.peek() )
732 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
733 case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
734 case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
736 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
737 case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
738 case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
An order-preserving dictionary of variants.
An order-preserving dictionary of variants.
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Defines exception's used by fc.
#define FC_CAPTURE_AND_RETHROW(...)
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
std::string quoteStringFromStream(T &in)
variants arrayFromStream(T &in, uint32_t max_depth)
fc::variant parseNumberOrStr(const std::string &token)
fc::variant maybeParseInt(const std::string &token, size_t start)
variant_object objectFromStream(T &in, uint32_t max_depth)
std::string stringFromStream(T &in)
variant wordFromStream(T &in)
variant variant_from_stream(T &in, uint32_t max_depth)
std::string tokenFromStream(T &in)
fc::variant parseInt(const std::string &token, size_t start)
variant numberFromStream(T &in)
std::string stringFromToken(T &in)
std::vector< fc::variant > variants
bool skip_white_space(T &in)
double to_double(const fc::string &)
#define T(meth, val, expected)
unsigned __int64 uint64_t
uint8_t operator[](char index) const