variant variant_from_stream( T& in, uint32_t depth ) { depth++; FC_ASSERT( depth <= JSON_MAX_RECURSION_DEPTH ); skip_white_space( in, depth ); variant var; while( true ) { signed char c = in.peek(); switch( c ) { case ' ': case '\t': case '\n': case '\r': in.get(); continue; case '"': return stringFromStream( in, depth ); case '{': return objectFromStream<T, parser_type>( in, depth ); case '[': return arrayFromStream<T, parser_type>( in, depth ); case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return number_from_stream<T, parser_type>( in, depth ); // null, true, false, or 'warning' / string case 'n': case 't': case 'f': return token_from_stream( in, depth ); case 0x04: // ^D end of transmission case EOF: case 0: FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" ); default: FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"", ("c", c)("s", stringFromToken( in, depth )) ); } } return variant(); }
variant variant_from_stream( T& in, uint32_t max_depth ) { if( max_depth == 0 ) FC_THROW_EXCEPTION( parse_error_exception, "Too many nested items in JSON input!" ); skip_white_space(in); signed char c = in.peek(); switch( c ) { case '"': return stringFromStream( in ); case '{': return objectFromStream<T, parser_type>( in, max_depth - 1 ); case '[': return arrayFromStream<T, parser_type>( in, max_depth - 1 ); case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return number_from_stream<T, parser_type>( in ); // null, true, false, or 'warning' / string case 'n': case 't': case 'f': return token_from_stream( in ); case 0x04: // ^D end of transmission case EOF: FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" ); case 0: if( parser_type == fc::json::broken_nul_parser ) return variant(); FALLTHROUGH default: FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"", ("c", c)("s", stringFromToken(in)) ); } }