Code deduplication

This commit is contained in:
Peter Conrad 2018-03-05 22:36:01 +01:00 committed by Peter Conrad
parent e37d9a5051
commit 43fabf618f
2 changed files with 24 additions and 79 deletions

View file

@ -564,84 +564,14 @@ namespace fc { namespace json_relaxed
template<typename T, bool strict>
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<T, strict>( 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<T, strict>( 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<T>( in, []( T& in ){ return json_relaxed::stringFromStream<T, strict>( in ); },
[]( T& in ){ return json_relaxed::variant_from_stream<T, strict>( in ); } );
}
template<typename T, bool strict>
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<T, strict>(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<T>( in, []( T& in ){ return json_relaxed::variant_from_stream<T, strict>( in ); } );
}
template<typename T, bool strict>

View file

@ -19,7 +19,9 @@ namespace fc
template<typename T> fc::string stringFromStream( T& in );
template<typename T> bool skip_white_space( T& in );
template<typename T> fc::string stringFromToken( T& in );
template<typename T> variant_object objectFromStreamBase( T& in, std::function<std::string(T&)>& get_key, std::function<variant(T&)>& get_value );
template<typename T, json::parse_type parser_type> variant_object objectFromStream( T& in );
template<typename T> variants arrayFromStreamBase( T& in, std::function<variant(T&)>& get_value );
template<typename T, json::parse_type parser_type> variants arrayFromStream( T& in );
template<typename T, json::parse_type parser_type> variant number_from_stream( T& in );
template<typename T> variant token_from_stream( T& in );
@ -166,8 +168,8 @@ namespace fc
("token", token.str() ) );
}
template<typename T, json::parse_type parser_type>
variant_object objectFromStream( T& in )
template<typename T>
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<T, parser_type>( in );
auto val = get_value( in );
obj(std::move(key),std::move(val));
}
@ -216,7 +218,14 @@ namespace fc
}
template<typename T, json::parse_type parser_type>
variants arrayFromStream( T& in )
variant_object objectFromStream( T& in )
{
return objectFromStreamBase<T>( in, []( T& in ){ return stringFromStream( in ); },
[]( T& in ){ return variant_from_stream<T, parser_type>( in ); } );
}
template<typename T>
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<T, parser_type>(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<typename T, json::parse_type parser_type>
variants arrayFromStream( T& in )
{
return arrayFromStreamBase<T>( in, []( T& in ){ return variant_from_stream<T, parser_type>( in ); } );
}
template<typename T, json::parse_type parser_type>
variant number_from_stream( T& in )
{