fix json pretty print, added value::clear
This commit is contained in:
parent
5c21d1d45c
commit
c3659eedfc
6 changed files with 147 additions and 21 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <fc/string.hpp>
|
#include <fc/string.hpp>
|
||||||
|
#include <fc/typename.hpp>
|
||||||
#include <fc/fwd.hpp>
|
#include <fc/fwd.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
@ -98,5 +99,7 @@ namespace fc {
|
||||||
class value;
|
class value;
|
||||||
void pack( fc::value& , const fc::path& );
|
void pack( fc::value& , const fc::path& );
|
||||||
void unpack( const fc::value& , fc::path& );
|
void unpack( const fc::value& , fc::path& );
|
||||||
|
|
||||||
|
template<> struct get_typename<path> { static const char* name() { return "path"; } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ namespace fc {
|
||||||
|
|
||||||
namespace json {
|
namespace json {
|
||||||
string to_string( const value& o );
|
string to_string( const value& o );
|
||||||
|
string to_pretty_string( const value& v );
|
||||||
|
|
||||||
|
|
||||||
value from_string( const string& s );
|
value from_string( const string& s );
|
||||||
|
|
@ -32,6 +33,10 @@ namespace fc {
|
||||||
string to_string( const T& o ) {
|
string to_string( const T& o ) {
|
||||||
return json::to_string(value(o));
|
return json::to_string(value(o));
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
string to_pretty_string( const T& o ) {
|
||||||
|
return json::to_pretty_string(value(o));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T from_string( const string& s ) {
|
T from_string( const string& s ) {
|
||||||
|
|
@ -43,6 +48,7 @@ namespace fc {
|
||||||
T from_file( const fc::path& s ) {
|
T from_file( const fc::path& s ) {
|
||||||
return value_cast<T>( fc::json::from_file(s) );
|
return value_cast<T>( fc::json::from_file(s) );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
} // fc
|
} // fc
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ namespace fc {
|
||||||
/* sets the subkey key with v and return *this */
|
/* sets the subkey key with v and return *this */
|
||||||
value& set( const char* key, fc::value v );
|
value& set( const char* key, fc::value v );
|
||||||
value& set( const fc::string& key, fc::value v );
|
value& set( const fc::string& key, fc::value v );
|
||||||
|
value& clear( const fc::string& key );
|
||||||
|
|
||||||
template<typename S, typename T>
|
template<typename S, typename T>
|
||||||
value& set( S&& key, T&& v ) { return set( fc::forward<S>(key), fc::value( fc::forward<T>(v) ) ); }
|
value& set( S&& key, T&& v ) { return set( fc::forward<S>(key), fc::value( fc::forward<T>(v) ) ); }
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,8 @@ namespace fc {
|
||||||
int idx = 0;
|
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 {
|
try {
|
||||||
m_out.push_back( value_cast<T>( *i ) );
|
m_out.push_back(T());
|
||||||
|
unpack( *i, m_out.back() );
|
||||||
} catch( fc::error_report& er ) {
|
} catch( fc::error_report& er ) {
|
||||||
throw FC_REPORT_PUSH( er, "Error parsing array index ${index} to ${type}",
|
throw FC_REPORT_PUSH( er, "Error parsing array index ${index} to ${type}",
|
||||||
fc::value().set("index", idx).set("type",fc::get_typename<T>::name()) );
|
fc::value().set("index", idx).set("type",fc::get_typename<T>::name()) );
|
||||||
|
|
@ -233,7 +234,9 @@ namespace fc {
|
||||||
template<typename Member>
|
template<typename Member>
|
||||||
void operator()( Member& m ) {
|
void operator()( Member& m ) {
|
||||||
try {
|
try {
|
||||||
m = value_cast<Member>(_val[idx]);
|
//m = value_cast<Member>(_val[idx]);
|
||||||
|
unpack( _val[idx], m );
|
||||||
|
// m = value_cast<Member>(_val[idx]);
|
||||||
} catch ( fc::error_report& er ) {
|
} catch ( fc::error_report& er ) {
|
||||||
throw FC_REPORT_PUSH( er, "Error parsing tuple element ${index}", fc::value().set("index",idx) );
|
throw FC_REPORT_PUSH( er, "Error parsing tuple element ${index}", fc::value().set("index",idx) );
|
||||||
}
|
}
|
||||||
|
|
@ -329,6 +332,9 @@ namespace fc {
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T value::cast()const {
|
T value::cast()const {
|
||||||
return value_cast<T>(*this);
|
T tmp;
|
||||||
|
unpack(*this,tmp);
|
||||||
|
return tmp;
|
||||||
|
// return unpackvalue_cast<T>(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
96
src/json.cpp
96
src/json.cpp
|
|
@ -1,8 +1,8 @@
|
||||||
|
#include <fc/filesystem.hpp>
|
||||||
#include <fc/json.hpp>
|
#include <fc/json.hpp>
|
||||||
#include <fc/hex.hpp>
|
#include <fc/hex.hpp>
|
||||||
#include <fc/exception.hpp>
|
#include <fc/exception.hpp>
|
||||||
#include <fc/sstream.hpp>
|
#include <fc/sstream.hpp>
|
||||||
#include <fc/filesystem.hpp>
|
|
||||||
#include <fc/interprocess/file_mapping.hpp>
|
#include <fc/interprocess/file_mapping.hpp>
|
||||||
#include <fc/error_report.hpp>
|
#include <fc/error_report.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
@ -785,6 +785,88 @@ fc::value to_value( char* start, char* end, error_collector& ec ) {
|
||||||
}
|
}
|
||||||
namespace fc { namespace json {
|
namespace fc { namespace json {
|
||||||
|
|
||||||
|
fc::string pretty_print( const fc::string& v, uint8_t indent ) {
|
||||||
|
int level = 0;
|
||||||
|
fc::stringstream ss;
|
||||||
|
bool first = false;
|
||||||
|
bool quote = false;
|
||||||
|
bool escape = false;
|
||||||
|
for( uint32_t i = 0; i < v.size(); ++i ) {
|
||||||
|
switch( v[i] ) {
|
||||||
|
case '\\':
|
||||||
|
if( !escape ) {
|
||||||
|
if( quote )
|
||||||
|
escape = true;
|
||||||
|
} else { escape = false; }
|
||||||
|
ss<<v[i];
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
if( !quote ) {
|
||||||
|
ss<<": ";
|
||||||
|
} else {
|
||||||
|
ss<<':';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
if( first ) {
|
||||||
|
ss<<'\n';
|
||||||
|
for( int i = 0; i < level*indent; ++i ) ss<<' ';
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
if( !escape ) {
|
||||||
|
quote = !quote;
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
ss<<'"';
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
case '[':
|
||||||
|
ss<<v[i];
|
||||||
|
if( !quote ) {
|
||||||
|
++level;
|
||||||
|
first = true;
|
||||||
|
}else {
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
case ']':
|
||||||
|
if( !quote ) {
|
||||||
|
if( v[i-1] != '[' && v[i-1] != '{' ) {
|
||||||
|
ss<<'\n';
|
||||||
|
}
|
||||||
|
--level;
|
||||||
|
if( !first ) {
|
||||||
|
for( int i = 0; i < level*indent; ++i ) ss<<' ';
|
||||||
|
}
|
||||||
|
ss<<v[i];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
escape = false;
|
||||||
|
ss<<v[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
if( !quote ) {
|
||||||
|
ss<<',';
|
||||||
|
first = true;
|
||||||
|
} else {
|
||||||
|
escape = false;
|
||||||
|
ss<<',';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if( first ) {
|
||||||
|
ss<<'\n';
|
||||||
|
for( int i = 0; i < level*indent; ++i ) ss<<' ';
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
ss << v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
||||||
int level = 0;
|
int level = 0;
|
||||||
fc::stringstream ss;
|
fc::stringstream ss;
|
||||||
|
|
@ -919,6 +1001,10 @@ fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fc::string to_pretty_string( const fc::value& v ) {
|
||||||
|
return pretty_print( to_string(v), 4 );
|
||||||
|
}
|
||||||
|
|
||||||
value from_file( const fc::path& local_path ) {
|
value from_file( const fc::path& local_path ) {
|
||||||
if( !exists(local_path) ) {
|
if( !exists(local_path) ) {
|
||||||
FC_THROW_REPORT( "Source file ${filename} does not exist", value().set("filename",local_path.string()) );
|
FC_THROW_REPORT( "Source file ${filename} does not exist", value().set("filename",local_path.string()) );
|
||||||
|
|
@ -927,7 +1013,7 @@ fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
||||||
FC_THROW_REPORT( "Source path ${path} is a directory; a file was expected",
|
FC_THROW_REPORT( "Source path ${path} is a directory; a file was expected",
|
||||||
value().set("path",local_path.string()) );
|
value().set("path",local_path.string()) );
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
// memory map the file
|
// memory map the file
|
||||||
size_t fsize = static_cast<size_t>(file_size(local_path));
|
size_t fsize = static_cast<size_t>(file_size(local_path));
|
||||||
if( fsize == 0 ) { return value(); }
|
if( fsize == 0 ) { return value(); }
|
||||||
|
|
@ -944,6 +1030,12 @@ fc::string pretty_print( fc::vector<char>&& v, uint8_t indent ) {
|
||||||
|
|
||||||
error_collector ec;
|
error_collector ec;
|
||||||
return to_value(tmp.data(), tmp.data()+fsize,ec);
|
return to_value(tmp.data(), tmp.data()+fsize,ec);
|
||||||
|
} catch ( ... ) {
|
||||||
|
FC_THROW_REPORT( "Error loading JSON object from file '${path}'",
|
||||||
|
fc::value().set( "file", local_path )
|
||||||
|
.set( "exception", fc::except_str() )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value from_string( const fc::string& s ) {
|
value from_string( const fc::string& s ) {
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,24 @@ value::object::const_iterator value::end()const {
|
||||||
return value::object::const_iterator();
|
return value::object::const_iterator();
|
||||||
//return nullptr;
|
//return nullptr;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* If this value is an object, remove key from the object
|
||||||
|
*
|
||||||
|
* @return *this;
|
||||||
|
*/
|
||||||
|
value& value::clear( const fc::string& key ) {
|
||||||
|
if( strcmp(gh(holder)->type(), "object") == 0) {
|
||||||
|
detail::value_holder_impl<value::object>* o = dynamic_cast<detail::value_holder_impl<value::object>*>(gh(holder));
|
||||||
|
for( auto i = o->val.fields.begin();
|
||||||
|
i != o->val.fields.end(); ++i ) {
|
||||||
|
if( strcmp( i->key.c_str(), key.c_str() ) == 0 ) {
|
||||||
|
o->val.fields.erase(i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
value& value::operator[]( const char* key ) {
|
value& value::operator[]( const char* key ) {
|
||||||
if( strcmp(gh(holder)->type(), "object") == 0) {
|
if( strcmp(gh(holder)->type(), "object") == 0) {
|
||||||
detail::value_holder_impl<value::object>* o = dynamic_cast<detail::value_holder_impl<value::object>*>(gh(holder));
|
detail::value_holder_impl<value::object>* o = dynamic_cast<detail::value_holder_impl<value::object>*>(gh(holder));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue