FC Updates from BitShares and myself #21

Closed
nathanielhourt wants to merge 687 commits from dapp-support into latest-fc
Showing only changes of commit e37d9a5051 - Show all commits

View file

@ -5,7 +5,6 @@
#include <fc/io/fstream.hpp> #include <fc/io/fstream.hpp>
#include <fc/io/sstream.hpp> #include <fc/io/sstream.hpp>
#include <fc/log/logger.hpp> #include <fc/log/logger.hpp>
//#include <utfcpp/utf8.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -179,7 +178,6 @@ namespace fc
"Expected '{', but read '${char}'", "Expected '{', but read '${char}'",
("char",string(&c, &c + 1)) ); ("char",string(&c, &c + 1)) );
in.get(); in.get();
skip_white_space(in);
while( in.peek() != '}' ) while( in.peek() != '}' )
{ {
if( in.peek() == ',' ) if( in.peek() == ',' )
@ -199,7 +197,6 @@ namespace fc
auto val = variant_from_stream<T, parser_type>( in ); auto val = variant_from_stream<T, parser_type>( in );
obj(std::move(key),std::move(val)); obj(std::move(key),std::move(val));
skip_white_space(in);
} }
if( in.peek() == '}' ) if( in.peek() == '}' )
{ {
@ -227,7 +224,6 @@ namespace fc
if( in.peek() != '[' ) if( in.peek() != '[' )
FC_THROW_EXCEPTION( parse_error_exception, "Expected '['" ); FC_THROW_EXCEPTION( parse_error_exception, "Expected '['" );
in.get(); in.get();
skip_white_space(in);
while( in.peek() != ']' ) while( in.peek() != ']' )
{ {
@ -238,7 +234,6 @@ namespace fc
} }
if( skip_white_space(in) ) continue; if( skip_white_space(in) ) continue;
ar.push_back( variant_from_stream<T, parser_type>(in) ); ar.push_back( variant_from_stream<T, parser_type>(in) );
skip_white_space(in);
} }
if( in.peek() != ']' ) if( in.peek() != ']' )
FC_THROW_EXCEPTION( parse_error_exception, "Expected ']' after parsing ${variant}", FC_THROW_EXCEPTION( parse_error_exception, "Expected ']' after parsing ${variant}",
@ -276,6 +271,7 @@ namespace fc
if (dot) if (dot)
FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places"); FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places");
dot = true; dot = true;
[[fallthrough]];
case '0': case '0':
case '1': case '1':
case '2': case '2':
@ -299,10 +295,10 @@ namespace fc
} }
} }
catch (fc::eof_exception&) catch (fc::eof_exception&)
{ { // EOF ends the loop
} }
catch (const std::ios_base::failure&) catch (const std::ios_base::failure&)
{ { // read error ends the loop
} }
fc::string str = ss.str(); fc::string str = ss.str();
if (str == "-." || str == ".") // check the obviously wrong things we could have encountered if (str == "-." || str == ".") // check the obviously wrong things we could have encountered
@ -379,7 +375,7 @@ namespace fc
// make out ("falfe") // make out ("falfe")
// A strict JSON parser would signal this as an error, but we // A strict JSON parser would signal this as an error, but we
// will just treat the malformed token as an un-quoted string. // will just treat the malformed token as an un-quoted string.
return str + stringFromToken(in);; return str + stringFromToken(in);
} }
} }
} }
@ -389,53 +385,42 @@ namespace fc
variant variant_from_stream( T& in ) variant variant_from_stream( T& in )
{ {
skip_white_space(in); skip_white_space(in);
variant var; signed char c = in.peek();
while( true ) switch( c )
{ {
signed char c = in.peek(); case '"':
switch( c ) return stringFromStream( in );
{ case '{':
case ' ': return objectFromStream<T, parser_type>( in );
case '\t': case '[':
case '\n': return arrayFromStream<T, parser_type>( in );
case '\r': case '-':
in.get(); case '.':
continue; case '0':
case '"': case '1':
return stringFromStream( in ); case '2':
case '{': case '3':
return objectFromStream<T, parser_type>( in ); case '4':
case '[': case '5':
return arrayFromStream<T, parser_type>( in ); case '6':
case '-': case '7':
case '.': case '8':
case '0': case '9':
case '1': return number_from_stream<T, parser_type>( in );
case '2': // null, true, false, or 'warning' / string
case '3': case 'n':
case '4': case 't':
case '5': case 'f':
case '6': return token_from_stream( in );
case '7': case 0x04: // ^D end of transmission
case '8': case EOF:
case '9': FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
return number_from_stream<T, parser_type>( in ); case 0:
// null, true, false, or 'warning' / string default:
case 'n': FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
case 't': ("c", c)("s", stringFromToken(in)) );
case 'f':
return token_from_stream( in );
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)) );
}
} }
return variant(); }
}
/** the purpose of this check is to verify that we will not get a stack overflow in the recursive descent parser */ /** the purpose of this check is to verify that we will not get a stack overflow in the recursive descent parser */
@ -467,33 +452,18 @@ namespace fc
} FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) ) } } FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) ) }
variants json::variants_from_string( const std::string& utf8_str, parse_type ptype ) variants json::variants_from_string( const std::string& utf8_str, parse_type ptype )
{ try { {
check_string_depth( utf8_str );
variants result; variants result;
fc::stringstream in( utf8_str );
//in.exceptions( std::ifstream::eofbit );
try { try {
check_string_depth( utf8_str );
fc::stringstream in( utf8_str );
while( true ) while( true )
{ result.push_back(json_relaxed::variant_from_stream<fc::stringstream, false>( in ));
// result.push_back( variant_from_stream( in )); } catch ( const fc::eof_exception& ) {
result.push_back(json_relaxed::variant_from_stream<fc::stringstream, false>( in )); return result;
} } FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) )
} catch ( const fc::eof_exception& ){}
return result;
} FC_RETHROW_EXCEPTIONS( warn, "", ("str",utf8_str) ) }
/*
void toUTF8( const char str, ostream& os )
{
// validate str == valid utf8
utf8::replace_invalid( &str, &str + 1, ostream_iterator<char>(os) );
} }
void toUTF8( const wchar_t c, ostream& os )
{
utf8::utf16to8( &c, (&c)+1, ostream_iterator<char>(os) );
}
*/
/** /**
* Convert '\t', '\a', '\n', '\\' and '"' to "\t\a\n\\\"" * Convert '\t', '\a', '\n', '\\' and '"' to "\t\a\n\\\""
* *
@ -563,7 +533,6 @@ namespace fc
default: default:
os << *itr; os << *itr;
//toUTF8( *itr, os );
} }
} }
os << '"'; os << '"';
@ -616,27 +585,19 @@ namespace fc
os << "null"; os << "null";
return; return;
case variant::int64_type: case variant::int64_type:
{
int64_t i = v.as_int64();
if( format == json::stringify_large_ints_and_doubles && if( format == json::stringify_large_ints_and_doubles &&
i > 0xffffffff ) v.as_int64() > 0xffffffff )
os << '"'<<v.as_string()<<'"'; os << '"'<<v.as_string()<<'"';
else else
os << i; os << v.as_int64();
return; return;
}
case variant::uint64_type: case variant::uint64_type:
{
uint64_t i = v.as_uint64();
if( format == json::stringify_large_ints_and_doubles && if( format == json::stringify_large_ints_and_doubles &&
i > 0xffffffff ) v.as_uint64() > 0xffffffff )
os << '"'<<v.as_string()<<'"'; os << '"'<<v.as_string()<<'"';
else else
os << i; os << v.as_uint64();
return; return;
}
case variant::double_type: case variant::double_type:
if (format == json::stringify_large_ints_and_doubles) if (format == json::stringify_large_ints_and_doubles)
os << '"'<<v.as_string()<<'"'; os << '"'<<v.as_string()<<'"';
@ -653,17 +614,13 @@ namespace fc
escape_string( v.as_string(), os ); escape_string( v.as_string(), os );
return; return;
case variant::array_type: case variant::array_type:
{ to_stream( os, v.get_array(), format );
const variants& a = v.get_array();
to_stream( os, a, format );
return; return;
}
case variant::object_type: case variant::object_type:
{ to_stream(os, v.get_object(), format );
const variant_object& o = v.get_object();
to_stream(os, o, format );
return; return;
} default:
FC_THROW_EXCEPTION( fc::invalid_arg_exception, "Unsupported variant type: " + v.get_type() );
} }
} }
@ -750,7 +707,7 @@ namespace fc
//If we're in quotes and see a \n, just print it literally but unset the escape flag. //If we're in quotes and see a \n, just print it literally but unset the escape flag.
if( quote && escape ) if( quote && escape )
escape = false; escape = false;
//No break; fall through to default case [[fallthrough]];
default: default:
if( first ) { if( first ) {
ss<<'\n'; ss<<'\n';