From 43fabf618f644c1888cda51dc8dc905f6209f833 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Mon, 5 Mar 2018 22:36:01 +0100 Subject: [PATCH] Code deduplication --- include/fc/io/json_relaxed.hpp | 76 ++-------------------------------- src/io/json.cpp | 27 +++++++++--- 2 files changed, 24 insertions(+), 79 deletions(-) diff --git a/include/fc/io/json_relaxed.hpp b/include/fc/io/json_relaxed.hpp index e4876f2..26a89a5 100644 --- a/include/fc/io/json_relaxed.hpp +++ b/include/fc/io/json_relaxed.hpp @@ -564,84 +564,14 @@ namespace fc { namespace json_relaxed template variant_object objectFromStream( T& in ) { - 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); - while( in.peek() != '}' ) - { - if( in.peek() == ',' ) - { - in.get(); - continue; - } - if( skip_white_space(in) ) continue; - string key = json_relaxed::stringFromStream( in ); - skip_white_space(in); - if( in.peek() != ':' ) - { - FC_THROW_EXCEPTION( parse_error_exception, "Expected ':' after key \"${key}\"", - ("key", key) ); - } - in.get(); - auto val = json_relaxed::variant_from_stream( in ); - - obj(std::move(key),std::move(val)); - skip_white_space(in); - } - 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" ); + return objectFromStreamBase( in, []( T& in ){ return json_relaxed::stringFromStream( in ); }, + []( T& in ){ return json_relaxed::variant_from_stream( in ); } ); } template variants arrayFromStream( T& in ) { - variants ar; - try - { - if( in.peek() != '[' ) - FC_THROW_EXCEPTION( parse_error_exception, "Expected '['" ); - in.get(); - skip_white_space(in); - - while( in.peek() != ']' ) - { - if( in.peek() == ',' ) - { - in.get(); - continue; - } - if( skip_white_space(in) ) continue; - ar.push_back( json_relaxed::variant_from_stream(in) ); - skip_white_space(in); - } - if( in.peek() != ']' ) - FC_THROW_EXCEPTION( parse_error_exception, "Expected ']' after parsing ${variant}", - ("variant", ar) ); - - in.get(); - } FC_RETHROW_EXCEPTIONS( warn, "Attempting to parse array ${array}", - ("array", ar ) ); - return ar; + return arrayFromStreamBase( in, []( T& in ){ return json_relaxed::variant_from_stream( in ); } ); } template diff --git a/src/io/json.cpp b/src/io/json.cpp index 99feab9..8f4f2c1 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -19,7 +19,9 @@ namespace fc template fc::string stringFromStream( T& in ); template bool skip_white_space( T& in ); template fc::string stringFromToken( T& in ); + template variant_object objectFromStreamBase( T& in, std::function& get_key, std::function& get_value ); template variant_object objectFromStream( T& in ); + template variants arrayFromStreamBase( T& in, std::function& get_value ); template variants arrayFromStream( T& in ); template variant number_from_stream( T& in ); template variant token_from_stream( T& in ); @@ -166,8 +168,8 @@ namespace fc ("token", token.str() ) ); } - template - variant_object objectFromStream( T& in ) + template + variant_object objectFromStreamBase( T& in, std::string (*get_key)(T&), variant (*get_value)(T&) ) { mutable_variant_object obj; try @@ -186,7 +188,7 @@ namespace fc continue; } if( skip_white_space(in) ) continue; - string key = stringFromStream( in ); + string key = get_key( in ); skip_white_space(in); if( in.peek() != ':' ) { @@ -194,7 +196,7 @@ namespace fc ("key", key) ); } in.get(); - auto val = variant_from_stream( in ); + auto val = get_value( in ); obj(std::move(key),std::move(val)); } @@ -216,7 +218,14 @@ namespace fc } template - variants arrayFromStream( T& in ) + variant_object objectFromStream( T& in ) + { + return objectFromStreamBase( in, []( T& in ){ return stringFromStream( in ); }, + []( T& in ){ return variant_from_stream( in ); } ); + } + + template + variants arrayFromStreamBase( T& in, variant (*get_value)(T&) ) { variants ar; try @@ -233,7 +242,7 @@ namespace fc continue; } if( skip_white_space(in) ) continue; - ar.push_back( variant_from_stream(in) ); + ar.push_back( get_value(in) ); } if( in.peek() != ']' ) FC_THROW_EXCEPTION( parse_error_exception, "Expected ']' after parsing ${variant}", @@ -245,6 +254,12 @@ namespace fc return ar; } + template + variants arrayFromStream( T& in ) + { + return arrayFromStreamBase( in, []( T& in ){ return variant_from_stream( in ); } ); + } + template variant number_from_stream( T& in ) {