- Add four-argument version of json-rpc call function
- fix bug in json parser that prevented correct parsing of a true/false/null at the end of input - prevent infinite recursion in a json helper function
This commit is contained in:
parent
7849cc7ada
commit
cd34f696ce
4 changed files with 91 additions and 30 deletions
|
|
@ -56,7 +56,7 @@ namespace fc
|
|||
template<typename T>
|
||||
static void save_to_file( const T& v, const string& p, bool pretty = true )
|
||||
{
|
||||
save_to_file( variant(v), p, pretty );
|
||||
save_to_file( variant(v), fc::path(p), pretty );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,12 @@ namespace fc { namespace rpc {
|
|||
const variant& a2,
|
||||
const variant& a3 );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4 );
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
|
|
@ -86,6 +92,17 @@ namespace fc { namespace rpc {
|
|||
return async_call( method, a1, a2, a3 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
|
|
|
|||
|
|
@ -264,37 +264,58 @@ namespace fc
|
|||
variant token_from_stream( T& in )
|
||||
{
|
||||
fc::stringstream ss;
|
||||
while( char c = in.peek() )
|
||||
bool parsed_unexpected_character = false;
|
||||
bool received_eof = false;
|
||||
try
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case 'n':
|
||||
case 'u':
|
||||
case 'l':
|
||||
case 't':
|
||||
case 'r':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'a':
|
||||
case 's':
|
||||
ss.put( in.get() );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
fc::string str = ss.str();
|
||||
if( str == "null" ) return variant();
|
||||
if( str == "true" ) return true;
|
||||
if( str == "false" ) return false;
|
||||
else
|
||||
{
|
||||
return str;
|
||||
// FC_THROW_EXCEPTION( parse_error_exception, "Invalid token '${token}'",
|
||||
// ("token",str) );
|
||||
}
|
||||
}
|
||||
}
|
||||
char c;
|
||||
while( (c = in.peek()) && !parsed_unexpected_character)
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case 'n':
|
||||
case 'u':
|
||||
case 'l':
|
||||
case 't':
|
||||
case 'r':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'a':
|
||||
case 's':
|
||||
ss.put( in.get() );
|
||||
break;
|
||||
default:
|
||||
parsed_unexpected_character = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (fc::eof_exception&)
|
||||
{
|
||||
received_eof = true;
|
||||
}
|
||||
|
||||
// we can get here either by processing a delimiter as in "null,"
|
||||
// an EOF like "null<EOF>", or an invalid token like "nullZ"
|
||||
fc::string str = ss.str();
|
||||
if( str == "null" ) return variant();
|
||||
if( str == "true" ) return true;
|
||||
if( str == "false" ) return false;
|
||||
else
|
||||
{
|
||||
if (received_eof)
|
||||
FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" );
|
||||
else
|
||||
{
|
||||
// I'm not sure why we do this, a comment would be helpful.
|
||||
// if we've reached this point, we've either seen a partial
|
||||
// token ("tru<EOF>") or something our simple parser couldn't
|
||||
// make out ("falfe")
|
||||
return str;
|
||||
// FC_THROW_EXCEPTION( parse_error_exception, "Invalid token '${token}'",
|
||||
// ("token",str) );
|
||||
}
|
||||
}
|
||||
FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -406,7 +406,30 @@ namespace fc { namespace rpc {
|
|||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>() );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << "]}\n";
|
||||
}
|
||||
my->_out->flush();
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const fc::string& method, mutable_variant_object named_args )
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue