parent
10a857ee78
commit
33215ffb6e
70 changed files with 823 additions and 748 deletions
|
|
@ -102,14 +102,14 @@ namespace fc {
|
|||
{ return 0 != memcmp( a.data, b.data, N*sizeof(T) ); }
|
||||
|
||||
template<typename T, size_t N>
|
||||
void to_variant( const array<T,N>& bi, variant& v )
|
||||
void to_variant( const array<T,N>& bi, variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, 1 );
|
||||
}
|
||||
template<typename T, size_t N>
|
||||
void from_variant( const variant& v, array<T,N>& bi )
|
||||
void from_variant( const variant& v, array<T,N>& bi, uint32_t max_depth = 1 )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
std::vector<char> ve = v.as< std::vector<char> >( 1 );
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
|
|
|
|||
|
|
@ -2,3 +2,8 @@
|
|||
// The maximum level of object nesting is around 20% of this value
|
||||
#define FC_PACK_MAX_DEPTH 1000
|
||||
#endif
|
||||
|
||||
#ifndef FC_MAX_LOG_OBJECT_DEPTH
|
||||
// how many levels of nested objects are displayed in log messages
|
||||
#define FC_MAX_LOG_OBJECT_DEPTH 200
|
||||
#endif
|
||||
|
|
@ -99,41 +99,48 @@ namespace fc {
|
|||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const flat_set<T>& var, variant& vo )
|
||||
void to_variant( const flat_set<T>& var, variant& vo, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
--_max_depth;
|
||||
std::vector<variant> vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = variant(*itr);
|
||||
for( const auto& item : var )
|
||||
vars[i++] = variant( item, _max_depth );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, flat_set<T>& vo )
|
||||
void from_variant( const variant& var, flat_set<T>& vo, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
--_max_depth;
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
vo.reserve( vars.size() );
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as<T>() );
|
||||
for( const auto& item : vars )
|
||||
vo.insert( item.as<T>(_max_depth) );
|
||||
}
|
||||
|
||||
template<typename K, typename... T>
|
||||
void to_variant( const flat_map<K, T...>& var, variant& vo )
|
||||
void to_variant( const flat_map<K, T...>& var, variant& vo, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
--_max_depth;
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = fc::variant(*itr);
|
||||
for( const auto& item : var )
|
||||
vars[i++] = variant( item, _max_depth );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename K, typename T, typename... A>
|
||||
void from_variant( const variant& var, flat_map<K, T, A...>& vo )
|
||||
void from_variant( const variant& var, flat_map<K, T, A...>& vo, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
--_max_depth;
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as< std::pair<K,T> >() );
|
||||
|
||||
for( const auto& item : vars )
|
||||
vo.insert( item.as<std::pair<K,T>>(_max_depth) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ namespace fc {
|
|||
|
||||
class variant;
|
||||
/** encodes the big int as base64 string, or a number */
|
||||
void to_variant( const bigint& bi, variant& v );
|
||||
void to_variant( const bigint& bi, variant& v, uint32_t max_depth = 1 );
|
||||
/** decodes the big int as base64 string, or a number */
|
||||
void from_variant( const variant& v, bigint& bi );
|
||||
void from_variant( const variant& v, bigint& bi, uint32_t max_depth = 1 );
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
|
|
@ -230,10 +230,10 @@ namespace fc {
|
|||
|
||||
|
||||
} // namespace ecc
|
||||
void to_variant( const ecc::private_key& var, variant& vo );
|
||||
void from_variant( const variant& var, ecc::private_key& vo );
|
||||
void to_variant( const ecc::public_key& var, variant& vo );
|
||||
void from_variant( const variant& var, ecc::public_key& vo );
|
||||
void to_variant( const ecc::private_key& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, ecc::private_key& vo, uint32_t max_depth );
|
||||
void to_variant( const ecc::public_key& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, ecc::public_key& vo, uint32_t max_depth );
|
||||
|
||||
namespace raw
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,10 +108,10 @@ namespace fc {
|
|||
}
|
||||
}
|
||||
class variant;
|
||||
void to_variant( const public_key& bi, variant& v );
|
||||
void from_variant( const variant& v, public_key& bi );
|
||||
void to_variant( const private_key& bi, variant& v );
|
||||
void from_variant( const variant& v, private_key& bi );
|
||||
void to_variant( const public_key& bi, variant& v, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& v, public_key& bi, uint32_t max_depth = 1 );
|
||||
void to_variant( const private_key& bi, variant& v, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& v, private_key& bi, uint32_t max_depth = 1 );
|
||||
|
||||
} // fc
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ class ripemd160
|
|||
};
|
||||
|
||||
class variant;
|
||||
void to_variant( const ripemd160& bi, variant& v );
|
||||
void from_variant( const variant& v, ripemd160& bi );
|
||||
void to_variant( const ripemd160& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, ripemd160& bi, uint32_t max_depth );
|
||||
|
||||
typedef ripemd160 uint160_t;
|
||||
typedef ripemd160 uint160;
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ class sha1
|
|||
};
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha1& bi, variant& v );
|
||||
void from_variant( const variant& v, sha1& bi );
|
||||
void to_variant( const sha1& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, sha1& bi, uint32_t max_depth );
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ class sha224
|
|||
};
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha224& bi, variant& v );
|
||||
void from_variant( const variant& v, sha224& bi );
|
||||
void to_variant( const sha224& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, sha224& bi, uint32_t max_depth );
|
||||
|
||||
} // fc
|
||||
namespace std
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ class sha256
|
|||
typedef sha256 uint256;
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha256& bi, variant& v );
|
||||
void from_variant( const variant& v, sha256& bi );
|
||||
void to_variant( const sha256& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, sha256& bi, uint32_t max_depth );
|
||||
|
||||
uint64_t hash64(const char* buf, size_t len);
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ class sha512
|
|||
typedef fc::sha512 uint512;
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha512& bi, variant& v );
|
||||
void from_variant( const variant& v, sha512& bi );
|
||||
void to_variant( const sha512& bi, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& v, sha512& bi, uint32_t max_depth );
|
||||
|
||||
} // fc
|
||||
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ namespace fc
|
|||
*/
|
||||
virtual std::shared_ptr<exception> dynamic_copy_exception()const;
|
||||
|
||||
friend void to_variant( const exception& e, variant& v );
|
||||
friend void from_variant( const variant& e, exception& ll );
|
||||
friend void to_variant( const exception& e, variant& v, uint32_t max_depth );
|
||||
friend void from_variant( const variant& e, exception& ll, uint32_t max_depth );
|
||||
|
||||
exception& operator=( const exception& copy );
|
||||
exception& operator=( exception&& copy );
|
||||
|
|
@ -125,8 +125,8 @@ namespace fc
|
|||
std::unique_ptr<detail::exception_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const exception& e, variant& v );
|
||||
void from_variant( const variant& e, exception& ll );
|
||||
void to_variant( const exception& e, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& e, exception& ll, uint32_t max_depth );
|
||||
typedef std::shared_ptr<exception> exception_ptr;
|
||||
|
||||
typedef optional<exception> oexception;
|
||||
|
|
|
|||
|
|
@ -182,8 +182,8 @@ namespace fc {
|
|||
const fc::path& current_path();
|
||||
|
||||
class variant;
|
||||
void to_variant( const fc::path&, fc::variant& );
|
||||
void from_variant( const fc::variant& , fc::path& );
|
||||
void to_variant( const fc::path&, fc::variant&, uint32_t max_depth = 1 );
|
||||
void from_variant( const fc::variant&, fc::path&, uint32_t max_depth = 1 );
|
||||
|
||||
template<> struct get_typename<path> { static const char* name() { return "path"; } };
|
||||
|
||||
|
|
|
|||
|
|
@ -121,43 +121,23 @@ namespace fc {
|
|||
left -= 1024;
|
||||
}
|
||||
s.read( buf, left );
|
||||
|
||||
/*
|
||||
s.seekp( s.tellp() + (size.value - sizeof(Storage)) );
|
||||
char tmp;
|
||||
size.value -= sizeof(storage);
|
||||
while( size.value ){ s.read( &tmp, 1 ); --size.value; }
|
||||
*/
|
||||
// s.skip( size.value - sizeof(Storage) );
|
||||
} else {
|
||||
s.read( (char*)&u.data, size.value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Stream, typename... Args>
|
||||
inline void pack( Stream& s, const boost::multiprecision::number<Args...>& d, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
|
||||
s.write( (const char*)&d, sizeof(d) );
|
||||
}
|
||||
|
||||
template<typename Stream, typename... Args>
|
||||
inline void unpack( Stream& s, boost::multiprecision::number<Args...>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
|
||||
s.read( (const char*)&u, sizeof(u) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#include <fc/variant.hpp>
|
||||
namespace fc {
|
||||
template<typename Storage>
|
||||
void to_variant( const fixed_string<Storage>& s, variant& v ) {
|
||||
void to_variant( const fixed_string<Storage>& s, variant& v, uint32_t max_depth = 1 ) {
|
||||
v = std::string(s);
|
||||
}
|
||||
|
||||
template<typename Storage>
|
||||
void from_variant( const variant& v, fixed_string<Storage>& s ) {
|
||||
void from_variant( const variant& v, fixed_string<Storage>& s, uint32_t max_depth = 1 ) {
|
||||
s = v.as_string();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <boost/interprocess/containers/set.hpp>
|
||||
#include <boost/interprocess/containers/deque.hpp>
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -16,87 +17,76 @@ namespace fc {
|
|||
namespace bip = boost::interprocess;
|
||||
|
||||
template<typename... T >
|
||||
void to_variant( const bip::deque< T... >& t, fc::variant& v ) {
|
||||
void to_variant( const bip::deque< T... >& t, fc::variant& v, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
std::vector<variant> vars(t.size());
|
||||
for( size_t i = 0; i < t.size(); ++i ) {
|
||||
vars[i] = t[i];
|
||||
to_variant( t[i], vars[i], max_depth );
|
||||
}
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
template<typename T, typename... A>
|
||||
void from_variant( const fc::variant& v, bip::deque< T, A... >& d ) {
|
||||
void from_variant( const fc::variant& v, bip::deque< T, A... >& d, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
const variants& vars = v.get_array();
|
||||
d.clear();
|
||||
d.resize( vars.size() );
|
||||
for( uint32_t i = 0; i < vars.size(); ++i ) {
|
||||
from_variant( vars[i], d[i] );
|
||||
from_variant( vars[i], d[i], max_depth );
|
||||
}
|
||||
}
|
||||
|
||||
//bip::map == boost::map
|
||||
template<typename K, typename V, typename... T >
|
||||
void to_variant( const bip::map< K, V, T... >& var, fc::variant& vo ) {
|
||||
void to_variant( const bip::map< K, V, T... >& var, fc::variant& vo, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = fc::variant(*itr);
|
||||
vars[i] = fc::variant( *itr, max_depth );
|
||||
vo = vars;
|
||||
}
|
||||
/*
|
||||
template<typename K, typename V, typename... A>
|
||||
void from_variant( const variant& var, bip::map<K, V, A...>& vo )
|
||||
{
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as< std::pair<K,V> >() ); Not safe for interprocess. Needs allocator
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename... T >
|
||||
void to_variant( const bip::vector< T... >& t, fc::variant& v ) {
|
||||
void to_variant( const bip::vector< T... >& t, fc::variant& v, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
std::vector<variant> vars(t.size());
|
||||
for( size_t i = 0; i < t.size(); ++i ) {
|
||||
vars[i] = t[i];
|
||||
to_variant( t[i], vars[i], max_depth );
|
||||
}
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
template<typename T, typename... A>
|
||||
void from_variant( const fc::variant& v, bip::vector< T, A... >& d ) {
|
||||
void from_variant( const fc::variant& v, bip::vector< T, A... >& d, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
const variants& vars = v.get_array();
|
||||
d.clear();
|
||||
d.resize( vars.size() );
|
||||
for( uint32_t i = 0; i < vars.size(); ++i ) {
|
||||
from_variant( vars[i], d[i] );
|
||||
from_variant( vars[i], d[i], max_depth );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... T >
|
||||
void to_variant( const bip::set< T... >& t, fc::variant& v ) {
|
||||
void to_variant( const bip::set< T... >& t, fc::variant& v, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
--max_depth;
|
||||
std::vector<variant> vars;
|
||||
vars.reserve(t.size());
|
||||
for( const auto& item : t ) {
|
||||
vars.emplace_back( item );
|
||||
vars.emplace_back( variant( item, max_depth ) );
|
||||
}
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename T, typename... A>
|
||||
void from_variant( const fc::variant& v, bip::set< T, A... >& d ) {
|
||||
const variants& vars = v.get_array();
|
||||
d.clear();
|
||||
d.reserve( vars.size() );
|
||||
for( uint32_t i = 0; i < vars.size(); ++i ) {
|
||||
from_variant( vars[i], d[i] ); Not safe for interprocess. Needs allocator
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename... A>
|
||||
void to_variant( const bip::vector<char, A...>& t, fc::variant& v )
|
||||
void to_variant( const bip::vector<char, A...>& t, fc::variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
if( t.size() )
|
||||
v = variant(fc::to_hex(t.data(), t.size()));
|
||||
|
|
@ -105,7 +95,7 @@ namespace fc {
|
|||
}
|
||||
|
||||
template<typename... A>
|
||||
void from_variant( const fc::variant& v, bip::vector<char, A...>& d )
|
||||
void from_variant( const fc::variant& v, bip::vector<char, A...>& d, uint32_t max_depth = 1 )
|
||||
{
|
||||
auto str = v.as_string();
|
||||
d.resize( str.size() / 2 );
|
||||
|
|
@ -114,8 +104,6 @@ namespace fc {
|
|||
size_t r = fc::from_hex( str, d.data(), d.size() );
|
||||
FC_ASSERT( r == d.size() );
|
||||
}
|
||||
// std::string b64 = base64_decode( var.as_string() );
|
||||
// vo = std::vector<char>( b64.c_str(), b64.c_str() + b64.size() );
|
||||
}
|
||||
|
||||
namespace raw {
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ namespace fc
|
|||
|
||||
|
||||
template<typename IntType, typename EnumType>
|
||||
void to_variant( const enum_type<IntType,EnumType>& var, variant& vo )
|
||||
void to_variant( const enum_type<IntType,EnumType>& var, variant& vo, uint32_t max_depth = 1 )
|
||||
{
|
||||
vo = (EnumType)var.value;
|
||||
to_variant( var.value, vo, max_depth );
|
||||
}
|
||||
template<typename IntType, typename EnumType>
|
||||
void from_variant( const variant& var, enum_type<IntType,EnumType>& vo )
|
||||
void from_variant( const variant& var, enum_type<IntType,EnumType>& vo, uint32_t max_depth )
|
||||
{
|
||||
vo.value = var.as<EnumType>();
|
||||
vo.value = var.as<EnumType>(1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace fc
|
|||
template<typename T>
|
||||
static void save_to_file( const T& v, const fc::path& fi, bool pretty = true, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH )
|
||||
{
|
||||
save_to_file( variant(v), fi, pretty, format, max_depth );
|
||||
save_to_file( variant(v, max_depth), fi, pretty, format, max_depth );
|
||||
}
|
||||
|
||||
static void save_to_file( const variant& v, const fc::path& fi, bool pretty = true, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH );
|
||||
|
|
@ -61,25 +61,25 @@ namespace fc
|
|||
template<typename T>
|
||||
static T from_file( const fc::path& p, parse_type ptype = legacy_parser, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH )
|
||||
{
|
||||
return json::from_file(p, ptype, max_depth).as<T>();
|
||||
return json::from_file(p, ptype, max_depth).as<T>(max_depth);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static string to_string( const T& v, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH )
|
||||
{
|
||||
return to_string( variant(v), format, max_depth );
|
||||
return to_string( variant(v, max_depth), format, max_depth );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static string to_pretty_string( const T& v, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH )
|
||||
{
|
||||
return to_pretty_string( variant(v), format, max_depth );
|
||||
return to_pretty_string( variant(v, max_depth), format, max_depth );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void save_to_file( const T& v, const std::string& p, bool pretty = true, output_formatting format = stringify_large_ints_and_doubles, uint32_t max_depth = DEFAULT_MAX_RECURSION_DEPTH )
|
||||
{
|
||||
save_to_file( variant(v), fc::path(p), pretty, format, max_depth );
|
||||
save_to_file( variant(v, max_depth), fc::path(p), pretty, format, max_depth );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/safe.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
|
|
@ -57,15 +58,17 @@ namespace fc {
|
|||
inline void pack( Stream& s, const fc::log_message& msg, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
fc::raw::pack( s, variant(msg), _max_depth - 1 ); // TODO check variant depth?
|
||||
--_max_depth;
|
||||
fc::raw::pack( s, variant( msg, std::min( _max_depth, uint32_t(FC_MAX_LOG_OBJECT_DEPTH) ) ), _max_depth );
|
||||
}
|
||||
template<typename Stream>
|
||||
inline void unpack( Stream& s, fc::log_message& msg, uint32_t _max_depth )
|
||||
{
|
||||
FC_ASSERT( _max_depth > 0 );
|
||||
fc::variant vmsg;
|
||||
fc::raw::unpack( s, vmsg, _max_depth - 1 );
|
||||
msg = vmsg.as<log_message>(); // TODO check depth?
|
||||
--_max_depth;
|
||||
fc::raw::unpack( s, vmsg, _max_depth );
|
||||
msg = vmsg.as<log_message>( std::min( _max_depth, uint32_t(FC_MAX_LOG_OBJECT_DEPTH) ) );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ struct signed_int {
|
|||
|
||||
class variant;
|
||||
|
||||
void to_variant( const signed_int& var, variant& vo );
|
||||
void from_variant( const variant& var, signed_int& vo );
|
||||
void to_variant( const unsigned_int& var, variant& vo );
|
||||
void from_variant( const variant& var, unsigned_int& vo );
|
||||
void to_variant( const signed_int& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, signed_int& vo, uint32_t max_depth = 1 );
|
||||
void to_variant( const unsigned_int& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, unsigned_int& vo, uint32_t max_depth = 1 );
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,12 @@ namespace fc
|
|||
{
|
||||
config()
|
||||
:format( "${timestamp} ${thread_name} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
stream(console_appender::stream::std_error),flush(true){}
|
||||
stream(console_appender::stream::std_error),max_object_depth(FC_MAX_LOG_OBJECT_DEPTH),flush(true){}
|
||||
|
||||
fc::string format;
|
||||
console_appender::stream::type stream;
|
||||
std::vector<level_color> level_colors;
|
||||
uint32_t max_object_depth;
|
||||
bool flush;
|
||||
};
|
||||
|
||||
|
|
@ -69,4 +70,4 @@ namespace fc
|
|||
FC_REFLECT_ENUM( fc::console_appender::stream::type, (std_out)(std_error) )
|
||||
FC_REFLECT_ENUM( fc::console_appender::color::type, (red)(green)(brown)(blue)(magenta)(cyan)(white)(console_default) )
|
||||
FC_REFLECT( fc::console_appender::level_color, (level)(color) )
|
||||
FC_REFLECT( fc::console_appender::config, (format)(stream)(level_colors)(flush) )
|
||||
FC_REFLECT( fc::console_appender::config, (format)(stream)(level_colors)(max_object_depth)(flush) )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class file_appender : public appender {
|
|||
microseconds rotation_interval;
|
||||
microseconds rotation_limit;
|
||||
bool rotation_compression = false;
|
||||
uint32_t max_object_depth;
|
||||
};
|
||||
file_appender( const variant& args );
|
||||
~file_appender();
|
||||
|
|
@ -32,4 +33,4 @@ class file_appender : public appender {
|
|||
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
FC_REFLECT( fc::file_appender::config,
|
||||
(format)(filename)(flush)(rotate)(rotation_interval)(rotation_limit)(rotation_compression) )
|
||||
(format)(filename)(flush)(rotate)(rotation_interval)(rotation_limit)(rotation_compression)(max_object_depth) )
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace fc
|
|||
{
|
||||
string endpoint = "127.0.0.1:12201";
|
||||
string host = "fc"; // the name of the host, source or application that sent this message (just passed through to GELF server)
|
||||
uint32_t max_object_depth;
|
||||
};
|
||||
|
||||
gelf_appender(const variant& args);
|
||||
|
|
@ -29,4 +30,4 @@ namespace fc
|
|||
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
FC_REFLECT(fc::gelf_appender::config,
|
||||
(endpoint)(host))
|
||||
(endpoint)(host)(max_object_depth))
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
* @file log_message.hpp
|
||||
* @brief Defines types and helper macros necessary for generating log messages.
|
||||
*/
|
||||
#include <fc/config.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
|
|
@ -51,8 +52,8 @@ namespace fc
|
|||
values value;
|
||||
};
|
||||
|
||||
void to_variant( log_level e, variant& v );
|
||||
void from_variant( const variant& e, log_level& ll );
|
||||
void to_variant( log_level e, variant& v, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& e, log_level& ll, uint32_t max_depth = 1 );
|
||||
|
||||
/**
|
||||
* @brief provides information about where and when a log message was generated.
|
||||
|
|
@ -69,8 +70,8 @@ namespace fc
|
|||
uint64_t line,
|
||||
const char* method );
|
||||
~log_context();
|
||||
explicit log_context( const variant& v );
|
||||
variant to_variant()const;
|
||||
explicit log_context( const variant& v, uint32_t max_depth );
|
||||
variant to_variant( uint32_t max_depth )const;
|
||||
|
||||
string get_file()const;
|
||||
uint64_t get_line_number()const;
|
||||
|
|
@ -89,8 +90,8 @@ namespace fc
|
|||
std::shared_ptr<detail::log_context_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const log_context& l, variant& v );
|
||||
void from_variant( const variant& l, log_context& c );
|
||||
void to_variant( const log_context& l, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& l, log_context& c, uint32_t max_depth );
|
||||
|
||||
/**
|
||||
* @brief aggregates a message along with the context and associated meta-information.
|
||||
|
|
@ -120,8 +121,8 @@ namespace fc
|
|||
log_message( log_context ctx, std::string format, variant_object args = variant_object() );
|
||||
~log_message();
|
||||
|
||||
log_message( const variant& v );
|
||||
variant to_variant()const;
|
||||
log_message( const variant& v, uint32_t max_depth );
|
||||
variant to_variant(uint32_t max_depth)const;
|
||||
|
||||
string get_message()const;
|
||||
|
||||
|
|
@ -133,8 +134,8 @@ namespace fc
|
|||
std::shared_ptr<detail::log_message_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const log_message& l, variant& v );
|
||||
void from_variant( const variant& l, log_message& c );
|
||||
void to_variant( const log_message& l, variant& v, uint32_t max_depth );
|
||||
void from_variant( const variant& l, log_message& c, uint32_t max_depth );
|
||||
|
||||
typedef std::vector<log_message> log_messages;
|
||||
|
||||
|
|
@ -165,8 +166,8 @@ FC_REFLECT_TYPENAME( fc::log_message );
|
|||
* @param FORMAT A const char* string containing zero or more references to keys as "${key}"
|
||||
* @param ... A set of key/value pairs denoted as ("key",val)("key2",val2)...
|
||||
*/
|
||||
#define FC_LOG_MESSAGE_GENERATE_PARAMETER_NAME(VALUE) BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(VALUE), fc::variant(VALUE) BOOST_PP_RPAREN()
|
||||
#define FC_LOG_MESSAGE_DONT_GENERATE_PARAMETER_NAME(NAME, VALUE) BOOST_PP_LPAREN() NAME, fc::variant(VALUE) BOOST_PP_RPAREN()
|
||||
#define FC_LOG_MESSAGE_GENERATE_PARAMETER_NAME(VALUE) BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(VALUE), fc::variant(VALUE, FC_MAX_LOG_OBJECT_DEPTH) BOOST_PP_RPAREN()
|
||||
#define FC_LOG_MESSAGE_DONT_GENERATE_PARAMETER_NAME(NAME, VALUE) BOOST_PP_LPAREN() NAME, fc::variant(VALUE, FC_MAX_LOG_OBJECT_DEPTH) BOOST_PP_RPAREN()
|
||||
#define FC_LOG_MESSAGE_GENERATE_PARAMETER_NAMES_IF_NEEDED(r, data, PARAMETER_AND_MAYBE_NAME) BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE PARAMETER_AND_MAYBE_NAME,1),FC_LOG_MESSAGE_GENERATE_PARAMETER_NAME,FC_LOG_MESSAGE_DONT_GENERATE_PARAMETER_NAME)PARAMETER_AND_MAYBE_NAME
|
||||
|
||||
#define FC_LOG_MESSAGE_STRING_ONLY(LOG_LEVEL, FORMAT) \
|
||||
|
|
@ -174,6 +175,5 @@ FC_REFLECT_TYPENAME( fc::log_message );
|
|||
#define FC_LOG_MESSAGE_WITH_SUBSTITUTIONS(LOG_LEVEL, FORMAT, ...) \
|
||||
fc::log_message(FC_LOG_CONTEXT(LOG_LEVEL), FORMAT, fc::mutable_variant_object() BOOST_PP_SEQ_FOR_EACH(FC_LOG_MESSAGE_GENERATE_PARAMETER_NAMES_IF_NEEDED, _, BOOST_PP_VARIADIC_SEQ_TO_SEQ(__VA_ARGS__)))
|
||||
|
||||
|
||||
#define FC_LOG_MESSAGE(LOG_LEVEL, ...) \
|
||||
BOOST_PP_EXPAND(BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),1),FC_LOG_MESSAGE_STRING_ONLY,FC_LOG_MESSAGE_WITH_SUBSTITUTIONS)(LOG_LEVEL,__VA_ARGS__))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <fc/config.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
|
|
@ -145,7 +146,7 @@ namespace fc
|
|||
BOOST_PP_STRINGIZE(base) ": ${" BOOST_PP_STRINGIZE( base ) "} "
|
||||
|
||||
#define FC_FORMAT_ARGS(r, unused, base) \
|
||||
BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(base),fc::variant(base) BOOST_PP_RPAREN()
|
||||
BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(base),fc::variant(base,FC_MAX_LOG_OBJECT_DEPTH) BOOST_PP_RPAREN()
|
||||
|
||||
#define FC_FORMAT( SEQ )\
|
||||
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARG, v, SEQ )
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@ namespace fc {
|
|||
|
||||
}
|
||||
class variant;
|
||||
void to_variant( const ip::endpoint& var, variant& vo );
|
||||
void from_variant( const variant& var, ip::endpoint& vo );
|
||||
void to_variant( const ip::endpoint& var, variant& vo, uint32_t _max_depth = 2 );
|
||||
void from_variant( const variant& var, ip::endpoint& vo, uint32_t _max_depth = 2 );
|
||||
|
||||
void to_variant( const ip::address& var, variant& vo );
|
||||
void from_variant( const variant& var, ip::address& vo );
|
||||
void to_variant( const ip::address& var, variant& vo, uint32_t _max_depth = 1 );
|
||||
void from_variant( const variant& var, ip::address& vo, uint32_t _max_depth = 1 );
|
||||
|
||||
|
||||
namespace raw
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ namespace fc {
|
|||
std::shared_ptr<detail::url_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const url& u, fc::variant& v );
|
||||
void from_variant( const fc::variant& v, url& u );
|
||||
void to_variant( const url& u, fc::variant& v, uint32_t max_depth = 1 );
|
||||
void from_variant( const fc::variant& v, url& u, uint32_t max_depth = 1 );
|
||||
|
||||
/**
|
||||
* Used to create / manipulate a URL
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ namespace fc {
|
|||
uint128 fixed;
|
||||
};
|
||||
|
||||
void to_variant( const real128& var, variant& vo );
|
||||
void from_variant( const variant& var, real128& vo );
|
||||
void to_variant( const real128& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, real128& vo, uint32_t max_depth = 1 );
|
||||
|
||||
namespace raw
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,17 +5,19 @@
|
|||
namespace fc
|
||||
{
|
||||
template<typename T>
|
||||
void to_variant( const T& o, variant& v );
|
||||
void to_variant( const T& o, variant& v, uint32_t max_depth );
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, T& o );
|
||||
void from_variant( const variant& v, T& o, uint32_t max_depth );
|
||||
|
||||
|
||||
template<typename T>
|
||||
class to_variant_visitor
|
||||
{
|
||||
public:
|
||||
to_variant_visitor( mutable_variant_object& mvo, const T& v )
|
||||
:vo(mvo),val(v){}
|
||||
to_variant_visitor( mutable_variant_object& mvo, const T& v, uint32_t max_depth )
|
||||
:vo(mvo),val(v),_max_depth(max_depth - 1) {
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
}
|
||||
|
||||
template<typename Member, class Class, Member (Class::*member)>
|
||||
void operator()( const char* name )const
|
||||
|
|
@ -28,63 +30,67 @@ namespace fc
|
|||
void add( mutable_variant_object& vo, const char* name, const optional<M>& v )const
|
||||
{
|
||||
if( v.valid() )
|
||||
vo(name,*v);
|
||||
vo(name, variant( *v, _max_depth ));
|
||||
}
|
||||
template<typename M>
|
||||
void add( mutable_variant_object& vo, const char* name, const M& v )const
|
||||
{ vo(name,v); }
|
||||
{ vo(name, variant( v, _max_depth )); }
|
||||
|
||||
mutable_variant_object& vo;
|
||||
const T& val;
|
||||
const uint32_t _max_depth;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class from_variant_visitor
|
||||
{
|
||||
public:
|
||||
from_variant_visitor( const variant_object& _vo, T& v )
|
||||
:vo(_vo),val(v){}
|
||||
from_variant_visitor( const variant_object& _vo, T& v, uint32_t max_depth )
|
||||
:vo(_vo),val(v),_max_depth(max_depth - 1) {
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
}
|
||||
|
||||
template<typename Member, class Class, Member (Class::*member)>
|
||||
void operator()( const char* name )const
|
||||
{
|
||||
auto itr = vo.find(name);
|
||||
if( itr != vo.end() )
|
||||
from_variant( itr->value(), val.*member );
|
||||
from_variant( itr->value(), val.*member, _max_depth );
|
||||
}
|
||||
|
||||
const variant_object& vo;
|
||||
T& val;
|
||||
const uint32_t _max_depth;
|
||||
};
|
||||
|
||||
template<typename IsReflected=fc::false_type>
|
||||
template<typename IsEnum=fc::false_type>
|
||||
struct if_enum
|
||||
{
|
||||
template<typename T>
|
||||
static inline void to_variant( const T& v, fc::variant& vo )
|
||||
{
|
||||
template<typename T>
|
||||
static inline void to_variant( const T& v, fc::variant& vo, uint32_t max_depth )
|
||||
{
|
||||
mutable_variant_object mvo;
|
||||
fc::reflector<T>::visit( to_variant_visitor<T>( mvo, v ) );
|
||||
fc::reflector<T>::visit( to_variant_visitor<T>( mvo, v, max_depth ) );
|
||||
vo = fc::move(mvo);
|
||||
}
|
||||
template<typename T>
|
||||
static inline void from_variant( const fc::variant& v, T& o )
|
||||
{
|
||||
}
|
||||
template<typename T>
|
||||
static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth )
|
||||
{
|
||||
const variant_object& vo = v.get_object();
|
||||
fc::reflector<T>::visit( from_variant_visitor<T>( vo, o ) );
|
||||
}
|
||||
fc::reflector<T>::visit( from_variant_visitor<T>( vo, o, max_depth ) );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct if_enum<fc::true_type>
|
||||
{
|
||||
template<typename T>
|
||||
static inline void to_variant( const T& o, fc::variant& v )
|
||||
static inline void to_variant( const T& o, fc::variant& v, uint32_t max_depth = 1 )
|
||||
{
|
||||
v = fc::reflector<T>::to_fc_string(o);
|
||||
}
|
||||
template<typename T>
|
||||
static inline void from_variant( const fc::variant& v, T& o )
|
||||
static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth = 1 )
|
||||
{
|
||||
if( v.is_string() )
|
||||
o = fc::reflector<T>::from_string( v.get_string().c_str() );
|
||||
|
|
@ -95,15 +101,14 @@ namespace fc
|
|||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const T& o, variant& v )
|
||||
void to_variant( const T& o, variant& v, uint32_t max_depth )
|
||||
{
|
||||
if_enum<typename fc::reflector<T>::is_enum>::to_variant( o, v );
|
||||
if_enum<typename fc::reflector<T>::is_enum>::to_variant( o, v, max_depth );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, T& o )
|
||||
void from_variant( const variant& v, T& o, uint32_t max_depth )
|
||||
{
|
||||
if_enum<typename fc::reflector<T>::is_enum>::from_variant( v, o );
|
||||
if_enum<typename fc::reflector<T>::is_enum>::from_variant( v, o, max_depth );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include <functional>
|
||||
#include <utility>
|
||||
#include <fc/signals.hpp>
|
||||
//#include <fc/rpc/json_connection.hpp>
|
||||
|
||||
namespace fc {
|
||||
class api_connection;
|
||||
|
|
@ -37,31 +36,34 @@ namespace fc {
|
|||
return [=]( Args... args ) { return f( a0, args... ); };
|
||||
}
|
||||
template<typename R>
|
||||
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e )
|
||||
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 )
|
||||
{
|
||||
return f();
|
||||
}
|
||||
|
||||
template<typename R, typename Arg0, typename ... Args>
|
||||
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
|
||||
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( a0 != e );
|
||||
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >() ), a0+1, e );
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >( max_depth - 1 ) ), a0+1, e, max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename R, typename ... Args>
|
||||
std::function<variant(const fc::variants&)> to_generic( const std::function<R(Args...)>& f )
|
||||
std::function<variant(const fc::variants&, uint32_t)> to_generic( const std::function<R(Args...)>& f )
|
||||
{
|
||||
return [=]( const variants& args ) {
|
||||
return variant( call_generic( f, args.begin(), args.end() ) );
|
||||
return [=]( const variants& args, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
return variant( call_generic( f, args.begin(), args.end(), max_depth - 1 ), max_depth - 1 );
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
std::function<variant(const fc::variants&)> to_generic( const std::function<void(Args...)>& f )
|
||||
std::function<variant(const fc::variants&, uint32_t)> to_generic( const std::function<void(Args...)>& f )
|
||||
{
|
||||
return [=]( const variants& args ) {
|
||||
call_generic( f, args.begin(), args.end() );
|
||||
return [=]( const variants& args, uint32_t max_depth ) {
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
call_generic( f, args.begin(), args.end(), max_depth - 1 );
|
||||
return variant();
|
||||
};
|
||||
}
|
||||
|
|
@ -139,31 +141,34 @@ namespace fc {
|
|||
}
|
||||
|
||||
template<typename R>
|
||||
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e )const
|
||||
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 )const
|
||||
{
|
||||
return f();
|
||||
}
|
||||
|
||||
template<typename R, typename Signature, typename ... Args>
|
||||
R call_generic( const std::function<R(std::function<Signature>,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
|
||||
R call_generic( const std::function<R(std::function<Signature>,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( a0 != e, "too few arguments passed to method" );
|
||||
detail::callback_functor<Signature> arg0( get_connection(), a0->as<uint64_t>() );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,std::function<Signature>,Args...>( f, std::function<Signature>(arg0) ), a0+1, e );
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
detail::callback_functor<Signature> arg0( get_connection(), a0->as<uint64_t>(1) );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,std::function<Signature>,Args...>( f, std::function<Signature>(arg0) ), a0+1, e, max_depth - 1 );
|
||||
}
|
||||
template<typename R, typename Signature, typename ... Args>
|
||||
R call_generic( const std::function<R(const std::function<Signature>&,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
|
||||
R call_generic( const std::function<R(const std::function<Signature>&,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( a0 != e, "too few arguments passed to method" );
|
||||
detail::callback_functor<Signature> arg0( get_connection(), a0->as<uint64_t>() );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,const std::function<Signature>&,Args...>( f, arg0 ), a0+1, e );
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
detail::callback_functor<Signature> arg0( get_connection(), a0->as<uint64_t>(1) );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,const std::function<Signature>&,Args...>( f, arg0 ), a0+1, e, max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename R, typename Arg0, typename ... Args>
|
||||
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
|
||||
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( a0 != e, "too few arguments passed to method" );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >() ), a0+1, e );
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >( max_depth - 1 ) ), a0+1, e, max_depth - 1 );
|
||||
}
|
||||
|
||||
struct api_visitor
|
||||
|
|
@ -207,7 +212,7 @@ namespace fc {
|
|||
class api_connection : public std::enable_shared_from_this<fc::api_connection>
|
||||
{
|
||||
public:
|
||||
api_connection(){}
|
||||
api_connection(uint32_t max_depth):_max_conversion_depth(max_depth){}
|
||||
virtual ~api_connection(){};
|
||||
|
||||
|
||||
|
|
@ -232,12 +237,12 @@ namespace fc {
|
|||
variant receive_callback( uint64_t callback_id, const variants& args = variants() )const
|
||||
{
|
||||
FC_ASSERT( _local_callbacks.size() > callback_id );
|
||||
return _local_callbacks[callback_id]( args );
|
||||
return _local_callbacks[callback_id]( args, _max_conversion_depth );
|
||||
}
|
||||
void receive_notice( uint64_t callback_id, const variants& args = variants() )const
|
||||
{
|
||||
FC_ASSERT( _local_callbacks.size() > callback_id );
|
||||
_local_callbacks[callback_id]( args );
|
||||
_local_callbacks[callback_id]( args, _max_conversion_depth );
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
|
|
@ -262,10 +267,11 @@ namespace fc {
|
|||
std::vector<std::string> get_method_names( api_id_type local_api_id = 0 )const { return _local_apis[local_api_id]->get_method_names(); }
|
||||
|
||||
fc::signal<void()> closed;
|
||||
const uint32_t _max_conversion_depth; // for nested structures, json, variant etc.
|
||||
private:
|
||||
std::vector< std::unique_ptr<generic_api> > _local_apis;
|
||||
std::map< uint64_t, api_id_type > _handle_to_id;
|
||||
std::vector< std::function<variant(const variants&)> > _local_callbacks;
|
||||
std::vector< std::unique_ptr<generic_api> > _local_apis;
|
||||
std::map< uint64_t, api_id_type > _handle_to_id;
|
||||
std::vector< std::function<variant(const variants&, uint32_t)> > _local_callbacks;
|
||||
|
||||
|
||||
struct api_visitor
|
||||
|
|
@ -281,15 +287,16 @@ namespace fc {
|
|||
api_visitor() = delete;
|
||||
|
||||
template<typename Result>
|
||||
static Result from_variant( const variant& v, Result*, const std::shared_ptr<fc::api_connection>& )
|
||||
static Result from_variant( const variant& v, Result*, const std::shared_ptr<fc::api_connection>&, uint32_t max_depth )
|
||||
{
|
||||
return v.as<Result>();
|
||||
return v.as<Result>( max_depth );
|
||||
}
|
||||
|
||||
template<typename ResultInterface>
|
||||
static fc::api<ResultInterface> from_variant( const variant& v,
|
||||
fc::api<ResultInterface>* /*used for template deduction*/,
|
||||
const std::shared_ptr<fc::api_connection>& con
|
||||
const std::shared_ptr<fc::api_connection>& con,
|
||||
uint32_t max_depth = 1
|
||||
)
|
||||
{
|
||||
return con->get_remote_api<ResultInterface>( v.as_uint64() );
|
||||
|
|
@ -298,7 +305,8 @@ namespace fc {
|
|||
static fc::api_ptr from_variant(
|
||||
const variant& v,
|
||||
fc::api_ptr* /* used for template deduction */,
|
||||
const std::shared_ptr<fc::api_connection>& con
|
||||
const std::shared_ptr<fc::api_connection>& con,
|
||||
uint32_t max_depth = 1
|
||||
)
|
||||
{
|
||||
if( v.is_null() )
|
||||
|
|
@ -307,9 +315,9 @@ namespace fc {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static fc::variant convert_callbacks( const std::shared_ptr<fc::api_connection>&, const T& v )
|
||||
static fc::variant convert_callbacks( const std::shared_ptr<fc::api_connection>& con, const T& v )
|
||||
{
|
||||
return fc::variant(v);
|
||||
return fc::variant( v, con->_max_conversion_depth );
|
||||
}
|
||||
|
||||
template<typename Signature>
|
||||
|
|
@ -325,7 +333,7 @@ namespace fc {
|
|||
auto api_id = _api_id;
|
||||
memb = [con,api_id,name]( Args... args ) {
|
||||
auto var_result = con->send_call( api_id, name, { convert_callbacks(con,args)...} );
|
||||
return from_variant( var_result, (Result*)nullptr, con );
|
||||
return from_variant( var_result, (Result*)nullptr, con, con->_max_conversion_depth );
|
||||
};
|
||||
}
|
||||
template<typename... Args>
|
||||
|
|
@ -343,6 +351,9 @@ namespace fc {
|
|||
class local_api_connection : public api_connection
|
||||
{
|
||||
public:
|
||||
local_api_connection( uint32_t max_depth ) : api_connection(max_depth){}
|
||||
~local_api_connection(){}
|
||||
|
||||
/** makes calls to the remote server */
|
||||
virtual variant send_call( api_id_type api_id, string method_name, variants args = variants() ) override
|
||||
{
|
||||
|
|
@ -389,7 +400,7 @@ namespace fc {
|
|||
auto con = api_con.lock();
|
||||
FC_ASSERT( con, "not connected" );
|
||||
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end() );
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth );
|
||||
return con->register_api( api_result );
|
||||
};
|
||||
}
|
||||
|
|
@ -403,7 +414,7 @@ namespace fc {
|
|||
auto con = api_con.lock();
|
||||
FC_ASSERT( con, "not connected" );
|
||||
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end() );
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth );
|
||||
if( api_result )
|
||||
return con->register_api( *api_result );
|
||||
return variant();
|
||||
|
|
@ -420,7 +431,7 @@ namespace fc {
|
|||
auto con = api_con.lock();
|
||||
FC_ASSERT( con, "not connected" );
|
||||
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end() );
|
||||
auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth );
|
||||
if( !api_result )
|
||||
return variant();
|
||||
return api_result->register_api( *con );
|
||||
|
|
@ -430,18 +441,24 @@ namespace fc {
|
|||
template<typename R, typename ... Args>
|
||||
std::function<variant(const fc::variants&)> generic_api::api_visitor::to_generic( const std::function<R(Args...)>& f )const
|
||||
{
|
||||
auto con = _api_con.lock();
|
||||
FC_ASSERT( con, "not connected" );
|
||||
uint32_t max_depth = con->_max_conversion_depth;
|
||||
generic_api* gapi = &_api;
|
||||
return [f,gapi]( const variants& args ) {
|
||||
return variant( gapi->call_generic( f, args.begin(), args.end() ) );
|
||||
return [f,gapi,max_depth]( const variants& args ) {
|
||||
return variant( gapi->call_generic( f, args.begin(), args.end(), max_depth ), max_depth );
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
std::function<variant(const fc::variants&)> generic_api::api_visitor::to_generic( const std::function<void(Args...)>& f )const
|
||||
{
|
||||
auto con = _api_con.lock();
|
||||
FC_ASSERT( con, "not connected" );
|
||||
uint32_t max_depth = con->_max_conversion_depth;
|
||||
generic_api* gapi = &_api;
|
||||
return [f,gapi]( const variants& args ) {
|
||||
gapi->call_generic( f, args.begin(), args.end() );
|
||||
return [f,gapi,max_depth]( const variants& args ) {
|
||||
gapi->call_generic( f, args.begin(), args.end(), max_depth );
|
||||
return variant();
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace fc { namespace rpc {
|
|||
class cli : public api_connection
|
||||
{
|
||||
public:
|
||||
cli( uint32_t max_depth ) : api_connection(max_depth) {}
|
||||
~cli();
|
||||
|
||||
virtual variant send_call( api_id_type api_id, string method_name, variants args = variants() );
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace fc { namespace rpc {
|
|||
class http_api_connection : public api_connection
|
||||
{
|
||||
public:
|
||||
http_api_connection();
|
||||
http_api_connection(uint32_t max_conversion_depth);
|
||||
~http_api_connection();
|
||||
|
||||
virtual variant send_call(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace fc { namespace rpc {
|
|||
typedef std::function<variant(const variants&)> method;
|
||||
typedef std::function<variant(const variant_object&)> named_param_method;
|
||||
|
||||
json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out );
|
||||
json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out, uint32_t max_depth );
|
||||
~json_connection();
|
||||
|
||||
/**
|
||||
|
|
@ -304,6 +304,9 @@ namespace fc { namespace rpc {
|
|||
variant call( const fc::string& method, const variant_object& named_args );
|
||||
///@}
|
||||
|
||||
protected:
|
||||
const uint32_t _max_conversion_depth; // for nested structures, json, variant etc.
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::json_connection_impl> my;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace fc { namespace rpc {
|
|||
class websocket_api_connection : public api_connection
|
||||
{
|
||||
public:
|
||||
websocket_api_connection( fc::http::websocket_connection& c );
|
||||
websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_conversion_depth );
|
||||
~websocket_api_connection();
|
||||
|
||||
virtual variant send_call(
|
||||
|
|
|
|||
|
|
@ -344,42 +344,45 @@ struct visitor {
|
|||
struct from_static_variant
|
||||
{
|
||||
variant& var;
|
||||
from_static_variant( variant& dv ):var(dv){}
|
||||
const uint32_t _max_depth;
|
||||
from_static_variant( variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename T> void operator()( const T& v )const
|
||||
{
|
||||
to_variant( v, var );
|
||||
to_variant( v, var, _max_depth );
|
||||
}
|
||||
};
|
||||
|
||||
struct to_static_variant
|
||||
{
|
||||
const variant& var;
|
||||
to_static_variant( const variant& dv ):var(dv){}
|
||||
const uint32_t _max_depth;
|
||||
to_static_variant( const variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename T> void operator()( T& v )const
|
||||
{
|
||||
from_variant( var, v );
|
||||
from_variant( var, v, _max_depth );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename... T> void to_variant( const fc::static_variant<T...>& s, fc::variant& v )
|
||||
template<typename... T> void to_variant( const fc::static_variant<T...>& s, fc::variant& v, uint32_t max_depth )
|
||||
{
|
||||
variant tmp;
|
||||
FC_ASSERT( max_depth > 0 );
|
||||
variants vars(2);
|
||||
vars[0] = s.which();
|
||||
s.visit( from_static_variant(vars[1]) );
|
||||
s.visit( from_static_variant(vars[1], max_depth - 1) );
|
||||
v = std::move(vars);
|
||||
}
|
||||
template<typename... T> void from_variant( const fc::variant& v, fc::static_variant<T...>& s )
|
||||
template<typename... T> void from_variant( const fc::variant& v, fc::static_variant<T...>& s, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( max_depth > 0 );
|
||||
auto ar = v.get_array();
|
||||
if( ar.size() < 2 ) return;
|
||||
s.set_which( ar[0].as_uint64() );
|
||||
s.visit( to_static_variant(ar[1]) );
|
||||
s.visit( to_static_variant(ar[1], max_depth - 1) );
|
||||
}
|
||||
|
||||
template<typename... T> struct get_typename { static const char* name() { return typeid(static_variant<T...>).name(); } };
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace fc
|
|||
|
||||
typedef fc::optional<fc::string> ostring;
|
||||
class variant_object;
|
||||
fc::string format_string( const fc::string&, const variant_object& );
|
||||
fc::string format_string( const fc::string&, const variant_object&, uint32_t max_object_depth = 200 );
|
||||
fc::string trim( const fc::string& );
|
||||
fc::string to_lower( const fc::string& );
|
||||
string trim_and_normalize_spaces( const string& s );
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ namespace fc {
|
|||
inline microseconds days(int64_t d) { return hours(24*d); }
|
||||
|
||||
class variant;
|
||||
void to_variant( const fc::microseconds&, fc::variant& );
|
||||
void from_variant( const fc::variant& , fc::microseconds& );
|
||||
void to_variant( const fc::microseconds&, fc::variant&, uint32_t max_depth = 1 );
|
||||
void from_variant( const fc::variant&, fc::microseconds&, uint32_t max_depth = 1 );
|
||||
|
||||
class time_point {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ namespace fc
|
|||
|
||||
class variant;
|
||||
|
||||
void to_variant( const uint128& var, variant& vo );
|
||||
void from_variant( const variant& var, uint128& vo );
|
||||
void to_variant( const uint128& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, uint128& vo, uint32_t max_depth = 1 );
|
||||
|
||||
namespace raw
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,17 @@
|
|||
#include <fc/smart_ref_fwd.hpp>
|
||||
#include <boost/multi_index_container_fwd.hpp>
|
||||
|
||||
#ifdef FC_ASSERT
|
||||
#define _FC_ASSERT(...) FC_ASSERT( __VA_ARGS__ )
|
||||
#else
|
||||
// poor man's FC_ASSERT, want to avoid recursive inclusion of exception.hpp
|
||||
namespace fc
|
||||
{
|
||||
void throw_assertion_failure( const std::string& message );
|
||||
}
|
||||
#define _FC_ASSERT( cond, msg ) { if( !(cond) ) { fc::throw_assertion_failure( #cond ": " msg ); } }
|
||||
#endif
|
||||
|
||||
namespace fc
|
||||
{
|
||||
/**
|
||||
|
|
@ -27,8 +38,8 @@ namespace fc
|
|||
* for your Serializable_type
|
||||
*
|
||||
* @code
|
||||
* void to_variant( const Serializable_type& e, variant& v );
|
||||
* void from_variant( const variant& e, Serializable_type& ll );
|
||||
* void to_variant( const Serializable_type& e, variant& v, uint32_t max_depth );
|
||||
* void from_variant( const variant& e, Serializable_type& ll, uint32_t max_depth );
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
|
|
@ -44,117 +55,120 @@ namespace fc
|
|||
|
||||
struct blob { std::vector<char> data; };
|
||||
|
||||
void to_variant( const blob& var, variant& vo );
|
||||
void from_variant( const variant& var, blob& vo );
|
||||
void to_variant( const blob& var, variant& vo, uint32_t max_depth = 1);
|
||||
void from_variant( const variant& var, blob& vo, uint32_t max_depth = 1 );
|
||||
|
||||
|
||||
template<typename T, typename... Args> void to_variant( const boost::multi_index_container<T,Args...>& s, variant& v );
|
||||
template<typename T, typename... Args> void from_variant( const variant& v, boost::multi_index_container<T,Args...>& s );
|
||||
template<typename T, typename... Args> void to_variant( const boost::multi_index_container<T,Args...>& s, variant& v, uint32_t max_depth );
|
||||
template<typename T, typename... Args> void from_variant( const variant& v, boost::multi_index_container<T,Args...>& s, uint32_t max_depth );
|
||||
|
||||
template<typename T> void to_variant( const smart_ref<T>& s, variant& v );
|
||||
template<typename T> void from_variant( const variant& v, smart_ref<T>& s );
|
||||
template<typename T> void to_variant( const safe<T>& s, variant& v );
|
||||
template<typename T> void from_variant( const variant& v, safe<T>& s );
|
||||
template<typename T> void to_variant( const std::unique_ptr<T>& s, variant& v );
|
||||
template<typename T> void from_variant( const variant& v, std::unique_ptr<T>& s );
|
||||
template<typename T> void to_variant( const smart_ref<T>& s, variant& v, uint32_t max_depth );
|
||||
template<typename T> void from_variant( const variant& v, smart_ref<T>& s, uint32_t max_depth );
|
||||
template<typename T> void to_variant( const safe<T>& s, variant& v, uint32_t max_depth );
|
||||
template<typename T> void from_variant( const variant& v, safe<T>& s, uint32_t max_depth );
|
||||
template<typename T> void to_variant( const std::unique_ptr<T>& s, variant& v, uint32_t max_depth );
|
||||
template<typename T> void from_variant( const variant& v, std::unique_ptr<T>& s, uint32_t max_depth );
|
||||
|
||||
template<typename... T> void to_variant( const static_variant<T...>& s, variant& v );
|
||||
template<typename... T> void from_variant( const variant& v, static_variant<T...>& s );
|
||||
template<typename... T> void to_variant( const static_variant<T...>& s, variant& v, uint32_t max_depth );
|
||||
template<typename... T> void from_variant( const variant& v, static_variant<T...>& s, uint32_t max_depth );
|
||||
|
||||
void to_variant( const uint8_t& var, variant& vo );
|
||||
void from_variant( const variant& var, uint8_t& vo );
|
||||
void to_variant( const int8_t& var, variant& vo );
|
||||
void from_variant( const variant& var, int8_t& vo );
|
||||
void to_variant( const uint8_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, uint8_t& vo, uint32_t max_depth = 1 );
|
||||
void to_variant( const int8_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, int8_t& vo, uint32_t max_depth = 1 );
|
||||
|
||||
void to_variant( const uint16_t& var, variant& vo );
|
||||
void from_variant( const variant& var, uint16_t& vo );
|
||||
void to_variant( const int16_t& var, variant& vo );
|
||||
void from_variant( const variant& var, int16_t& vo );
|
||||
void to_variant( const uint16_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, uint16_t& vo, uint32_t max_depth = 1 );
|
||||
void to_variant( const int16_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, int16_t& vo, uint32_t max_depth = 1 );
|
||||
|
||||
void to_variant( const uint32_t& var, variant& vo );
|
||||
void from_variant( const variant& var, uint32_t& vo );
|
||||
void to_variant( const int32_t& var, variant& vo );
|
||||
void from_variant( const variant& var, int32_t& vo );
|
||||
void to_variant( const uint32_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, uint32_t& vo, uint32_t max_depth = 1 );
|
||||
void to_variant( const int32_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, int32_t& vo, uint32_t max_depth = 1 );
|
||||
|
||||
void to_variant( const variant_object& var, variant& vo );
|
||||
void from_variant( const variant& var, variant_object& vo );
|
||||
void to_variant( const mutable_variant_object& var, variant& vo );
|
||||
void from_variant( const variant& var, mutable_variant_object& vo );
|
||||
void to_variant( const std::vector<char>& var, variant& vo );
|
||||
void from_variant( const variant& var, std::vector<char>& vo );
|
||||
void to_variant( const uint64_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void to_variant( const int64_t& var, variant& vo, uint32_t max_depth = 1 );
|
||||
|
||||
void to_variant( const variant_object& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, variant_object& vo, uint32_t max_depth );
|
||||
void to_variant( const mutable_variant_object& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, mutable_variant_object& vo, uint32_t max_depth );
|
||||
void to_variant( const std::vector<char>& var, variant& vo, uint32_t max_depth = 1 );
|
||||
void from_variant( const variant& var, std::vector<char>& vo, uint32_t max_depth = 1 );
|
||||
|
||||
template<typename K, typename T>
|
||||
void to_variant( const std::unordered_map<K,T>& var, variant& vo );
|
||||
void to_variant( const std::unordered_map<K,T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename K, typename T>
|
||||
void from_variant( const variant& var, std::unordered_map<K,T>& vo );
|
||||
void from_variant( const variant& var, std::unordered_map<K,T>& vo, uint32_t max_depth );
|
||||
|
||||
template<typename K, typename... T>
|
||||
void to_variant( const fc::flat_map<K,T...>& var, variant& vo );
|
||||
void to_variant( const fc::flat_map<K,T...>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename K, typename T, typename... A>
|
||||
void from_variant(const variant& var, flat_map<K, T, A...>& vo);
|
||||
void from_variant(const variant& var, flat_map<K, T, A...>& vo, uint32_t max_depth );
|
||||
|
||||
template<typename K, typename T, typename C>
|
||||
void to_variant( const std::map<K,T, C>& var, variant& vo );
|
||||
void to_variant( const std::map<K,T, C>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename K, typename T, typename C>
|
||||
void from_variant( const variant& var, std::map<K,T,C>& vo );
|
||||
void from_variant( const variant& var, std::map<K,T,C>& vo, uint32_t max_depth );
|
||||
template<typename K, typename T>
|
||||
void to_variant( const std::multimap<K,T>& var, variant& vo );
|
||||
void to_variant( const std::multimap<K,T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename K, typename T>
|
||||
void from_variant( const variant& var, std::multimap<K,T>& vo );
|
||||
void from_variant( const variant& var, std::multimap<K,T>& vo, uint32_t max_depth );
|
||||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::unordered_set<T>& var, variant& vo );
|
||||
void to_variant( const std::unordered_set<T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::unordered_set<T>& vo );
|
||||
void from_variant( const variant& var, std::unordered_set<T>& vo, uint32_t max_depth );
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::deque<T>& var, variant& vo );
|
||||
void to_variant( const std::deque<T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::deque<T>& vo );
|
||||
void from_variant( const variant& var, std::deque<T>& vo, uint32_t max_depth );
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const fc::flat_set<T>& var, variant& vo );
|
||||
void to_variant( const fc::flat_set<T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, fc::flat_set<T>& vo );
|
||||
void from_variant( const variant& var, fc::flat_set<T>& vo, uint32_t max_depth );
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::set<T>& var, variant& vo );
|
||||
void to_variant( const std::set<T>& var, variant& vo, uint32_t max_depth );
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::set<T>& vo );
|
||||
void from_variant( const variant& var, std::set<T>& vo, uint32_t max_depth );
|
||||
|
||||
void to_variant( const time_point& var, variant& vo );
|
||||
void from_variant( const variant& var, time_point& vo );
|
||||
void to_variant( const time_point& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, time_point& vo, uint32_t max_depth );
|
||||
|
||||
void to_variant( const time_point_sec& var, variant& vo );
|
||||
void from_variant( const variant& var, time_point_sec& vo );
|
||||
void to_variant( const time_point_sec& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, time_point_sec& vo, uint32_t max_depth );
|
||||
|
||||
void to_variant( const microseconds& input_microseconds, variant& output_variant );
|
||||
void from_variant( const variant& input_variant, microseconds& output_microseconds );
|
||||
void to_variant( const microseconds& input_microseconds, variant& output_variant, uint32_t max_depth );
|
||||
void from_variant( const variant& input_variant, microseconds& output_microseconds, uint32_t max_depth );
|
||||
|
||||
#ifdef __APPLE__
|
||||
void to_variant( size_t s, variant& v );
|
||||
void to_variant( size_t s, variant& v, uint32_t max_depth = 1 );
|
||||
#elif defined(_MSC_VER)
|
||||
void to_variant( unsigned long s, variant& v);
|
||||
void to_variant( unsigned long s, variant& v, uint32_t max_depth = 1 );
|
||||
#elif !defined(_MSC_VER)
|
||||
void to_variant( long long int s, variant& v );
|
||||
void to_variant( unsigned long long int s, variant& v );
|
||||
void to_variant( long long int s, variant& v, uint32_t max_depth = 1 );
|
||||
void to_variant( unsigned long long int s, variant& v, uint32_t max_depth = 1 );
|
||||
#endif
|
||||
void to_variant( const std::string& s, variant& v );
|
||||
void to_variant( const std::string& s, variant& v, uint32_t max_depth = 1 );
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::shared_ptr<T>& var, variant& vo );
|
||||
void to_variant( const std::shared_ptr<T>& var, variant& vo, uint32_t max_depth );
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::shared_ptr<T>& vo );
|
||||
void from_variant( const variant& var, std::shared_ptr<T>& vo, uint32_t max_depth );
|
||||
|
||||
typedef std::vector<variant> variants;
|
||||
template<typename A, typename B>
|
||||
void to_variant( const std::pair<A,B>& t, variant& v );
|
||||
void to_variant( const std::pair<A,B>& t, variant& v, uint32_t max_depth );
|
||||
template<typename A, typename B>
|
||||
void from_variant( const variant& v, std::pair<A,B>& p );
|
||||
|
||||
|
||||
void from_variant( const variant& v, std::pair<A,B>& p, uint32_t max_depth );
|
||||
|
||||
/**
|
||||
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
|
||||
|
|
@ -184,31 +198,31 @@ namespace fc
|
|||
/// Constructs a null_type variant
|
||||
variant();
|
||||
/// Constructs a null_type variant
|
||||
variant( nullptr_t );
|
||||
variant( nullptr_t, uint32_t max_depth = 1 );
|
||||
|
||||
/// @param str - UTF8 string
|
||||
variant( const char* str );
|
||||
variant( char* str );
|
||||
variant( wchar_t* str );
|
||||
variant( const wchar_t* str );
|
||||
variant( float val );
|
||||
variant( uint8_t val );
|
||||
variant( int8_t val );
|
||||
variant( uint16_t val );
|
||||
variant( int16_t val );
|
||||
variant( uint32_t val );
|
||||
variant( int32_t val );
|
||||
variant( uint64_t val );
|
||||
variant( int64_t val );
|
||||
variant( double val );
|
||||
variant( bool val );
|
||||
variant( blob val );
|
||||
variant( fc::string val );
|
||||
variant( variant_object );
|
||||
variant( mutable_variant_object );
|
||||
variant( variants );
|
||||
variant( const variant& );
|
||||
variant( variant&& );
|
||||
variant( const char* str, uint32_t max_depth = 1 );
|
||||
variant( char* str, uint32_t max_depth = 1 );
|
||||
variant( wchar_t* str, uint32_t max_depth = 1 );
|
||||
variant( const wchar_t* str, uint32_t max_depth = 1 );
|
||||
variant( float val, uint32_t max_depth = 1 );
|
||||
variant( uint8_t val, uint32_t max_depth = 1 );
|
||||
variant( int8_t val, uint32_t max_depth = 1 );
|
||||
variant( uint16_t val, uint32_t max_depth = 1 );
|
||||
variant( int16_t val, uint32_t max_depth = 1 );
|
||||
variant( uint32_t val, uint32_t max_depth = 1 );
|
||||
variant( int32_t val, uint32_t max_depth = 1 );
|
||||
variant( uint64_t val, uint32_t max_depth = 1 );
|
||||
variant( int64_t val, uint32_t max_depth = 1 );
|
||||
variant( double val, uint32_t max_depth = 1 );
|
||||
variant( bool val, uint32_t max_depth = 1 );
|
||||
variant( blob val, uint32_t max_depth = 1 );
|
||||
variant( fc::string val, uint32_t max_depth = 1 );
|
||||
variant( variant_object, uint32_t max_depth = 1 );
|
||||
variant( mutable_variant_object, uint32_t max_depth = 1 );
|
||||
variant( variants, uint32_t max_depth = 1 );
|
||||
variant( const variant&, uint32_t max_depth = 1 );
|
||||
variant( variant&&, uint32_t max_depth = 1 );
|
||||
~variant();
|
||||
|
||||
/**
|
||||
|
|
@ -292,7 +306,7 @@ namespace fc
|
|||
* following method to implement conversion from variant to T.
|
||||
*
|
||||
* <code>
|
||||
* void from_variant( const Variant& var, T& val )
|
||||
* void from_variant( const Variant& var, T& val, uint32_t max_depth )
|
||||
* </code>
|
||||
*
|
||||
* The above form is not always convienant, so the this templated
|
||||
|
|
@ -300,17 +314,17 @@ namespace fc
|
|||
* types.
|
||||
*/
|
||||
template<typename T>
|
||||
T as()const
|
||||
T as( uint32_t max_depth )const
|
||||
{
|
||||
T tmp;
|
||||
from_variant( *this, tmp );
|
||||
from_variant( *this, tmp, max_depth );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void as( T& v )const
|
||||
void as( T& v, uint32_t max_depth )const
|
||||
{
|
||||
from_variant( *this, v );
|
||||
from_variant( *this, v, max_depth );
|
||||
}
|
||||
|
||||
variant& operator=( variant&& v );
|
||||
|
|
@ -323,14 +337,15 @@ namespace fc
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
variant( const optional<T>& v )
|
||||
variant( const optional<T>& v, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
memset( this, 0, sizeof(*this) );
|
||||
if( v.valid() ) *this = variant(*v);
|
||||
if( v.valid() ) *this = variant( *v, max_depth - 1 );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
explicit variant( const T& val );
|
||||
variant( const T& val, uint32_t max_depth );
|
||||
|
||||
|
||||
void clear();
|
||||
|
|
@ -342,200 +357,213 @@ namespace fc
|
|||
typedef optional<variant> ovariant;
|
||||
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, string& vo );
|
||||
void from_variant( const variant& var, string& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, variants& vo );
|
||||
void from_variant( const variant& var, variant& vo );
|
||||
void from_variant( const variant& var, variants& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, variant& vo, uint32_t max_depth );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, int64_t& vo );
|
||||
void from_variant( const variant& var, int64_t& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, uint64_t& vo );
|
||||
void from_variant( const variant& var, uint64_t& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, bool& vo );
|
||||
void from_variant( const variant& var, bool& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, double& vo );
|
||||
void from_variant( const variant& var, double& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, float& vo );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, int32_t& vo );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, uint32_t& vo );
|
||||
void from_variant( const variant& var, float& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, optional<T>& vo )
|
||||
void from_variant( const variant& var, optional<T>& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var.is_null() ) vo = optional<T>();
|
||||
else
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
vo = T();
|
||||
from_variant( var, *vo );
|
||||
from_variant( var, *vo, max_depth - 1 );
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
void to_variant( const std::unordered_set<T>& var, variant& vo )
|
||||
void to_variant( const std::unordered_set<T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = variant(*itr);
|
||||
for( const auto& item : var )
|
||||
vars[i++] = variant( item, max_depth - 1 );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::unordered_set<T>& vo )
|
||||
void from_variant( const variant& var, std::unordered_set<T>& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
vo.reserve( vars.size() );
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as<T>() );
|
||||
for( const auto& item : vars )
|
||||
vo.insert( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
|
||||
template<typename K, typename T>
|
||||
void to_variant( const std::unordered_map<K, T>& var, variant& vo )
|
||||
void to_variant( const std::unordered_map<K, T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = fc::variant(*itr);
|
||||
vo = vars;
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( const auto& key_value : var )
|
||||
vars[i++] = fc::variant( key_value, max_depth - 1 );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename K, typename T>
|
||||
void from_variant( const variant& var, std::unordered_map<K, T>& vo )
|
||||
void from_variant( const variant& var, std::unordered_map<K, T>& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as< std::pair<K,T> >() );
|
||||
|
||||
vo.reserve( vars.size() );
|
||||
for( const auto& item : vars )
|
||||
vo.insert( item.as< std::pair<K,T> >( max_depth - 1 ) );
|
||||
}
|
||||
template<typename K, typename T, typename C>
|
||||
void to_variant( const std::map<K, T, C>& var, variant& vo )
|
||||
void to_variant( const std::map<K, T, C>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = fc::variant(*itr);
|
||||
vo = vars;
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( const auto& key_value : var )
|
||||
vars[i++] = fc::variant( key_value, max_depth - 1 );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename K, typename T, typename C>
|
||||
void from_variant( const variant& var, std::map<K, T, C>& vo )
|
||||
void from_variant( const variant& var, std::map<K, T, C>& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as< std::pair<K,T> >() );
|
||||
for( auto item : vars )
|
||||
vo.insert( item.as< std::pair<K,T> >( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
template<typename K, typename T>
|
||||
void to_variant( const std::multimap<K, T>& var, variant& vo )
|
||||
void to_variant( const std::multimap<K, T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = fc::variant(*itr);
|
||||
vo = vars;
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector< variant > vars(var.size());
|
||||
size_t i = 0;
|
||||
for( const auto& key_value : var )
|
||||
vars[i++] = fc::variant( key_value, max_depth - 1 );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename K, typename T>
|
||||
void from_variant( const variant& var, std::multimap<K, T>& vo )
|
||||
void from_variant( const variant& var, std::multimap<K, T>& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as< std::pair<K,T> >() );
|
||||
for( auto item : vars )
|
||||
vo.insert( item.as< std::pair<K,T> >( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::set<T>& var, variant& vo )
|
||||
void to_variant( const std::set<T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
std::vector<variant> vars(var.size());
|
||||
size_t i = 0;
|
||||
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
|
||||
vars[i] = variant(*itr);
|
||||
vo = vars;
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars(var.size());
|
||||
size_t i = 0;
|
||||
for( const auto& item : var )
|
||||
vars[i++] = fc::variant( item, max_depth - 1 );
|
||||
vo = vars;
|
||||
}
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::set<T>& vo )
|
||||
void from_variant( const variant& var, std::set<T>& vo, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
vo.clear();
|
||||
//vo.reserve( vars.size() );
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
vo.insert( itr->as<T>() );
|
||||
for( const auto& item : vars )
|
||||
vo.insert( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
/** @ingroup Serializable */
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::deque<T>& tmp )
|
||||
void from_variant( const variant& var, std::deque<T>& dest, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
tmp.clear();
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
tmp.push_back( itr->as<T>() );
|
||||
dest.clear();
|
||||
dest.resize( vars.size() );
|
||||
for( const auto& item : vars )
|
||||
dest.push_back( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
/** @ingroup Serializable */
|
||||
template<typename T>
|
||||
void to_variant( const std::deque<T>& t, variant& v )
|
||||
void to_variant( const std::deque<T>& src, variant& v, uint32_t max_depth )
|
||||
{
|
||||
std::vector<variant> vars(t.size());
|
||||
for( size_t i = 0; i < t.size(); ++i )
|
||||
vars[i] = variant(t[i]);
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars(src.size());
|
||||
for( size_t i = 0; i < src.size(); ++i )
|
||||
vars[i] = variant( src[i], max_depth - 1 );
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
|
||||
/** @ingroup Serializable */
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::vector<T>& tmp )
|
||||
void from_variant( const variant& var, std::vector<T>& dest, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = var.get_array();
|
||||
tmp.clear();
|
||||
tmp.reserve( vars.size() );
|
||||
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||
tmp.push_back( itr->as<T>() );
|
||||
dest.clear();
|
||||
dest.reserve( vars.size() );
|
||||
for( const auto& item : vars )
|
||||
dest.push_back( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
/** @ingroup Serializable */
|
||||
template<typename T>
|
||||
void to_variant( const std::vector<T>& t, variant& v )
|
||||
void to_variant( const std::vector<T>& t, variant& v, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars(t.size());
|
||||
for( size_t i = 0; i < t.size(); ++i )
|
||||
vars[i] = variant(t[i]);
|
||||
v = std::move(vars);
|
||||
for( size_t i = 0; i < t.size(); ++i )
|
||||
vars[i] = variant( t[i], max_depth - 1 );
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
|
||||
/** @ingroup Serializable */
|
||||
template<typename A, typename B>
|
||||
void to_variant( const std::pair<A,B>& t, variant& v )
|
||||
void to_variant( const std::pair<A,B>& t, variant& v, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars(2);
|
||||
vars[0] = variant(t.first);
|
||||
vars[1] = variant(t.second);
|
||||
v = vars;
|
||||
vars[0] = variant( t.first, max_depth - 1 );
|
||||
vars[1] = variant( t.second, max_depth - 1 );
|
||||
v = vars;
|
||||
}
|
||||
template<typename A, typename B>
|
||||
void from_variant( const variant& v, std::pair<A,B>& p )
|
||||
void from_variant( const variant& v, std::pair<A,B>& p, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = v.get_array();
|
||||
if( vars.size() > 0 )
|
||||
p.first = vars[0].as<A>();
|
||||
p.first = vars[0].as<A>( max_depth - 1 );
|
||||
if( vars.size() > 1 )
|
||||
p.second = vars[1].as<B>();
|
||||
p.second = vars[1].as<B>( max_depth - 1 );
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
variant::variant( const T& val )
|
||||
variant::variant( const T& val, uint32_t max_depth )
|
||||
{
|
||||
memset( this, 0, sizeof(*this) );
|
||||
to_variant( val, *this );
|
||||
to_variant( val, *this, max_depth );
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
inline void to_variant( size_t s, variant& v ) { v = variant(uint64_t(s)); }
|
||||
inline void to_variant( size_t s, variant& v, uint32_t max_depth = 1 ) { v = variant(uint64_t(s)); }
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
@ -543,68 +571,90 @@ namespace fc
|
|||
#endif
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const std::shared_ptr<T>& var, variant& vo )
|
||||
void to_variant( const std::shared_ptr<T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var ) to_variant( *var, vo );
|
||||
if( var )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
to_variant( *var, vo, max_depth - 1 );
|
||||
}
|
||||
else vo = nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::shared_ptr<T>& vo )
|
||||
void from_variant( const variant& var, std::shared_ptr<T>& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var.is_null() ) vo = nullptr;
|
||||
else if( vo ) from_variant( var, *vo );
|
||||
else {
|
||||
vo = std::make_shared<T>();
|
||||
from_variant( var, *vo );
|
||||
else
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
if( !vo ) vo = std::make_shared<T>();
|
||||
from_variant( var, *vo, max_depth - 1 );
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
void to_variant( const std::unique_ptr<T>& var, variant& vo )
|
||||
void to_variant( const std::unique_ptr<T>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var ) to_variant( *var, vo );
|
||||
if( var )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
to_variant( *var, vo, max_depth - 1 );
|
||||
}
|
||||
else vo = nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& var, std::unique_ptr<T>& vo )
|
||||
void from_variant( const variant& var, std::unique_ptr<T>& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var.is_null() ) vo.reset();
|
||||
else if( vo ) from_variant( var, *vo );
|
||||
else {
|
||||
vo.reset( new T() );
|
||||
from_variant( var, *vo );
|
||||
else
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
if( !vo ) vo.reset( new T() );
|
||||
from_variant( var, *vo, max_depth - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const safe<T>& s, variant& v ) { v = s.value; }
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, safe<T>& s ) { s.value = v.as_uint64(); }
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const smart_ref<T>& s, variant& v ) { v = *s; }
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, smart_ref<T>& s ) { from_variant( v, *s ); }
|
||||
|
||||
template<typename T, typename... Args> void to_variant( const boost::multi_index_container<T,Args...>& c, variant& v )
|
||||
{
|
||||
std::vector<variant> vars;
|
||||
vars.reserve( c.size() );
|
||||
for( const auto& item : c )
|
||||
vars.emplace_back( variant(item) );
|
||||
v = std::move(vars);
|
||||
void to_variant( const safe<T>& s, variant& v, uint32_t max_depth ) {
|
||||
to_variant( s.value, v, max_depth );
|
||||
}
|
||||
|
||||
template<typename T, typename... Args> void from_variant( const variant& v, boost::multi_index_container<T,Args...>& c )
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, safe<T>& s, uint32_t max_depth ) {
|
||||
s.value = v.as<T>( max_depth );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const smart_ref<T>& s, variant& v, uint32_t max_depth ) {
|
||||
to_variant( *s, v, max_depth );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, smart_ref<T>& s, uint32_t max_depth ) {
|
||||
from_variant( v, *s, max_depth );
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void to_variant( const boost::multi_index_container<T,Args...>& c, variant& v, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
std::vector<variant> vars;
|
||||
vars.reserve( c.size() );
|
||||
for( const auto& item : c )
|
||||
vars.emplace_back( variant( item, max_depth - 1 ) );
|
||||
v = std::move(vars);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void from_variant( const variant& v, boost::multi_index_container<T,Args...>& c, uint32_t max_depth )
|
||||
{
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
const variants& vars = v.get_array();
|
||||
c.clear();
|
||||
for( const auto& item : vars )
|
||||
c.insert( item.as<T>() );
|
||||
c.insert( item.as<T>( max_depth - 1 ) );
|
||||
}
|
||||
|
||||
variant operator + ( const variant& a, const variant& b );
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ namespace fc
|
|||
friend class mutable_variant_object;
|
||||
};
|
||||
/** @ingroup Serializable */
|
||||
void to_variant( const variant_object& var, variant& vo );
|
||||
void to_variant( const variant_object& var, variant& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, variant_object& vo );
|
||||
void from_variant( const variant& var, variant_object& vo, uint32_t max_depth = 1 );
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -169,11 +169,12 @@ namespace fc
|
|||
*
|
||||
* @return *this;
|
||||
*/
|
||||
mutable_variant_object& operator()( string key, variant var );
|
||||
mutable_variant_object& operator()( string key, variant var, uint32_t max_depth = 1 );
|
||||
template<typename T>
|
||||
mutable_variant_object& operator()( string key, T&& var )
|
||||
mutable_variant_object& operator()( string key, T&& var, uint32_t max_depth )
|
||||
{
|
||||
set(std::move(key), variant( fc::forward<T>(var) ) );
|
||||
_FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
set( std::move(key), variant( fc::forward<T>(var), max_depth - 1 ) );
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
|
|
@ -216,9 +217,27 @@ namespace fc
|
|||
std::unique_ptr< std::vector< entry > > _key_value;
|
||||
friend class variant_object;
|
||||
};
|
||||
|
||||
class limited_mutable_variant_object : public mutable_variant_object
|
||||
{
|
||||
public:
|
||||
limited_mutable_variant_object( uint32_t max_depth );
|
||||
|
||||
template<typename T>
|
||||
limited_mutable_variant_object& operator()( string key, T&& var )
|
||||
{
|
||||
set( std::move(key), variant( fc::forward<T>(var), _max_depth ) );
|
||||
return *this;
|
||||
}
|
||||
limited_mutable_variant_object& operator()( const variant_object& vo );
|
||||
|
||||
private:
|
||||
const uint32_t _max_depth;
|
||||
};
|
||||
|
||||
/** @ingroup Serializable */
|
||||
void to_variant( const mutable_variant_object& var, variant& vo );
|
||||
void to_variant( const mutable_variant_object& var, variant& vo, uint32_t max_depth = 1 );
|
||||
/** @ingroup Serializable */
|
||||
void from_variant( const variant& var, mutable_variant_object& vo );
|
||||
void from_variant( const variant& var, mutable_variant_object& vo, uint32_t max_depth = 1 );
|
||||
|
||||
} // namespace fc
|
||||
|
|
|
|||
|
|
@ -128,14 +128,14 @@ namespace fc {
|
|||
}
|
||||
bigint bigint::operator / ( const bigint& a ) const {
|
||||
BN_CTX* ctx = BN_CTX_new();
|
||||
bigint tmp;//(*this);
|
||||
bigint tmp;
|
||||
BN_div( tmp.n, NULL, n, a.n, ctx );
|
||||
BN_CTX_free(ctx);
|
||||
return tmp;
|
||||
}
|
||||
bigint bigint::operator % ( const bigint& a ) const {
|
||||
BN_CTX* ctx = BN_CTX_new();
|
||||
bigint tmp;//(*this);
|
||||
bigint tmp;
|
||||
BN_mod( tmp.n, n, a.n, ctx );
|
||||
BN_CTX_free(ctx);
|
||||
return tmp;
|
||||
|
|
@ -143,7 +143,7 @@ namespace fc {
|
|||
|
||||
bigint bigint::operator /= ( const bigint& a ) {
|
||||
BN_CTX* ctx = BN_CTX_new();
|
||||
bigint tmp;//*this);
|
||||
bigint tmp;
|
||||
BN_div( tmp.n, NULL, n, a.n, ctx );
|
||||
fc_swap( tmp.n, n );
|
||||
BN_CTX_free(ctx);
|
||||
|
|
@ -188,6 +188,8 @@ namespace fc {
|
|||
|
||||
|
||||
bigint& bigint::operator = ( bigint&& a ) {
|
||||
if( &a == this )
|
||||
return *this;
|
||||
fc_swap( a.n, n );
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -208,14 +210,14 @@ namespace fc {
|
|||
}
|
||||
|
||||
/** encodes the big int as base64 string, or a number */
|
||||
void to_variant( const bigint& bi, variant& v )
|
||||
void to_variant( const bigint& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = bi;
|
||||
v = fc::variant(base64_encode((unsigned char*)ve.data(),ve.size()));
|
||||
}
|
||||
|
||||
/** decodes the big int as base64 string, or a number */
|
||||
void from_variant( const variant& v, bigint& bi )
|
||||
void from_variant( const variant& v, bigint& bi, uint32_t max_depth )
|
||||
{
|
||||
if( v.is_numeric() ) bi = bigint( static_cast<unsigned long>(v.as_uint64()) );
|
||||
else
|
||||
|
|
|
|||
|
|
@ -381,27 +381,27 @@ namespace fc { namespace ecc {
|
|||
}
|
||||
}
|
||||
|
||||
void to_variant( const ecc::private_key& var, variant& vo )
|
||||
void to_variant( const ecc::private_key& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.get_secret();
|
||||
to_variant( var.get_secret(), vo, max_depth );
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, ecc::private_key& vo )
|
||||
void from_variant( const variant& var, ecc::private_key& vo, uint32_t max_depth )
|
||||
{
|
||||
fc::sha256 sec;
|
||||
from_variant( var, sec );
|
||||
from_variant( var, sec, max_depth );
|
||||
vo = ecc::private_key::regenerate(sec);
|
||||
}
|
||||
|
||||
void to_variant( const ecc::public_key& var, variant& vo )
|
||||
void to_variant( const ecc::public_key& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.serialize();
|
||||
to_variant( var.serialize(), vo, max_depth );
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, ecc::public_key& vo )
|
||||
void from_variant( const variant& var, ecc::public_key& vo, uint32_t max_depth )
|
||||
{
|
||||
ecc::public_key_data dat;
|
||||
from_variant( var, dat );
|
||||
from_variant( var, dat, max_depth );
|
||||
vo = ecc::public_key(dat);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,28 +338,28 @@ namespace fc {
|
|||
}
|
||||
|
||||
/** encodes the big int as base64 string, or a number */
|
||||
void to_variant( const public_key& bi, variant& v )
|
||||
void to_variant( const public_key& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = bi.serialize();
|
||||
}
|
||||
|
||||
/** decodes the big int as base64 string, or a number */
|
||||
void from_variant( const variant& v, public_key& bi )
|
||||
void from_variant( const variant& v, public_key& bi, uint32_t max_depth )
|
||||
{
|
||||
bi = public_key( v.as<std::vector<char> >() );
|
||||
bi = public_key( v.as<std::vector<char> >(max_depth) );
|
||||
}
|
||||
|
||||
|
||||
/** encodes the big int as base64 string, or a number */
|
||||
void to_variant( const private_key& bi, variant& v )
|
||||
void to_variant( const private_key& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = bi.serialize();
|
||||
}
|
||||
|
||||
/** decodes the big int as base64 string, or a number */
|
||||
void from_variant( const variant& v, private_key& bi )
|
||||
void from_variant( const variant& v, private_key& bi, uint32_t max_depth )
|
||||
{
|
||||
bi = private_key( v.as<std::vector<char> >() );
|
||||
bi = private_key( v.as<std::vector<char> >(max_depth) );
|
||||
}
|
||||
|
||||
} // fc
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ ripemd160::operator string()const { return str(); }
|
|||
char* ripemd160::data()const { return (char*)&_hash[0]; }
|
||||
|
||||
|
||||
struct ripemd160::encoder::impl {
|
||||
class ripemd160::encoder::impl {
|
||||
public:
|
||||
impl()
|
||||
{
|
||||
memset( (char*)&ctx, 0, sizeof(ctx) );
|
||||
|
|
@ -98,19 +99,16 @@ bool operator == ( const ripemd160& h1, const ripemd160& h2 ) {
|
|||
return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0;
|
||||
}
|
||||
|
||||
void to_variant( const ripemd160& bi, variant& v )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
}
|
||||
void from_variant( const variant& v, ripemd160& bi )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
void to_variant( const ripemd160& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
}
|
||||
void from_variant( const variant& v, ripemd160& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
} // fc
|
||||
|
|
|
|||
|
|
@ -83,19 +83,16 @@ bool operator == ( const sha1& h1, const sha1& h2 ) {
|
|||
return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0;
|
||||
}
|
||||
|
||||
void to_variant( const sha1& bi, variant& v )
|
||||
void to_variant( const sha1& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
}
|
||||
void from_variant( const variant& v, sha1& bi )
|
||||
void from_variant( const variant& v, sha1& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
} // fc
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace fc {
|
|||
sha224 operator ^ ( const sha224& h1, const sha224& h2 ) {
|
||||
sha224 result;
|
||||
for( uint32_t i = 0; i < 7; ++i )
|
||||
result._hash[i] = h1._hash[i] ^ h2._hash[i];
|
||||
result._hash[i] = h1._hash[i] ^ h2._hash[i];
|
||||
return result;
|
||||
}
|
||||
bool operator >= ( const sha224& h1, const sha224& h2 ) {
|
||||
|
|
@ -79,19 +79,16 @@ namespace fc {
|
|||
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) == 0;
|
||||
}
|
||||
|
||||
void to_variant( const sha224& bi, variant& v )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
}
|
||||
void from_variant( const variant& v, sha224& bi )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
void to_variant( const sha224& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
}
|
||||
void from_variant( const variant& v, sha224& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ namespace fc {
|
|||
}
|
||||
else
|
||||
(*this) = (*this) << (nzbits - 0x18);
|
||||
return;
|
||||
}
|
||||
|
||||
double sha256::inverse_approx_log_32_double( uint32_t x )
|
||||
|
|
@ -194,19 +193,16 @@ namespace fc {
|
|||
return lzbits;
|
||||
}
|
||||
|
||||
void to_variant( const sha256& bi, variant& v )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
}
|
||||
void from_variant( const variant& v, sha256& bi )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
void to_variant( const sha256& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
}
|
||||
void from_variant( const variant& v, sha256& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
uint64_t hash64(const char* buf, size_t len)
|
||||
|
|
|
|||
|
|
@ -85,19 +85,16 @@ namespace fc {
|
|||
return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0;
|
||||
}
|
||||
|
||||
void to_variant( const sha512& bi, variant& v )
|
||||
{
|
||||
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
||||
}
|
||||
void from_variant( const variant& v, sha512& bi )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >();
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
void to_variant( const sha512& bi, variant& v, uint32_t max_depth )
|
||||
{
|
||||
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
|
||||
}
|
||||
void from_variant( const variant& v, sha512& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -123,19 +123,25 @@ namespace fc
|
|||
|
||||
exception::~exception(){}
|
||||
|
||||
void to_variant( const exception& e, variant& v )
|
||||
void to_variant( const exception& e, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = mutable_variant_object( "code", e.code() )
|
||||
( "name", e.name() )
|
||||
( "message", e.what() )
|
||||
( "stack", e.get_log() );
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
variant v_log;
|
||||
to_variant( e.get_log(), v_log, max_depth - 1 );
|
||||
mutable_variant_object tmp;
|
||||
tmp( "code", e.code() )
|
||||
( "name", e.name() )
|
||||
( "message", e.what() )
|
||||
( "stack", v_log );
|
||||
v = variant( tmp, max_depth );
|
||||
|
||||
}
|
||||
void from_variant( const variant& v, exception& ll )
|
||||
void from_variant( const variant& v, exception& ll, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
|
||||
auto obj = v.get_object();
|
||||
if( obj.contains( "stack" ) )
|
||||
ll.my->_elog = obj["stack"].as<log_messages>();
|
||||
ll.my->_elog = obj["stack"].as<log_messages>( max_depth - 1 );
|
||||
if( obj.contains( "code" ) )
|
||||
ll.my->_code = obj["code"].as_int64();
|
||||
if( obj.contains( "name" ) )
|
||||
|
|
@ -161,7 +167,7 @@ namespace fc
|
|||
ss << variant(my->_code).as_string() <<" " << my->_name << ": " <<my->_what<<"\n";
|
||||
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); )
|
||||
{
|
||||
ss << itr->get_message() <<"\n"; //fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
|
||||
ss << itr->get_message() <<"\n";
|
||||
try
|
||||
{
|
||||
ss << " " << json::to_string( itr->get_data() )<<"\n";
|
||||
|
|
@ -188,7 +194,6 @@ namespace fc
|
|||
{
|
||||
if( itr->get_format().size() )
|
||||
ss << " " << fc::format_string( itr->get_format(), itr->get_data() );
|
||||
// ss << " " << itr->get_context().to_string() <<"\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
|
@ -251,6 +256,11 @@ namespace fc
|
|||
return *this;
|
||||
}
|
||||
|
||||
void throw_assertion_failure( const std::string& message )
|
||||
{
|
||||
FC_THROW_EXCEPTION( fc::assert_exception, message );
|
||||
}
|
||||
|
||||
void record_assert_trip(
|
||||
const char* filename,
|
||||
uint32_t lineno,
|
||||
|
|
|
|||
|
|
@ -27,19 +27,15 @@
|
|||
|
||||
namespace fc {
|
||||
// when converting to and from a variant, store utf-8 in the variant
|
||||
void to_variant( const fc::path& path_to_convert, variant& variant_output )
|
||||
void to_variant( const fc::path& path_to_convert, variant& variant_output, uint32_t max_depth )
|
||||
{
|
||||
std::wstring wide_string = path_to_convert.generic_wstring();
|
||||
std::string utf8_string;
|
||||
fc::encodeUtf8(wide_string, &utf8_string);
|
||||
variant_output = utf8_string;
|
||||
|
||||
//std::string path = t.to_native_ansi_path();
|
||||
//std::replace(path.begin(), path.end(), '\\', '/');
|
||||
//v = path;
|
||||
}
|
||||
|
||||
void from_variant( const fc::variant& variant_to_convert, fc::path& path_output )
|
||||
void from_variant( const fc::variant& variant_to_convert, fc::path& path_output, uint32_t max_depth )
|
||||
{
|
||||
std::wstring wide_string;
|
||||
fc::decodeUtf8(variant_to_convert.as_string(), &wide_string);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
namespace fc
|
||||
{
|
||||
void to_variant( const signed_int& var, variant& vo ) { vo = var.value; }
|
||||
void from_variant( const variant& var, signed_int& vo ) { vo.value = static_cast<int32_t>(var.as_int64()); }
|
||||
void to_variant( const unsigned_int& var, variant& vo ) { vo = var.value; }
|
||||
void from_variant( const variant& var, unsigned_int& vo ) { vo.value = static_cast<uint32_t>(var.as_uint64()); }
|
||||
void to_variant( const signed_int& var, variant& vo, uint32_t max_depth ) { vo = var.value; }
|
||||
void from_variant( const variant& var, signed_int& vo, uint32_t max_depth ) { vo.value = static_cast<int32_t>(var.as_int64()); }
|
||||
void to_variant( const unsigned_int& var, variant& vo, uint32_t max_depth ) { vo = var.value; }
|
||||
void from_variant( const variant& var, unsigned_int& vo, uint32_t max_depth ) { vo.value = static_cast<uint32_t>(var.as_uint64()); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace fc {
|
|||
console_appender::console_appender( const variant& args )
|
||||
:my(new impl)
|
||||
{
|
||||
configure( args.as<config>() );
|
||||
configure( args.as<config>( FC_MAX_LOG_OBJECT_DEPTH ) );
|
||||
}
|
||||
|
||||
console_appender::console_appender( const config& cfg )
|
||||
|
|
@ -89,12 +89,9 @@ namespace fc {
|
|||
}
|
||||
|
||||
void console_appender::log( const log_message& m ) {
|
||||
//fc::string message = fc::format_string( m.get_format(), m.get_data() );
|
||||
//fc::variant lmsg(m);
|
||||
|
||||
FILE* out = stream::std_error ? stderr : stdout;
|
||||
|
||||
//fc::string fmt_str = fc::format_string( cfg.format, mutable_variant_object(m.get_context())( "message", message) );
|
||||
std::stringstream file_line;
|
||||
file_line << m.get_context().get_file() <<":"<<m.get_context().get_line_number() <<" ";
|
||||
|
||||
|
|
@ -117,8 +114,8 @@ namespace fc {
|
|||
line << std::setw( 20 ) << std::left << m.get_context().get_method().substr(p,20).c_str() <<" ";
|
||||
}
|
||||
line << "] ";
|
||||
fc::string message = fc::format_string( m.get_format(), m.get_data() );
|
||||
line << message;//.c_str();
|
||||
fc::string message = fc::format_string( m.get_format(), m.get_data(), my->cfg.max_object_depth );
|
||||
line << message;
|
||||
|
||||
fc::unique_lock<boost::mutex> lock(log_mutex());
|
||||
|
||||
|
|
@ -141,7 +138,7 @@ namespace fc {
|
|||
#endif
|
||||
|
||||
if( text.size() )
|
||||
fprintf( out, "%s", text.c_str() ); //fmt_str.c_str() );
|
||||
fprintf( out, "%s", text.c_str() );
|
||||
|
||||
#ifdef WIN32
|
||||
if (my->console_handle != INVALID_HANDLE_VALUE)
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ namespace fc {
|
|||
{}
|
||||
|
||||
file_appender::file_appender( const variant& args ) :
|
||||
my( new impl( args.as<config>() ) )
|
||||
my( new impl( args.as<config>( FC_MAX_LOG_OBJECT_DEPTH ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -221,13 +221,9 @@ namespace fc {
|
|||
}
|
||||
|
||||
line << "] ";
|
||||
fc::string message = fc::format_string( m.get_format(), m.get_data() );
|
||||
fc::string message = fc::format_string( m.get_format(), m.get_data(), my->cfg.max_object_depth );
|
||||
line << message.c_str();
|
||||
|
||||
//fc::variant lmsg(m);
|
||||
|
||||
// fc::string fmt_str = fc::format_string( my->cfg.format, mutable_variant_object(m.get_context())( "message", message) );
|
||||
|
||||
{
|
||||
fc::scoped_lock<boost::mutex> lock( my->slock );
|
||||
my->out << line.str() << "\t\t\t" << m.get_context().get_file() << ":" << m.get_context().get_line_number() << "\n";
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace fc
|
|||
};
|
||||
|
||||
gelf_appender::gelf_appender(const variant& args) :
|
||||
my(new impl(args.as<config>()))
|
||||
my( new impl( args.as<config>( FC_MAX_LOG_OBJECT_DEPTH ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -94,7 +94,7 @@ namespace fc
|
|||
mutable_variant_object gelf_message;
|
||||
gelf_message["version"] = "1.1";
|
||||
gelf_message["host"] = my->cfg.host;
|
||||
gelf_message["short_message"] = format_string(message.get_format(), message.get_data());
|
||||
gelf_message["short_message"] = format_string( message.get_format(), message.get_data(), my->cfg.max_object_depth );
|
||||
|
||||
gelf_message["timestamp"] = context.get_timestamp().time_since_epoch().count() / 1000000.;
|
||||
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ namespace fc
|
|||
my->task_name = current_task_desc ? current_task_desc : "?unnamed?";
|
||||
}
|
||||
|
||||
log_context::log_context( const variant& v )
|
||||
log_context::log_context( const variant& v, uint32_t max_depth )
|
||||
:my( std::make_shared<detail::log_context_impl>() )
|
||||
{
|
||||
auto obj = v.get_object();
|
||||
my->level = obj["level"].as<log_level>();
|
||||
my->level = obj["level"].as<log_level>(max_depth);
|
||||
my->file = obj["file"].as_string();
|
||||
my->line = obj["line"].as_uint64();
|
||||
my->method = obj["method"].as_string();
|
||||
|
|
@ -70,9 +70,9 @@ namespace fc
|
|||
my->thread_name = obj["thread_name"].as_string();
|
||||
if (obj.contains("task_name"))
|
||||
my->task_name = obj["task_name"].as_string();
|
||||
my->timestamp = obj["timestamp"].as<time_point>();
|
||||
my->timestamp = obj["timestamp"].as<time_point>(max_depth);
|
||||
if( obj.contains( "context" ) )
|
||||
my->context = obj["context"].as<string>();
|
||||
my->context = obj["context"].as<string>(max_depth);
|
||||
}
|
||||
|
||||
fc::string log_context::to_string()const
|
||||
|
|
@ -91,26 +91,26 @@ namespace fc
|
|||
log_context::~log_context(){}
|
||||
|
||||
|
||||
void to_variant( const log_context& l, variant& v )
|
||||
void to_variant( const log_context& l, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = l.to_variant();
|
||||
v = l.to_variant(max_depth);
|
||||
}
|
||||
|
||||
void from_variant( const variant& l, log_context& c )
|
||||
void from_variant( const variant& l, log_context& c, uint32_t max_depth )
|
||||
{
|
||||
c = log_context(l);
|
||||
c = log_context(l, max_depth);
|
||||
}
|
||||
|
||||
void from_variant( const variant& l, log_message& c )
|
||||
void from_variant( const variant& l, log_message& c, uint32_t max_depth )
|
||||
{
|
||||
c = log_message(l);
|
||||
c = log_message(l, max_depth);
|
||||
}
|
||||
void to_variant( const log_message& m, variant& v )
|
||||
void to_variant( const log_message& m, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = m.to_variant();
|
||||
v = m.to_variant( max_depth );
|
||||
}
|
||||
|
||||
void to_variant( log_level e, variant& v )
|
||||
void to_variant( log_level e, variant& v, uint32_t max_depth )
|
||||
{
|
||||
switch( e )
|
||||
{
|
||||
|
|
@ -134,7 +134,7 @@ namespace fc
|
|||
return;
|
||||
}
|
||||
}
|
||||
void from_variant( const variant& v, log_level& e )
|
||||
void from_variant( const variant& v, log_level& e, uint32_t max_depth )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -163,16 +163,16 @@ namespace fc
|
|||
string log_context::get_context()const { return my->context; }
|
||||
|
||||
|
||||
variant log_context::to_variant()const
|
||||
variant log_context::to_variant(uint32_t max_depth)const
|
||||
{
|
||||
mutable_variant_object o;
|
||||
o( "level", variant(my->level) )
|
||||
o( "level", variant(my->level, max_depth) )
|
||||
( "file", my->file )
|
||||
( "line", my->line )
|
||||
( "method", my->method )
|
||||
( "hostname", my->hostname )
|
||||
( "thread_name", my->thread_name )
|
||||
( "timestamp", variant(my->timestamp) );
|
||||
( "timestamp", variant(my->timestamp, max_depth) );
|
||||
|
||||
if( my->context.size() )
|
||||
o( "context", my->context );
|
||||
|
|
@ -191,22 +191,23 @@ namespace fc
|
|||
my->args = std::move(args);
|
||||
}
|
||||
|
||||
log_message::log_message( const variant& v )
|
||||
:my( std::make_shared<detail::log_message_impl>( log_context( v.get_object()["context"] ) ) )
|
||||
log_message::log_message( const variant& v, uint32_t max_depth )
|
||||
:my( std::make_shared<detail::log_message_impl>( log_context( v.get_object()["context"], max_depth ) ) )
|
||||
{
|
||||
my->format = v.get_object()["format"].as_string();
|
||||
my->args = v.get_object()["data"].get_object();
|
||||
}
|
||||
|
||||
variant log_message::to_variant()const
|
||||
variant log_message::to_variant(uint32_t max_depth)const
|
||||
{
|
||||
return mutable_variant_object( "context", my->context )
|
||||
return limited_mutable_variant_object(max_depth)
|
||||
( "context", my->context )
|
||||
( "format", my->format )
|
||||
( "data", my->args );
|
||||
}
|
||||
|
||||
log_context log_message::get_context()const { return my->context; }
|
||||
string log_message::get_format()const { return my->format; }
|
||||
log_context log_message::get_context()const { return my->context; }
|
||||
string log_message::get_format()const { return my->format; }
|
||||
variant_object log_message::get_data()const { return my->args; }
|
||||
|
||||
string log_message::get_message()const
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ namespace fc {
|
|||
get_logger_map().clear();
|
||||
get_appender_map().clear();
|
||||
|
||||
//slog( "\n%s", fc::json::to_pretty_string(cfg).c_str() );
|
||||
for( size_t i = 0; i < cfg.appenders.size(); ++i ) {
|
||||
appender::create( cfg.appenders[i].name, cfg.appenders[i].type, cfg.appenders[i].args );
|
||||
// TODO... process enabled
|
||||
|
|
|
|||
|
|
@ -137,20 +137,20 @@ namespace fc { namespace ip {
|
|||
|
||||
} // namespace ip
|
||||
|
||||
void to_variant( const ip::endpoint& var, variant& vo )
|
||||
void to_variant( const ip::endpoint& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = fc::string(var);
|
||||
}
|
||||
void from_variant( const variant& var, ip::endpoint& vo )
|
||||
void from_variant( const variant& var, ip::endpoint& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = ip::endpoint::from_string(var.as_string());
|
||||
}
|
||||
|
||||
void to_variant( const ip::address& var, variant& vo )
|
||||
void to_variant( const ip::address& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = fc::string(var);
|
||||
}
|
||||
void from_variant( const variant& var, ip::address& vo )
|
||||
void from_variant( const variant& var, ip::address& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = ip::address(var.as_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ namespace fc
|
|||
};
|
||||
}
|
||||
|
||||
void to_variant( const url& u, fc::variant& v )
|
||||
void to_variant( const url& u, fc::variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = fc::string(u);
|
||||
}
|
||||
void from_variant( const fc::variant& v, url& u )
|
||||
void from_variant( const fc::variant& v, url& u, uint32_t max_depth )
|
||||
{
|
||||
u = url( v.as_string() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ namespace fc
|
|||
return result;
|
||||
}
|
||||
|
||||
void to_variant( const real128& var, variant& vo )
|
||||
void to_variant( const real128& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = std::string(var);
|
||||
}
|
||||
void from_variant( const variant& var, real128& vo )
|
||||
void from_variant( const variant& var, real128& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = real128(var.as_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ http_api_connection::~http_api_connection()
|
|||
{
|
||||
}
|
||||
|
||||
http_api_connection::http_api_connection()
|
||||
http_api_connection::http_api_connection(uint32_t max_depth)
|
||||
:api_connection(max_depth)
|
||||
{
|
||||
_rpc_state.add_method( "call", [this]( const variants& args ) -> variant
|
||||
{
|
||||
|
|
@ -88,25 +89,27 @@ void http_api_connection::on_request( const fc::http::request& req, const fc::ht
|
|||
{
|
||||
resp.add_header( "Content-Type", "application/json" );
|
||||
std::string req_body( req.body.begin(), req.body.end() );
|
||||
auto var = fc::json::from_string( req_body );
|
||||
auto var = fc::json::from_string( req_body, fc::json::legacy_parser, _max_conversion_depth );
|
||||
const auto& var_obj = var.get_object();
|
||||
|
||||
if( var_obj.contains( "method" ) )
|
||||
{
|
||||
auto call = var.as<fc::rpc::request>();
|
||||
auto call = var.as<fc::rpc::request>(_max_conversion_depth);
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
auto result = _rpc_state.local_call( call.method, call.params );
|
||||
resp_body = fc::json::to_string( fc::rpc::response( *call.id, result ) );
|
||||
fc::variant result( _rpc_state.local_call( call.method, call.params ), _max_conversion_depth );
|
||||
resp_body = fc::json::to_string( fc::variant( fc::rpc::response( *call.id, result ), _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
resp_status = http::reply::OK;
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW( (call.method)(call.params) );
|
||||
}
|
||||
catch ( const fc::exception& e )
|
||||
{
|
||||
resp_body = fc::json::to_string( fc::rpc::response( *call.id, error_object{ 1, e.to_detail_string(), fc::variant(e)} ) );
|
||||
resp_body = fc::json::to_string( fc::variant( fc::rpc::response( *call.id, error_object{ 1, e.to_detail_string(), fc::variant(e, _max_conversion_depth)} ), _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
resp_status = http::reply::InternalServerError;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ namespace fc { namespace rpc {
|
|||
class json_connection_impl
|
||||
{
|
||||
public:
|
||||
json_connection_impl( fc::buffered_istream_ptr&& in, fc::buffered_ostream_ptr&& out )
|
||||
:_in(fc::move(in)),_out(fc::move(out)),_eof(false),_next_id(0),_logger("json_connection"){}
|
||||
json_connection_impl( fc::buffered_istream_ptr&& in, fc::buffered_ostream_ptr&& out, uint32_t max_depth )
|
||||
:_in(fc::move(in)),_out(fc::move(out)),_eof(false),_next_id(0),_logger("json_connection"),_max_depth(max_depth){}
|
||||
|
||||
fc::buffered_istream_ptr _in;
|
||||
fc::buffered_ostream_ptr _out;
|
||||
|
|
@ -33,6 +33,7 @@ namespace fc { namespace rpc {
|
|||
std::function<void(fc::exception_ptr)> _on_close;
|
||||
|
||||
logger _logger;
|
||||
uint32_t _max_depth;
|
||||
|
||||
void send_result( variant id, variant result )
|
||||
{
|
||||
|
|
@ -40,9 +41,9 @@ namespace fc { namespace rpc {
|
|||
{
|
||||
fc::scoped_lock<fc::mutex> lock(_write_mutex);
|
||||
*_out << "{\"id\":";
|
||||
json::to_stream( *_out, id );
|
||||
json::to_stream( *_out, id, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << ",\"result\":";
|
||||
json::to_stream( *_out, result);
|
||||
json::to_stream( *_out, result, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << "}\n";
|
||||
_out->flush();
|
||||
}
|
||||
|
|
@ -54,11 +55,11 @@ namespace fc { namespace rpc {
|
|||
{
|
||||
fc::scoped_lock<fc::mutex> lock(_write_mutex);
|
||||
*_out << "{\"id\":";
|
||||
json::to_stream( *_out, id );
|
||||
json::to_stream( *_out, id, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << ",\"error\":{\"message\":";
|
||||
json::to_stream( *_out, fc::string(e.what()) );
|
||||
*_out <<",\"code\":0,\"data\":";
|
||||
json::to_stream( *_out, variant(e));
|
||||
json::to_stream( *_out, variant(e, _max_depth), json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << "}}\n";
|
||||
_out->flush();
|
||||
}
|
||||
|
|
@ -165,10 +166,7 @@ namespace fc { namespace rpc {
|
|||
auto err = e->value().get_object();
|
||||
auto data = err.find( "data" );
|
||||
if( data != err.end() )
|
||||
{
|
||||
//wlog( "exception: ${except}", ("except", data->value() ) );
|
||||
await->second->set_exception( data->value().as<exception>().dynamic_copy_exception() );
|
||||
}
|
||||
await->second->set_exception( data->value().as<exception>(_max_depth).dynamic_copy_exception() );
|
||||
else
|
||||
await->second->set_exception( exception_ptr(new FC_EXCEPTION( exception, "${error}", ("error",e->value()) ) ) );
|
||||
}
|
||||
|
|
@ -207,7 +205,7 @@ namespace fc { namespace rpc {
|
|||
fc::string line;
|
||||
while( !_done.canceled() )
|
||||
{
|
||||
variant v = json::from_stream(*_in);
|
||||
variant v = json::from_stream( *_in, json::legacy_parser, _max_depth );
|
||||
///ilog( "input: ${in}", ("in", v ) );
|
||||
//wlog( "recv: ${line}", ("line", line) );
|
||||
_handle_message_future = fc::async([=](){ handle_message(v.get_object()); }, "json_connection handle_message");
|
||||
|
|
@ -242,8 +240,8 @@ namespace fc { namespace rpc {
|
|||
};
|
||||
}//namespace detail
|
||||
|
||||
json_connection::json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out )
|
||||
:my( new detail::json_connection_impl(fc::move(in),fc::move(out)) )
|
||||
json_connection::json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out, uint32_t max_depth )
|
||||
:_max_conversion_depth(max_depth),my( new detail::json_connection_impl(fc::move(in),fc::move(out),max_depth) )
|
||||
{}
|
||||
|
||||
json_connection::~json_connection()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ websocket_api_connection::~websocket_api_connection()
|
|||
{
|
||||
}
|
||||
|
||||
websocket_api_connection::websocket_api_connection( fc::http::websocket_connection& c )
|
||||
: _connection(c)
|
||||
websocket_api_connection::websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_depth )
|
||||
: api_connection(max_depth),_connection(c)
|
||||
{
|
||||
_rpc_state.add_method( "call", [this]( const variants& args ) -> variant
|
||||
{
|
||||
|
|
@ -58,7 +58,8 @@ variant websocket_api_connection::send_call(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
auto request = _rpc_state.start_remote_call( "call", {api_id, std::move(method_name), std::move(args) } );
|
||||
_connection.send_message( fc::json::to_string(request) );
|
||||
_connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
return _rpc_state.wait_for_response( *request.id );
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +68,8 @@ variant websocket_api_connection::send_callback(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
auto request = _rpc_state.start_remote_call( "callback", {callback_id, std::move(args) } );
|
||||
_connection.send_message( fc::json::to_string(request) );
|
||||
_connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
return _rpc_state.wait_for_response( *request.id );
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +78,8 @@ void websocket_api_connection::send_notice(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
fc::rpc::request req{ optional<uint64_t>(), "notice", {callback_id, std::move(args)}};
|
||||
_connection.send_message( fc::json::to_string(req) );
|
||||
_connection.send_message( fc::json::to_string(fc::variant(req, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
}
|
||||
|
||||
std::string websocket_api_connection::on_message(
|
||||
|
|
@ -85,12 +88,12 @@ std::string websocket_api_connection::on_message(
|
|||
{
|
||||
try
|
||||
{
|
||||
auto var = fc::json::from_string(message);
|
||||
auto var = fc::json::from_string(message, fc::json::legacy_parser, _max_conversion_depth);
|
||||
const auto& var_obj = var.get_object();
|
||||
|
||||
if( var_obj.contains( "method" ) )
|
||||
{
|
||||
auto call = var.as<fc::rpc::request>();
|
||||
auto call = var.as<fc::rpc::request>(_max_conversion_depth);
|
||||
exception_ptr optexcept;
|
||||
try
|
||||
{
|
||||
|
|
@ -113,7 +116,7 @@ std::string websocket_api_connection::on_message(
|
|||
|
||||
if( call.id )
|
||||
{
|
||||
auto reply = fc::json::to_string( response( *call.id, result, "2.0" ) );
|
||||
auto reply = fc::json::to_string( response( *call.id, result, "2.0" ), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
if( send_message )
|
||||
_connection.send_message( reply );
|
||||
return reply;
|
||||
|
|
@ -130,7 +133,8 @@ std::string websocket_api_connection::on_message(
|
|||
}
|
||||
if( optexcept ) {
|
||||
|
||||
auto reply = fc::json::to_string( response( *call.id, error_object{ 1, optexcept->to_string(), fc::variant(*optexcept)}, "2.0" ) );
|
||||
auto reply = fc::json::to_string( variant(response( *call.id, error_object{ 1, optexcept->to_string(), fc::variant(*optexcept, _max_conversion_depth)}, "2.0" ), _max_conversion_depth ),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
if( send_message )
|
||||
_connection.send_message( reply );
|
||||
|
||||
|
|
@ -139,7 +143,7 @@ std::string websocket_api_connection::on_message(
|
|||
}
|
||||
else
|
||||
{
|
||||
auto reply = var.as<fc::rpc::response>();
|
||||
auto reply = var.as<fc::rpc::response>(_max_conversion_depth);
|
||||
_rpc_state.handle_reply( reply );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ namespace fc {
|
|||
}
|
||||
}
|
||||
|
||||
string format_string( const string& format, const variant_object& args )
|
||||
string format_string( const string& format, const variant_object& args, uint32_t max_object_depth )
|
||||
{
|
||||
stringstream ss;
|
||||
size_t prev = 0;
|
||||
|
|
@ -291,7 +291,7 @@ namespace fc {
|
|||
{
|
||||
try
|
||||
{
|
||||
ss << json::to_string( val->value() );
|
||||
ss << json::to_string( val->value(), json::stringify_large_ints_and_doubles, max_object_depth );
|
||||
}
|
||||
catch( const fc::assert_exception& e )
|
||||
{
|
||||
|
|
|
|||
16
src/time.cpp
16
src/time.cpp
|
|
@ -54,16 +54,16 @@ namespace fc {
|
|||
return time_point( time_point_sec::from_iso_string( s ) );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "unable to convert ISO-formatted string to fc::time_point" ) }
|
||||
|
||||
void to_variant( const fc::time_point& t, variant& v ) {
|
||||
v = fc::string( t );
|
||||
void to_variant( const fc::time_point& t, variant& v, uint32_t max_depth ) {
|
||||
to_variant( fc::string( t ), v, max_depth );
|
||||
}
|
||||
void from_variant( const fc::variant& v, fc::time_point& t ) {
|
||||
void from_variant( const fc::variant& v, fc::time_point& t, uint32_t max_depth ) {
|
||||
t = fc::time_point::from_iso_string( v.as_string() );
|
||||
}
|
||||
void to_variant( const fc::time_point_sec& t, variant& v ) {
|
||||
v = fc::string( t );
|
||||
void to_variant( const fc::time_point_sec& t, variant& v, uint32_t max_depth ) {
|
||||
to_variant( fc::string( t ), v, max_depth );
|
||||
}
|
||||
void from_variant( const fc::variant& v, fc::time_point_sec& t ) {
|
||||
void from_variant( const fc::variant& v, fc::time_point_sec& t, uint32_t max_depth ) {
|
||||
t = fc::time_point_sec::from_iso_string( v.as_string() );
|
||||
}
|
||||
|
||||
|
|
@ -134,11 +134,11 @@ namespace fc {
|
|||
return get_approximate_relative_time_string(time_point_sec(event_time), time_point_sec(relative_to_time), ago);
|
||||
}
|
||||
|
||||
void to_variant( const microseconds& input_microseconds, variant& output_variant )
|
||||
void to_variant( const microseconds& input_microseconds, variant& output_variant, uint32_t max_depth )
|
||||
{
|
||||
output_variant = input_microseconds.count();
|
||||
}
|
||||
void from_variant( const variant& input_variant, microseconds& output_microseconds )
|
||||
void from_variant( const variant& input_variant, microseconds& output_microseconds, uint32_t max_depth )
|
||||
{
|
||||
output_microseconds = microseconds(input_variant.as_int64());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace fc
|
|||
template <typename T>
|
||||
static void divide(const T &numerator, const T &denominator, T "ient, T &remainder)
|
||||
{
|
||||
static const int bits = sizeof(T) * 8;//CHAR_BIT;
|
||||
static const int bits = sizeof(T) * 8;
|
||||
|
||||
if(denominator == 0) {
|
||||
throw std::domain_error("divide by zero");
|
||||
|
|
@ -228,22 +228,6 @@ namespace fc
|
|||
self /= other;
|
||||
hi = static_cast<uint64_t>(self >> 64);
|
||||
lo = static_cast<uint64_t>((self << 64 ) >> 64);
|
||||
|
||||
/*
|
||||
uint128 remainder;
|
||||
divide(*this, b, *this, remainder ); //, *this);
|
||||
if( tmp.hi != hi || tmp.lo != lo ) {
|
||||
std::cerr << tmp.hi << " " << hi <<"\n";
|
||||
std::cerr << tmp.lo << " " << lo << "\n";
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
const auto& b128 = std::reinterpret_cast<const m128&>(b);
|
||||
auto& this128 = std::reinterpret_cast<m128&>(*this);
|
||||
this128 /= b128;
|
||||
*/
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -344,8 +328,6 @@ namespace fc
|
|||
|
||||
result_hi = uint128( y[3], y[2] );
|
||||
result_lo = uint128( y[1], y[0] );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t _popcount_64( uint64_t x )
|
||||
|
|
@ -374,8 +356,14 @@ namespace fc
|
|||
return _popcount_64( lo ) + _popcount_64( hi );
|
||||
}
|
||||
|
||||
void to_variant( const uint128& var, variant& vo ) { vo = std::string(var); }
|
||||
void from_variant( const variant& var, uint128& vo ){ vo = uint128(var.as_string()); }
|
||||
void to_variant( const uint128& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = std::string(var);
|
||||
}
|
||||
void from_variant( const variant& var, uint128& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = uint128(var.as_string());
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
122
src/variant.cpp
122
src/variant.cpp
|
|
@ -27,140 +27,139 @@ variant::variant()
|
|||
set_variant_type( this, null_type );
|
||||
}
|
||||
|
||||
variant::variant( fc::nullptr_t )
|
||||
variant::variant( fc::nullptr_t, uint32_t max_depth )
|
||||
{
|
||||
set_variant_type( this, null_type );
|
||||
}
|
||||
|
||||
variant::variant( uint8_t val )
|
||||
variant::variant( uint8_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<uint64_t*>(this) = val;
|
||||
set_variant_type( this, uint64_type );
|
||||
}
|
||||
|
||||
variant::variant( int8_t val )
|
||||
variant::variant( int8_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<int64_t*>(this) = val;
|
||||
set_variant_type( this, int64_type );
|
||||
}
|
||||
|
||||
variant::variant( uint16_t val )
|
||||
variant::variant( uint16_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<uint64_t*>(this) = val;
|
||||
set_variant_type( this, uint64_type );
|
||||
}
|
||||
|
||||
variant::variant( int16_t val )
|
||||
variant::variant( int16_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<int64_t*>(this) = val;
|
||||
set_variant_type( this, int64_type );
|
||||
}
|
||||
|
||||
variant::variant( uint32_t val )
|
||||
variant::variant( uint32_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<uint64_t*>(this) = val;
|
||||
set_variant_type( this, uint64_type );
|
||||
}
|
||||
|
||||
variant::variant( int32_t val )
|
||||
variant::variant( int32_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<int64_t*>(this) = val;
|
||||
set_variant_type( this, int64_type );
|
||||
}
|
||||
|
||||
variant::variant( uint64_t val )
|
||||
variant::variant( uint64_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<uint64_t*>(this) = val;
|
||||
set_variant_type( this, uint64_type );
|
||||
}
|
||||
|
||||
variant::variant( int64_t val )
|
||||
variant::variant( int64_t val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<int64_t*>(this) = val;
|
||||
set_variant_type( this, int64_type );
|
||||
}
|
||||
|
||||
variant::variant( float val )
|
||||
variant::variant( float val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<double*>(this) = val;
|
||||
set_variant_type( this, double_type );
|
||||
}
|
||||
|
||||
variant::variant( double val )
|
||||
variant::variant( double val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<double*>(this) = val;
|
||||
set_variant_type( this, double_type );
|
||||
}
|
||||
|
||||
variant::variant( bool val )
|
||||
variant::variant( bool val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<bool*>(this) = val;
|
||||
set_variant_type( this, bool_type );
|
||||
}
|
||||
|
||||
variant::variant( char* str )
|
||||
variant::variant( char* str, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<string**>(this) = new string( str );
|
||||
set_variant_type( this, string_type );
|
||||
}
|
||||
|
||||
variant::variant( const char* str )
|
||||
variant::variant( const char* str, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<string**>(this) = new string( str );
|
||||
set_variant_type( this, string_type );
|
||||
}
|
||||
|
||||
// TODO: do a proper conversion to utf8
|
||||
variant::variant( wchar_t* str )
|
||||
variant::variant( wchar_t* str, uint32_t max_depth )
|
||||
{
|
||||
size_t len = wcslen(str);
|
||||
boost::scoped_array<char> buffer(new char[len]);
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
buffer[i] = (char)str[i];
|
||||
buffer[i] = (char)str[i];
|
||||
*reinterpret_cast<string**>(this) = new string(buffer.get(), len);
|
||||
set_variant_type( this, string_type );
|
||||
}
|
||||
|
||||
// TODO: do a proper conversion to utf8
|
||||
variant::variant( const wchar_t* str )
|
||||
variant::variant( const wchar_t* str, uint32_t max_depth )
|
||||
{
|
||||
size_t len = wcslen(str);
|
||||
boost::scoped_array<char> buffer(new char[len]);
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
buffer[i] = (char)str[i];
|
||||
buffer[i] = (char)str[i];
|
||||
*reinterpret_cast<string**>(this) = new string(buffer.get(), len);
|
||||
set_variant_type( this, string_type );
|
||||
}
|
||||
|
||||
variant::variant( fc::string val )
|
||||
variant::variant( fc::string val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<string**>(this) = new string( fc::move(val) );
|
||||
set_variant_type( this, string_type );
|
||||
}
|
||||
variant::variant( blob val )
|
||||
variant::variant( blob val, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<blob**>(this) = new blob( fc::move(val) );
|
||||
set_variant_type( this, blob_type );
|
||||
}
|
||||
|
||||
variant::variant( variant_object obj)
|
||||
variant::variant( variant_object obj, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<variant_object**>(this) = new variant_object(fc::move(obj));
|
||||
*reinterpret_cast<variant_object**>(this) = new variant_object(fc::move(obj));
|
||||
set_variant_type(this, object_type );
|
||||
}
|
||||
variant::variant( mutable_variant_object obj)
|
||||
variant::variant( mutable_variant_object obj, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<variant_object**>(this) = new variant_object(fc::move(obj));
|
||||
*reinterpret_cast<variant_object**>(this) = new variant_object(fc::move(obj));
|
||||
set_variant_type(this, object_type );
|
||||
}
|
||||
|
||||
variant::variant( variants arr )
|
||||
variant::variant( variants arr, uint32_t max_depth )
|
||||
{
|
||||
*reinterpret_cast<variants**>(this) = new variants(fc::move(arr));
|
||||
set_variant_type(this, array_type );
|
||||
}
|
||||
|
||||
|
||||
typedef const variant_object* const_variant_object_ptr;
|
||||
typedef const variants* const_variants_ptr;
|
||||
typedef const blob* const_blob_ptr;
|
||||
|
|
@ -185,7 +184,7 @@ void variant::clear()
|
|||
set_variant_type( this, null_type );
|
||||
}
|
||||
|
||||
variant::variant( const variant& v )
|
||||
variant::variant( const variant& v, uint32_t max_depth )
|
||||
{
|
||||
switch( v.get_type() )
|
||||
{
|
||||
|
|
@ -209,7 +208,7 @@ variant::variant( const variant& v )
|
|||
}
|
||||
}
|
||||
|
||||
variant::variant( variant&& v )
|
||||
variant::variant( variant&& v, uint32_t max_depth )
|
||||
{
|
||||
memcpy( this, &v, sizeof(v) );
|
||||
set_variant_type( &v, null_type );
|
||||
|
|
@ -575,88 +574,85 @@ const variant_object& variant::get_object()const
|
|||
FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from type '${type}' to Object", ("type",get_type()) );
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, variants& vo )
|
||||
void from_variant( const variant& var, variants& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.get_array();
|
||||
}
|
||||
|
||||
//void from_variant( const variant& var, variant_object& vo )
|
||||
//{
|
||||
// vo = var.get_object();
|
||||
//}
|
||||
void from_variant( const variant& var, variant& vo, uint32_t max_depth ) { vo = var; }
|
||||
|
||||
void from_variant( const variant& var, variant& vo ) { vo = var; }
|
||||
|
||||
void to_variant( const uint8_t& var, variant& vo ) { vo = uint64_t(var); }
|
||||
void to_variant( const uint8_t& var, variant& vo, uint32_t max_depth ) { vo = uint64_t(var); }
|
||||
// TODO: warn on overflow?
|
||||
void from_variant( const variant& var, uint8_t& vo ){ vo = static_cast<uint8_t>(var.as_uint64()); }
|
||||
void from_variant( const variant& var, uint8_t& vo, uint32_t max_depth ){ vo = static_cast<uint8_t>(var.as_uint64()); }
|
||||
|
||||
void to_variant( const int8_t& var, variant& vo ) { vo = int64_t(var); }
|
||||
void to_variant( const int8_t& var, variant& vo, uint32_t max_depth ) { vo = int64_t(var); }
|
||||
// TODO: warn on overflow?
|
||||
void from_variant( const variant& var, int8_t& vo ){ vo = static_cast<int8_t>(var.as_int64()); }
|
||||
void from_variant( const variant& var, int8_t& vo, uint32_t max_depth ) { vo = static_cast<int8_t>(var.as_int64()); }
|
||||
|
||||
void to_variant( const uint16_t& var, variant& vo ) { vo = uint64_t(var); }
|
||||
void to_variant( const uint16_t& var, variant& vo, uint32_t max_depth ) { vo = uint64_t(var); }
|
||||
// TODO: warn on overflow?
|
||||
void from_variant( const variant& var, uint16_t& vo ){ vo = static_cast<uint16_t>(var.as_uint64()); }
|
||||
void from_variant( const variant& var, uint16_t& vo, uint32_t max_depth ){ vo = static_cast<uint16_t>(var.as_uint64()); }
|
||||
|
||||
void to_variant( const int16_t& var, variant& vo ) { vo = int64_t(var); }
|
||||
void to_variant( const int16_t& var, variant& vo, uint32_t max_depth ) { vo = int64_t(var); }
|
||||
// TODO: warn on overflow?
|
||||
void from_variant( const variant& var, int16_t& vo ){ vo = static_cast<int16_t>(var.as_int64()); }
|
||||
void from_variant( const variant& var, int16_t& vo, uint32_t max_depth ){ vo = static_cast<int16_t>(var.as_int64()); }
|
||||
|
||||
void to_variant( const uint32_t& var, variant& vo ) { vo = uint64_t(var); }
|
||||
void from_variant( const variant& var, uint32_t& vo )
|
||||
void to_variant( const uint32_t& var, variant& vo, uint32_t max_depth ) { vo = uint64_t(var); }
|
||||
void from_variant( const variant& var, uint32_t& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = static_cast<uint32_t>(var.as_uint64());
|
||||
}
|
||||
|
||||
void to_variant( const int32_t& var, variant& vo ) { vo = int64_t(var); }
|
||||
void from_variant( const variant& var, int32_t& vo )
|
||||
void to_variant( const int32_t& var, variant& vo, uint32_t max_depth ) { vo = int64_t(var); }
|
||||
void from_variant( const variant& var,int32_t& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = static_cast<int32_t>(var.as_int64());
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, int64_t& vo )
|
||||
void to_variant( const int64_t& var, variant& vo, uint32_t max_depth ) { vo = var; }
|
||||
void from_variant( const variant& var, int64_t& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.as_int64();
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, uint64_t& vo )
|
||||
void to_variant( const uint64_t& var, variant& vo, uint32_t max_depth ) { vo = var; }
|
||||
void from_variant( const variant& var, uint64_t& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.as_uint64();
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, bool& vo )
|
||||
void from_variant( const variant& var, bool& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.as_bool();
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, double& vo )
|
||||
void from_variant( const variant& var, double& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.as_double();
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, float& vo )
|
||||
void from_variant( const variant& var, float& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = static_cast<float>(var.as_double());
|
||||
}
|
||||
|
||||
void to_variant( const std::string& s, variant& v )
|
||||
void to_variant( const std::string& s, variant& v, uint32_t max_depth )
|
||||
{
|
||||
v = variant( fc::string(s) );
|
||||
v = variant( fc::string(s), max_depth );
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, string& vo )
|
||||
void from_variant( const variant& var, string& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.as_string();
|
||||
}
|
||||
|
||||
void to_variant( const std::vector<char>& var, variant& vo )
|
||||
void to_variant( const std::vector<char>& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
if( var.size() )
|
||||
vo = variant(to_hex(var.data(),var.size()));
|
||||
else vo = "";
|
||||
}
|
||||
void from_variant( const variant& var, std::vector<char>& vo )
|
||||
void from_variant( const variant& var, std::vector<char>& vo, uint32_t max_depth )
|
||||
{
|
||||
auto str = var.as_string();
|
||||
vo.resize( str.size() / 2 );
|
||||
|
|
@ -665,15 +661,13 @@ void from_variant( const variant& var, std::vector<char>& vo )
|
|||
size_t r = from_hex( str, vo.data(), vo.size() );
|
||||
FC_ASSERT( r == vo.size() );
|
||||
}
|
||||
// std::string b64 = base64_decode( var.as_string() );
|
||||
// vo = std::vector<char>( b64.c_str(), b64.c_str() + b64.size() );
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#elif !defined(_MSC_VER)
|
||||
void to_variant( long long int s, variant& v ) { v = variant( int64_t(s) ); }
|
||||
void to_variant( unsigned long long int s, variant& v ) { v = variant( uint64_t(s)); }
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#elif !defined(_MSC_VER)
|
||||
void to_variant( long long int s, variant& v, uint32_t max_depth ) { v = variant( int64_t(s) ); }
|
||||
void to_variant( unsigned long long int s, variant& v, uint32_t max_depth ) { v = variant( uint64_t(s)); }
|
||||
#endif
|
||||
|
||||
variant operator == ( const variant& a, const variant& b )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ namespace fc
|
|||
variant_object::variant_object( string key, variant val )
|
||||
: _key_value(std::make_shared<std::vector<entry>>())
|
||||
{
|
||||
//_key_value->push_back(entry(fc::move(key), fc::move(val)));
|
||||
_key_value->emplace_back(entry(fc::move(key), fc::move(val)));
|
||||
}
|
||||
|
||||
|
|
@ -163,12 +162,12 @@ namespace fc
|
|||
return *this;
|
||||
}
|
||||
|
||||
void to_variant( const variant_object& var, variant& vo )
|
||||
void to_variant( const variant_object& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = variant(var);
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, variant_object& vo )
|
||||
void from_variant( const variant& var, variant_object& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.get_object();
|
||||
}
|
||||
|
|
@ -344,7 +343,7 @@ namespace fc
|
|||
/** Appends \a key and \a var without checking for duplicates, designed to
|
||||
* simplify construction of dictionaries using (key,val)(key2,val2) syntax
|
||||
*/
|
||||
mutable_variant_object& mutable_variant_object::operator()( string key, variant var )
|
||||
mutable_variant_object& mutable_variant_object::operator()( string key, variant var, uint32_t max_depth )
|
||||
{
|
||||
_key_value->push_back( entry( fc::move(key), fc::move(var) ) );
|
||||
return *this;
|
||||
|
|
@ -366,12 +365,24 @@ namespace fc
|
|||
return *this;
|
||||
}
|
||||
|
||||
void to_variant( const mutable_variant_object& var, variant& vo )
|
||||
limited_mutable_variant_object::limited_mutable_variant_object( uint32_t m )
|
||||
: mutable_variant_object(), _max_depth(m - 1)
|
||||
{
|
||||
FC_ASSERT( m > 0, "Recursion depth exceeded!" );
|
||||
}
|
||||
|
||||
limited_mutable_variant_object& limited_mutable_variant_object::operator()( const variant_object& vo )
|
||||
{
|
||||
mutable_variant_object::operator()( vo );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void to_variant( const mutable_variant_object& var, variant& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = variant(var);
|
||||
}
|
||||
|
||||
void from_variant( const variant& var, mutable_variant_object& vo )
|
||||
void from_variant( const variant& var, mutable_variant_object& vo, uint32_t max_depth )
|
||||
{
|
||||
vo = var.get_object();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ class variant_calculator
|
|||
using namespace fc::http;
|
||||
using namespace fc::rpc;
|
||||
|
||||
#define MAX_DEPTH 10
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
try {
|
||||
|
|
@ -59,7 +61,7 @@ int main( int argc, char** argv )
|
|||
|
||||
fc::http::websocket_server server;
|
||||
server.on_connection([&]( const websocket_connection_ptr& c ){
|
||||
auto wsc = std::make_shared<websocket_api_connection>(*c);
|
||||
auto wsc = std::make_shared<websocket_api_connection>(*c, MAX_DEPTH);
|
||||
auto login = std::make_shared<login_api>();
|
||||
login->calc = calc_api;
|
||||
wsc->register_api(fc::api<login_api>(login));
|
||||
|
|
@ -74,7 +76,7 @@ int main( int argc, char** argv )
|
|||
try {
|
||||
fc::http::websocket_client client;
|
||||
auto con = client.connect( "ws://localhost:8090" );
|
||||
auto apic = std::make_shared<websocket_api_connection>(*con);
|
||||
auto apic = std::make_shared<websocket_api_connection>(*con, MAX_DEPTH);
|
||||
auto remote_login_api = apic->get_remote_api<login_api>();
|
||||
auto remote_calc = remote_login_api->get_calc();
|
||||
remote_calc->on_result( []( uint32_t r ) { elog( "callback result ${r}", ("r",r) ); } );
|
||||
|
|
@ -167,8 +169,8 @@ int main( int argc, char** argv )
|
|||
fc::api<login_api> napi(&napi_impl);
|
||||
|
||||
|
||||
auto client_side = std::make_shared<local_api_connection>();
|
||||
auto server_side = std::make_shared<local_api_connection>();
|
||||
auto client_side = std::make_shared<local_api_connection>(MAX_DEPTH);
|
||||
auto server_side = std::make_shared<local_api_connection>(MAX_DEPTH);
|
||||
server_side->set_remote_connection( client_side );
|
||||
client_side->set_remote_connection( server_side );
|
||||
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ void test_big( const std::string& expected ) {
|
|||
|
||||
H hash2( expected );
|
||||
fc::variant v;
|
||||
to_variant( hash2, v );
|
||||
from_variant( v, hash );
|
||||
to_variant( hash2, v, 5 );
|
||||
from_variant( v, hash, 5 );
|
||||
BOOST_CHECK( hash == hash2 );
|
||||
|
||||
H hash3( expected.substr(15) + "000000000000000" );
|
||||
|
|
|
|||
|
|
@ -128,9 +128,9 @@ static bool equal( const fc::variant& a, const fc::variant& b )
|
|||
{
|
||||
auto a_type = a.get_type();
|
||||
auto b_type = b.get_type();
|
||||
if( a_type == fc::variant::type_id::int64_type && a.as<int64_t>() > 0 )
|
||||
if( a_type == fc::variant::type_id::int64_type && a.as<int64_t>(1) > 0 )
|
||||
a_type = fc::variant::type_id::uint64_type;
|
||||
if( b_type == fc::variant::type_id::int64_type && b.as<int64_t>() > 0 )
|
||||
if( b_type == fc::variant::type_id::int64_type && b.as<int64_t>(1) > 0 )
|
||||
b_type = fc::variant::type_id::uint64_type;
|
||||
if( a_type != b_type )
|
||||
{
|
||||
|
|
@ -138,17 +138,17 @@ static bool equal( const fc::variant& a, const fc::variant& b )
|
|||
&& b_type == fc::variant::type_id::string_type )
|
||||
|| ( a_type == fc::variant::type_id::string_type
|
||||
&& b_type == fc::variant::type_id::double_type ) )
|
||||
return a.as<double>() == b.as<double>();
|
||||
return a.as<double>(1) == b.as<double>(1);
|
||||
return false;
|
||||
}
|
||||
switch( a_type )
|
||||
{
|
||||
case fc::variant::type_id::null_type: return true;
|
||||
case fc::variant::type_id::int64_type: return a.as<int64_t>() == b.as<int64_t>();
|
||||
case fc::variant::type_id::uint64_type: return a.as<uint64_t>() == b.as<uint64_t>();
|
||||
case fc::variant::type_id::double_type: return a.as<double>() == b.as<double>();
|
||||
case fc::variant::type_id::bool_type: return a.as<bool>() == b.as<bool>();
|
||||
case fc::variant::type_id::string_type: return a.as<std::string>() == b.as<std::string>();
|
||||
case fc::variant::type_id::int64_type: return a.as<int64_t>(1) == b.as<int64_t>(1);
|
||||
case fc::variant::type_id::uint64_type: return a.as<uint64_t>(1) == b.as<uint64_t>(1);
|
||||
case fc::variant::type_id::double_type: return a.as<double>(1) == b.as<double>(1);
|
||||
case fc::variant::type_id::bool_type: return a.as<bool>(1) == b.as<bool>(1);
|
||||
case fc::variant::type_id::string_type: return a.as<std::string>(1) == b.as<std::string>(1);
|
||||
case fc::variant::type_id::array_type:
|
||||
if( a.get_array().size() != b.get_array().size() ) return false;
|
||||
else
|
||||
|
|
@ -311,8 +311,8 @@ BOOST_AUTO_TEST_CASE(structured_test)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(precision_test)
|
||||
{
|
||||
BOOST_CHECK_EQUAL( "\"4294967296\"", fc::json::to_string( fc::variant( 0x100000000LL ) ) );
|
||||
BOOST_CHECK_EQUAL( "\"-4294967296\"", fc::json::to_string( fc::variant( -0x100000000LL ) ) );
|
||||
BOOST_CHECK_EQUAL( "\"4294967296\"", fc::json::to_string( fc::variant( int64_t(0x100000000LL) ) ) );
|
||||
BOOST_CHECK_EQUAL( "\"-4294967296\"", fc::json::to_string( fc::variant( int64_t(-0x100000000LL) ) ) );
|
||||
std::string half = fc::json::to_string( fc::variant( 0.5 ) );
|
||||
BOOST_CHECK_EQUAL( '"', half.front() );
|
||||
BOOST_CHECK_EQUAL( '"', half.back() );
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ BOOST_AUTO_TEST_CASE(websocket_test)
|
|||
BOOST_FAIL("expected assertion failure");
|
||||
} catch (const fc::assert_exception& e) {
|
||||
std::cerr << e.to_string() << "\n";
|
||||
} catch (const fc::exception& e) {
|
||||
BOOST_FAIL("Unexpected exception: " + e.to_string());
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_FAIL("Unexpected exception: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue