update json parsing to be more flexible and report better errors
This commit is contained in:
parent
38f97ef61a
commit
68e50ee166
2 changed files with 113 additions and 93 deletions
|
|
@ -8,6 +8,7 @@
|
||||||
#include <fc/tuple.hpp>
|
#include <fc/tuple.hpp>
|
||||||
#include <fc/vector.hpp>
|
#include <fc/vector.hpp>
|
||||||
#include <fc/typename.hpp>
|
#include <fc/typename.hpp>
|
||||||
|
#include <fc/error_report.hpp>
|
||||||
|
|
||||||
//#include <typeinfo>
|
//#include <typeinfo>
|
||||||
|
|
||||||
|
|
@ -31,9 +32,12 @@ namespace fc {
|
||||||
virtual void operator()( const double& v ) { m_out = fc::numeric_cast<T>(v); }
|
virtual void operator()( const double& v ) { m_out = fc::numeric_cast<T>(v); }
|
||||||
virtual void operator()( const bool& v ) { m_out = v; }
|
virtual void operator()( const bool& v ) { m_out = v; }
|
||||||
virtual void operator()( const fc::string& v ) { m_out = fc::lexical_cast<T>(v); }
|
virtual void operator()( const fc::string& v ) { m_out = fc::lexical_cast<T>(v); }
|
||||||
virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::object& ) { FC_THROW_REPORT("bad cast to ${type} from object",
|
||||||
virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); }
|
fc::value().set("type",fc::get_typename<T>::name())); }
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::array& ) { FC_THROW_REPORT("bad cast to ${type} from array",
|
||||||
|
fc::value().set("type",fc::get_typename<T>::name())); }
|
||||||
|
virtual void operator()( ) { FC_THROW_REPORT("bad cast to ${type} from null",
|
||||||
|
fc::value().set("type",fc::get_typename<T>::name())); }
|
||||||
private:
|
private:
|
||||||
T& m_out;
|
T& m_out;
|
||||||
};
|
};
|
||||||
|
|
@ -53,9 +57,9 @@ namespace fc {
|
||||||
virtual void operator()( const double& v ){ m_out = v != 0; }
|
virtual void operator()( const double& v ){ m_out = v != 0; }
|
||||||
virtual void operator()( const bool& v ){ m_out = v; }
|
virtual void operator()( const bool& v ){ m_out = v; }
|
||||||
virtual void operator()( const fc::string& v ) { m_out = !(v != "true"); }
|
virtual void operator()( const fc::string& v ) { m_out = !(v != "true"); }
|
||||||
virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::object& ) { FC_THROW_REPORT("bad cast to bool from object"); }
|
||||||
virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::array& ) { FC_THROW_REPORT("bad cast to bool from array"); }
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( ) { FC_THROW_REPORT("bad cast to bool from null"); }
|
||||||
private:
|
private:
|
||||||
bool& m_out;
|
bool& m_out;
|
||||||
};
|
};
|
||||||
|
|
@ -76,9 +80,9 @@ namespace fc {
|
||||||
virtual void operator()( const double& v ) { m_out = fc::lexical_cast<fc::string>(v); }
|
virtual void operator()( const double& v ) { m_out = fc::lexical_cast<fc::string>(v); }
|
||||||
virtual void operator()( const bool& v ) { m_out = v != 0 ? "true" : "false"; }
|
virtual void operator()( const bool& v ) { m_out = v != 0 ? "true" : "false"; }
|
||||||
virtual void operator()( const fc::string& v ) { m_out = v; }
|
virtual void operator()( const fc::string& v ) { m_out = v; }
|
||||||
virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::object& ){ FC_THROW_REPORT("bad cast to string from object"); }
|
||||||
virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( const value::array& ) { FC_THROW_REPORT("bad cast to string from array"); }
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast"); }
|
virtual void operator()( ) { m_out = fc::string(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fc::string& m_out;
|
fc::string& m_out;
|
||||||
|
|
@ -88,21 +92,21 @@ namespace fc {
|
||||||
struct cast_visitor<value::array> : value::const_visitor {
|
struct cast_visitor<value::array> : value::const_visitor {
|
||||||
cast_visitor( value::array& out )
|
cast_visitor( value::array& out )
|
||||||
:m_out(out){}
|
:m_out(out){}
|
||||||
virtual void operator()( const int8_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int8_t& v ) { FC_THROW_REPORT("bad cast to array from int8");}
|
||||||
virtual void operator()( const int16_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int16_t& v ) { FC_THROW_REPORT("bad cast to array from int16");}
|
||||||
virtual void operator()( const int32_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int32_t& v ) { FC_THROW_REPORT("bad cast to array from int32");}
|
||||||
virtual void operator()( const int64_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int64_t& v ) { FC_THROW_REPORT("bad cast to array from int32");}
|
||||||
virtual void operator()( const uint8_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint8_t& v ) { FC_THROW_REPORT("bad cast to array from uint8");}
|
||||||
virtual void operator()( const uint16_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint16_t& v ) { FC_THROW_REPORT("bad cast to array from uint16");}
|
||||||
virtual void operator()( const uint32_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint32_t& v ) { FC_THROW_REPORT("bad cast to array from uint32");}
|
||||||
virtual void operator()( const uint64_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint64_t& v ) { FC_THROW_REPORT("bad cast to array from uint64");}
|
||||||
virtual void operator()( const float& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const float& v ) { FC_THROW_REPORT("bad cast to array from float");}
|
||||||
virtual void operator()( const double& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const double& v ) { FC_THROW_REPORT("bad cast to array from double");}
|
||||||
virtual void operator()( const bool& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const bool& v ) { FC_THROW_REPORT("bad cast to array from bool");}
|
||||||
virtual void operator()( const fc::string& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const fc::string& v ) { FC_THROW_REPORT("bad cast to array from string");}
|
||||||
virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const value::object& ) { FC_THROW_REPORT("bad cast to array from object");}
|
||||||
virtual void operator()( const value::array& a ) { m_out = a; }
|
virtual void operator()( const value::array& a ) { m_out = a; }
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( ) { m_out = value::array(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
value::array& m_out;
|
value::array& m_out;
|
||||||
|
|
@ -112,21 +116,21 @@ namespace fc {
|
||||||
struct cast_visitor<value::object> : value::const_visitor {
|
struct cast_visitor<value::object> : value::const_visitor {
|
||||||
cast_visitor( value::object& out )
|
cast_visitor( value::object& out )
|
||||||
:m_out(out){}
|
:m_out(out){}
|
||||||
virtual void operator()( const int8_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int8_t& v ){ FC_THROW_REPORT("bad cast to array from int8");}
|
||||||
virtual void operator()( const int16_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int16_t& v ){ FC_THROW_REPORT("bad cast to array from int16");}
|
||||||
virtual void operator()( const int32_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int32_t& v ){ FC_THROW_REPORT("bad cast to array from int32");}
|
||||||
virtual void operator()( const int64_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int64_t& v ){ FC_THROW_REPORT("bad cast to array from int32");}
|
||||||
virtual void operator()( const uint8_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint8_t& v ){ FC_THROW_REPORT("bad cast to array from uint8");}
|
||||||
virtual void operator()( const uint16_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint16_t& v ){ FC_THROW_REPORT("bad cast to array from uint16");}
|
||||||
virtual void operator()( const uint32_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint32_t& v ){ FC_THROW_REPORT("bad cast to array from uint32");}
|
||||||
virtual void operator()( const uint64_t& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint64_t& v ){ FC_THROW_REPORT("bad cast to array from uint64");}
|
||||||
virtual void operator()( const float& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const float& v ){ FC_THROW_REPORT("bad cast to array from float");}
|
||||||
virtual void operator()( const double& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const double& v ){ FC_THROW_REPORT("bad cast to array from double");}
|
||||||
virtual void operator()( const bool& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const bool& v ){ FC_THROW_REPORT("bad cast to array from bool");}
|
||||||
virtual void operator()( const fc::string& v ){ FC_THROW_MSG("bad cast");}
|
virtual void operator()( const fc::string& v ) { FC_THROW_REPORT("bad cast to array from string");}
|
||||||
virtual void operator()( const value::object& a ) { m_out = a; }
|
virtual void operator()( const value::object& a ) { m_out = a; }
|
||||||
virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const value::array& ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( ) { m_out = value::object(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
value::object& m_out;
|
value::object& m_out;
|
||||||
|
|
@ -158,28 +162,35 @@ namespace fc {
|
||||||
struct cast_visitor<fc::vector<T>> : value::const_visitor {
|
struct cast_visitor<fc::vector<T>> : value::const_visitor {
|
||||||
cast_visitor( fc::vector<T>& out )
|
cast_visitor( fc::vector<T>& out )
|
||||||
:m_out(out){}
|
:m_out(out){}
|
||||||
virtual void operator()( const int8_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int8_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from int8");}
|
||||||
virtual void operator()( const int16_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int16_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from int16");}
|
||||||
virtual void operator()( const int32_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int32_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from int32");}
|
||||||
virtual void operator()( const int64_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int64_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from int64");}
|
||||||
virtual void operator()( const uint8_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint8_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from uint8");}
|
||||||
virtual void operator()( const uint16_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint16_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from uint16");}
|
||||||
virtual void operator()( const uint32_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint32_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from uint32");}
|
||||||
virtual void operator()( const uint64_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint64_t& v ) { FC_THROW_REPORT("bad cast to vector<T> from uint64");}
|
||||||
virtual void operator()( const float& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const float& v ) { FC_THROW_REPORT("bad cast to vector<T> from float");}
|
||||||
virtual void operator()( const double& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const double& v ) { FC_THROW_REPORT("bad cast to vector<T> from double");}
|
||||||
virtual void operator()( const bool& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const bool& v ) { FC_THROW_REPORT("bad cast to vector<T> from bool");}
|
||||||
virtual void operator()( const fc::string& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const fc::string& v ) { FC_THROW_REPORT("bad cast to vector<T> from string");}
|
||||||
virtual void operator()( const value::object& a ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const value::object& a ) { FC_THROW_REPORT("bad cast to vector<T> from object");}
|
||||||
virtual void operator()( const value::array& a ) {
|
virtual void operator()( const value::array& a ) {
|
||||||
m_out.resize(0);
|
m_out.resize(0);
|
||||||
m_out.reserve( a.fields.size() );
|
m_out.reserve( a.fields.size() );
|
||||||
|
int idx = 0;
|
||||||
for( auto i = a.fields.begin(); i != a.fields.end(); ++i ) {
|
for( auto i = a.fields.begin(); i != a.fields.end(); ++i ) {
|
||||||
|
try {
|
||||||
m_out.push_back( value_cast<T>( *i ) );
|
m_out.push_back( value_cast<T>( *i ) );
|
||||||
|
} catch( fc::error_report& er ) {
|
||||||
|
throw FC_REPORT_PUSH( er, "Error parsing array index ${index} to ${type}",
|
||||||
|
fc::value().set("index", idx).set("type",fc::get_typename<T>::name()) );
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void operator()( ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( ) { FC_THROW_REPORT("bad cast");}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fc::vector<T>& m_out;
|
fc::vector<T>& m_out;
|
||||||
|
|
@ -189,20 +200,20 @@ namespace fc {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct cast_visitor<void> : value::const_visitor {
|
struct cast_visitor<void> : value::const_visitor {
|
||||||
virtual void operator()( const int8_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int8_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const int16_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int16_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const int32_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int32_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const int64_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const int64_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const uint8_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint8_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const uint16_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint16_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const uint32_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint32_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const uint64_t& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const uint64_t& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const float& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const float& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const double& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const double& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const bool& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const bool& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const fc::string& v ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const fc::string& v ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const value::object& a ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const value::object& a ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast");}
|
virtual void operator()( const value::array& ) { FC_THROW_REPORT("bad cast");}
|
||||||
virtual void operator()( ) { }
|
virtual void operator()( ) { }
|
||||||
};
|
};
|
||||||
template<typename IsTuple=fc::false_type>
|
template<typename IsTuple=fc::false_type>
|
||||||
|
|
@ -221,7 +232,11 @@ namespace fc {
|
||||||
:_val(v),idx(0){}
|
:_val(v),idx(0){}
|
||||||
template<typename Member>
|
template<typename Member>
|
||||||
void operator()( Member& m ) {
|
void operator()( Member& m ) {
|
||||||
|
try {
|
||||||
m = value_cast<Member>(_val[idx]);
|
m = value_cast<Member>(_val[idx]);
|
||||||
|
} catch ( fc::error_report& er ) {
|
||||||
|
throw FC_REPORT_PUSH( er, "Error parsing tuple element ${index}", fc::value().set("index",idx) );
|
||||||
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
const value& _val;
|
const value& _val;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <fc/value.hpp>
|
#include <fc/value.hpp>
|
||||||
#include <fc/value_cast.hpp>
|
#include <fc/value_cast.hpp>
|
||||||
#include <fc/tuple.hpp>
|
#include <fc/tuple.hpp>
|
||||||
|
#include <fc/error_report.hpp>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -129,7 +130,11 @@ namespace fc {
|
||||||
template<typename T, typename C, T (C::*p)>
|
template<typename T, typename C, T (C::*p)>
|
||||||
void operator()( const char* name )const {
|
void operator()( const char* name )const {
|
||||||
if( obj.find(name) != obj.end()) {
|
if( obj.find(name) != obj.end()) {
|
||||||
|
try {
|
||||||
fc::unpack( obj[name], c.*p );
|
fc::unpack( obj[name], c.*p );
|
||||||
|
} catch ( fc::error_report& er ) {
|
||||||
|
throw FC_REPORT_PUSH( er, "Error parsing field '${field_name}'", fc::value().set("field_name",name) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( !is_optional< typename fc::remove_reference<decltype(c.*p)>::type >::type::value ) {
|
if( !is_optional< typename fc::remove_reference<decltype(c.*p)>::type >::type::value ) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue