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_object objectFromStream( T& in, uint32_t depth ) { depth++; FC_ASSERT( depth <= JSON_MAX_RECURSION_DEPTH ); mutable_variant_object obj; try { char c = in.peek(); if( c != '{' ) FC_THROW_EXCEPTION( parse_error_exception, "Expected '{', but read '${char}'", ("char",string(&c, &c + 1)) ); in.get(); skip_white_space( in, depth ); while( in.peek() != '}' ) { if( in.peek() == ',' ) { in.get(); continue; } if( skip_white_space( in, depth ) ) continue; string key = stringFromStream( in, depth ); skip_white_space( in, depth ); if( in.peek() != ':' ) { FC_THROW_EXCEPTION( parse_error_exception, "Expected ':' after key \"${key}\"", ("key", key) ); } in.get(); auto val = variant_from_stream<T, parser_type>( in, depth ); obj(std::move(key),std::move(val)); skip_white_space( in, depth ); } if( in.peek() == '}' ) { in.get(); return obj; } FC_THROW_EXCEPTION( parse_error_exception, "Expected '}' after ${variant}", ("variant", obj ) ); } catch( const fc::eof_exception& e ) { FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF: ${e}", ("e", e.to_detail_string() ) ); } catch( const std::ios_base::failure& e ) { FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF: ${e}", ("e", e.what() ) ); } FC_RETHROW_EXCEPTIONS( warn, "Error parsing object" ); }
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)) ); } }
Object * Read::readAtom(std::istream& stream) { std::string stringFromStream(std::istreambuf_iterator<char>(stream), {});; std::string read = getWord(stringFromStream); if (isNumber(read)) { Number * number = new Number(std::stoi(read)); return number; } if (isString(read)) { String * string = new String(read.substr(1, read.size() - 2)); return string; } Symbol * symbol = symbolsList.findSymbol(read); if (symbol) return symbol; Symbol * newSymbol = new Symbol(read, NULL); return newSymbol; }
variant_object objectFromStream( T& in, uint32_t max_depth ) { std::function<std::string(T&)> get_key = []( T& in ){ return stringFromStream( in ); }; std::function<variant(T&)> get_value = [max_depth]( T& in ){ return variant_from_stream<T, parser_type>( in, max_depth ); }; return objectFromStreamBase<T>( in, get_key, get_value ); }