Updates from BitShares FC #22

Closed
nathanielhourt wants to merge 693 commits from dapp-support into latest-fc
15 changed files with 610 additions and 476 deletions
Showing only changes of commit 86e18663a0 - Show all commits

4
include/fc/config.hpp Normal file
View file

@ -0,0 +1,4 @@
#ifndef FC_PACK_MAX_DEPTH
// The maximum level of object nesting is around 20% of this value
#define FC_PACK_MAX_DEPTH 1000
#endif

View file

@ -1,13 +1,14 @@
#pragma once #pragma once
#include <fc/config.hpp>
#include <deque> #include <deque>
namespace fc { namespace fc {
namespace raw { namespace raw {
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const std::deque<T>& value ); void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, std::deque<T>& value ); void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
} }
} // namespace fc } // namespace fc

View file

@ -8,61 +8,66 @@
namespace fc { namespace fc {
namespace raw { namespace raw {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const flat_set<T>& value ) { inline void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth ) {
pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto itr = value.begin(); auto itr = value.begin();
auto end = value.end(); auto end = value.end();
while( itr != end ) { while( itr != end ) {
fc::raw::pack( s, *itr ); fc::raw::pack( s, *itr, _max_depth - 1 );
++itr; ++itr;
} }
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, flat_set<T>& value ) { inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth ) {
unsigned_int size; unpack( s, size ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 );
value.clear(); value.clear();
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
value.reserve(size.value); value.reserve(size.value);
for( uint32_t i = 0; i < size.value; ++i ) for( uint32_t i = 0; i < size.value; ++i )
{ {
T tmp; T tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
template<typename Stream, typename K, typename... V> template<typename Stream, typename K, typename... V>
inline void pack( Stream& s, const flat_map<K,V...>& value ) { inline void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth ) {
pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto itr = value.begin(); auto itr = value.begin();
auto end = value.end(); auto end = value.end();
while( itr != end ) { while( itr != end ) {
fc::raw::pack( s, *itr ); fc::raw::pack( s, *itr, _max_depth - 1 );
++itr; ++itr;
} }
} }
template<typename Stream, typename K, typename V, typename... A> template<typename Stream, typename K, typename V, typename... A>
inline void unpack( Stream& s, flat_map<K,V,A...>& value ) inline void unpack( Stream& s, flat_map<K,V,A...>& value, uint32_t _max_depth )
{ {
unsigned_int size; unpack( s, size ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 );
value.clear(); value.clear();
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE ); FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
value.reserve(size.value); value.reserve(size.value);
for( uint32_t i = 0; i < size.value; ++i ) for( uint32_t i = 0; i < size.value; ++i )
{ {
std::pair<K,V> tmp; std::pair<K,V> tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void pack( Stream& s, const bip::vector<T,A>& value ) { void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth ) {
pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
if( !std::is_fundamental<T>::value ) { if( !std::is_fundamental<T>::value ) {
auto itr = value.begin(); auto itr = value.begin();
auto end = value.end(); auto end = value.end();
while( itr != end ) { while( itr != end ) {
fc::raw::pack( s, *itr ); fc::raw::pack( s, *itr, _max_depth - 1 );
++itr; ++itr;
} }
} else { } else {
@ -71,13 +76,14 @@ namespace fc {
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void unpack( Stream& s, bip::vector<T,A>& value ) { void unpack( Stream& s, bip::vector<T,A>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size; unsigned_int size;
unpack( s, size ); unpack( s, size, _max_depth - 1 );
value.resize( size ); value.resize( size );
if( !std::is_fundamental<T>::value ) { if( !std::is_fundamental<T>::value ) {
for( auto& item : value ) for( auto& item : value )
unpack( s, item ); unpack( s, item, _max_depth - 1 );
} else { } else {
s.read( (char*)value.data(), value.size() ); s.read( (char*)value.data(), value.size() );
} }

View file

@ -1,7 +1,8 @@
#pragma once #pragma once
#include <boost/container/flat_map.hpp> #include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp> #include <boost/container/flat_set.hpp>
#include <boost/interprocess/containers/vector.hpp> #include <boost/interprocess/containers/vector.hpp>
#include <fc/config.hpp>
namespace fc { namespace fc {
@ -11,19 +12,19 @@ namespace fc {
namespace raw { namespace raw {
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const flat_set<T>& value ); void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, flat_set<T>& value ); void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename... V> template<typename Stream, typename K, typename... V>
void pack( Stream& s, const flat_map<K,V...>& value ); void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V, typename... A> template<typename Stream, typename K, typename V, typename... A>
void unpack(Stream& s, flat_map<K, V, A...>& value); void unpack(Stream& s, flat_map<K, V, A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void pack( Stream& s, const bip::vector<T,A>& value ); void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void unpack( Stream& s, bip::vector<T,A>& value ); void unpack( Stream& s, bip::vector<T,A>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
} // namespace raw } // namespace raw
} // fc } // fc

View file

@ -260,31 +260,35 @@ namespace fc {
namespace raw namespace raw
{ {
template<typename Stream> template<typename Stream>
void unpack( Stream& s, fc::ecc::public_key& pk) void unpack( Stream& s, fc::ecc::public_key& pk, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
ecc::public_key_data ser; ecc::public_key_data ser;
fc::raw::unpack(s,ser); fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::ecc::public_key( ser ); pk = fc::ecc::public_key( ser );
} }
template<typename Stream> template<typename Stream>
void pack( Stream& s, const fc::ecc::public_key& pk) void pack( Stream& s, const fc::ecc::public_key& pk, uint32_t _max_depth )
{ {
fc::raw::pack( s, pk.serialize() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
void unpack( Stream& s, fc::ecc::private_key& pk) void unpack( Stream& s, fc::ecc::private_key& pk, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
fc::sha256 sec; fc::sha256 sec;
unpack( s, sec ); unpack( s, sec, _max_depth - 1 );
pk = ecc::private_key::regenerate(sec); pk = ecc::private_key::regenerate(sec);
} }
template<typename Stream> template<typename Stream>
void pack( Stream& s, const fc::ecc::private_key& pk) void pack( Stream& s, const fc::ecc::private_key& pk, uint32_t _max_depth )
{ {
fc::raw::pack( s, pk.get_secret() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.get_secret(), _max_depth - 1 );
} }
} // namespace raw } // namespace raw

View file

@ -76,31 +76,35 @@ namespace fc {
namespace raw namespace raw
{ {
template<typename Stream> template<typename Stream>
void unpack( Stream& s, fc::public_key& pk) void unpack( Stream& s, fc::public_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
FC_ASSERT( _max_depth > 0 );
bytes ser; bytes ser;
fc::raw::unpack(s,ser); fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::public_key( ser ); pk = fc::public_key( ser );
} }
template<typename Stream> template<typename Stream>
void pack( Stream& s, const fc::public_key& pk) void pack( Stream& s, const fc::public_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
fc::raw::pack( s, pk.serialize() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
void unpack( Stream& s, fc::private_key& pk) void unpack( Stream& s, fc::private_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
FC_ASSERT( _max_depth > 0 );
bytes ser; bytes ser;
fc::raw::unpack(s,ser); fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::private_key( ser ); pk = fc::private_key( ser );
} }
template<typename Stream> template<typename Stream>
void pack( Stream& s, const fc::private_key& pk) void pack( Stream& s, const fc::private_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
fc::raw::pack( s, pk.serialize() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
} }
} }
class variant; class variant;

View file

@ -98,16 +98,18 @@ namespace fc {
namespace raw namespace raw
{ {
template<typename Stream, typename Storage> template<typename Stream, typename Storage>
inline void pack( Stream& s, const fc::fixed_string<Storage>& u ) { inline void pack( Stream& s, const fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size = u.size(); unsigned_int size = u.size();
pack( s, size ); pack( s, size, _max_depth - 1 );
s.write( (const char*)&u.data, size ); s.write( (const char*)&u.data, size );
} }
template<typename Stream, typename Storage> template<typename Stream, typename Storage>
inline void unpack( Stream& s, fc::fixed_string<Storage>& u ) { inline void unpack( Stream& s, fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size; unsigned_int size;
fc::raw::unpack( s, size ); fc::raw::unpack( s, size, _max_depth - 1 );
if( size.value > 0 ) { if( size.value > 0 ) {
if( size.value > sizeof(Storage) ) { if( size.value > sizeof(Storage) ) {
s.read( (char*)&u.data, sizeof(Storage) ); s.read( (char*)&u.data, sizeof(Storage) );
@ -135,12 +137,12 @@ namespace fc {
/* /*
template<typename Stream, typename... Args> template<typename Stream, typename... Args>
inline void pack( Stream& s, const boost::multiprecision::number<Args...>& d ) { 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) ); s.write( (const char*)&d, sizeof(d) );
} }
template<typename Stream, typename... Args> template<typename Stream, typename... Args>
inline void unpack( Stream& s, boost::multiprecision::number<Args...>& u ) { 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) ); s.read( (const char*)&u, sizeof(u) );
} }
*/ */

View file

@ -122,22 +122,24 @@ namespace fc {
namespace bip = boost::interprocess; namespace bip = boost::interprocess;
template<typename Stream, typename T, typename... A> template<typename Stream, typename T, typename... A>
inline void pack( Stream& s, const bip::vector<T,A...>& value ) { inline void pack( Stream& s, const bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T, typename... A> template<typename Stream, typename T, typename... A>
inline void unpack( Stream& s, bip::vector<T,A...>& value ) { inline void unpack( Stream& s, bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
unsigned_int size; FC_ASSERT( _max_depth > 0 );
unpack( s, size ); unsigned_int size;
value.clear(); value.resize(size); unpack( s, size, _max_depth - 1 );
for( auto& item : value ) value.clear(); value.resize(size);
fc::raw::unpack( s, item ); for( auto& item : value )
fc::raw::unpack( s, item, _max_depth - 1 );
} }
} }
} }

View file

@ -11,16 +11,16 @@ namespace fc
public: public:
enum_type( EnumType t ) enum_type( EnumType t )
:value(t){} :value(t){}
enum_type( IntType t ) enum_type( IntType t )
:value( (EnumType)t ){} :value( (EnumType)t ){}
enum_type(){} enum_type(){}
explicit operator IntType()const { return static_cast<IntType>(value); } explicit operator IntType()const { return static_cast<IntType>(value); }
operator EnumType()const { return value; } operator EnumType()const { return value; }
operator std::string()const { return fc::reflector<EnumType>::to_string(value); } operator std::string()const { return fc::reflector<EnumType>::to_string(value); }
enum_type& operator=( IntType i ) { value = (EnumType)i; return *this;} enum_type& operator=( IntType i ) { value = (EnumType)i; return *this;}
enum_type& operator=( EnumType i ) { value = i; return *this;} enum_type& operator=( EnumType i ) { value = i; return *this;}
bool operator<( EnumType i ) const { return value < i; } bool operator<( EnumType i ) const { return value < i; }
@ -60,19 +60,21 @@ namespace fc
/** serializes like an IntType */ /** serializes like an IntType */
namespace raw namespace raw
{ {
template<typename Stream, typename IntType, typename EnumType> template<typename Stream, typename IntType, typename EnumType>
inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp ) inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth )
{ {
fc::raw::pack( s, static_cast<IntType>(tp) ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, static_cast<IntType>(tp), _max_depth - 1 );
} }
template<typename Stream, typename IntType, typename EnumType> template<typename Stream, typename IntType, typename EnumType>
inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp ) inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
IntType t; IntType t;
fc::raw::unpack( s, t ); fc::raw::unpack( s, t, _max_depth - 1 );
tp = t; tp = t;
} }
} }

View file

@ -19,70 +19,77 @@ namespace fc {
namespace raw { namespace raw {
template<typename Stream, typename Arg0, typename... Args> template<typename Stream, typename Arg0, typename... Args>
inline void pack( Stream& s, const Arg0& a0, Args... args ) { inline void pack( Stream& s, const Arg0& a0, Args... args, uint32_t _max_depth ) {
pack( s, a0 ); FC_ASSERT( _max_depth > 0 );
pack( s, args... ); pack( s, a0, _max_depth - 1 );
pack( s, args..., _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::exception& e ) inline void pack( Stream& s, const fc::exception& e, uint32_t _max_depth )
{ {
fc::raw::pack( s, e.code() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, std::string(e.name()) ); fc::raw::pack( s, e.code(), _max_depth - 1 );
fc::raw::pack( s, std::string(e.what()) ); fc::raw::pack( s, std::string(e.name()), _max_depth - 1 );
fc::raw::pack( s, e.get_log() ); fc::raw::pack( s, std::string(e.what()), _max_depth - 1 );
fc::raw::pack( s, e.get_log(), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::exception& e ) inline void unpack( Stream& s, fc::exception& e, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
int64_t code; int64_t code;
std::string name, what; std::string name, what;
log_messages msgs; log_messages msgs;
fc::raw::unpack( s, code ); fc::raw::unpack( s, code, _max_depth - 1 );
fc::raw::unpack( s, name ); fc::raw::unpack( s, name, _max_depth - 1 );
fc::raw::unpack( s, what ); fc::raw::unpack( s, what, _max_depth - 1 );
fc::raw::unpack( s, msgs ); fc::raw::unpack( s, msgs, _max_depth - 1 );
e = fc::exception( fc::move(msgs), code, name, what ); e = fc::exception( fc::move(msgs), code, name, what );
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::log_message& msg ) inline void pack( Stream& s, const fc::log_message& msg, uint32_t _max_depth )
{ {
fc::raw::pack( s, variant(msg) ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, variant(msg), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::log_message& msg ) inline void unpack( Stream& s, fc::log_message& msg, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
fc::variant vmsg; fc::variant vmsg;
fc::raw::unpack( s, vmsg ); fc::raw::unpack( s, vmsg, _max_depth - 1 );
msg = vmsg.as<log_message>(); msg = vmsg.as<log_message>();
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::path& tp ) inline void pack( Stream& s, const fc::path& tp, uint32_t _max_depth )
{ {
fc::raw::pack( s, tp.generic_string() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, tp.generic_string(), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::path& tp ) inline void unpack( Stream& s, fc::path& tp, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
std::string p; std::string p;
fc::raw::unpack( s, p ); fc::raw::unpack( s, p, _max_depth - 1 );
tp = p; tp = p;
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::time_point_sec& tp ) inline void pack( Stream& s, const fc::time_point_sec& tp, uint32_t _max_depth )
{ {
uint32_t usec = tp.sec_since_epoch(); uint32_t usec = tp.sec_since_epoch();
s.write( (const char*)&usec, sizeof(usec) ); s.write( (const char*)&usec, sizeof(usec) );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::time_point_sec& tp ) inline void unpack( Stream& s, fc::time_point_sec& tp, uint32_t _max_depth )
{ try { { try {
uint32_t sec; uint32_t sec;
s.read( (char*)&sec, sizeof(sec) ); s.read( (char*)&sec, sizeof(sec) );
@ -90,14 +97,14 @@ namespace fc {
} FC_RETHROW_EXCEPTIONS( warn, "" ) } } FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::time_point& tp ) inline void pack( Stream& s, const fc::time_point& tp, uint32_t _max_depth )
{ {
uint64_t usec = tp.time_since_epoch().count(); uint64_t usec = tp.time_since_epoch().count();
s.write( (const char*)&usec, sizeof(usec) ); s.write( (const char*)&usec, sizeof(usec) );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::time_point& tp ) inline void unpack( Stream& s, fc::time_point& tp, uint32_t _max_depth )
{ try { { try {
uint64_t usec; uint64_t usec;
s.read( (char*)&usec, sizeof(usec) ); s.read( (char*)&usec, sizeof(usec) );
@ -105,14 +112,14 @@ namespace fc {
} FC_RETHROW_EXCEPTIONS( warn, "" ) } } FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::microseconds& usec ) inline void pack( Stream& s, const fc::microseconds& usec, uint32_t _max_depth )
{ {
uint64_t usec_as_int64 = usec.count(); uint64_t usec_as_int64 = usec.count();
s.write( (const char*)&usec_as_int64, sizeof(usec_as_int64) ); s.write( (const char*)&usec_as_int64, sizeof(usec_as_int64) );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::microseconds& usec ) inline void unpack( Stream& s, fc::microseconds& usec, uint32_t _max_depth )
{ try { { try {
uint64_t usec_as_int64; uint64_t usec_as_int64;
s.read( (char*)&usec_as_int64, sizeof(usec_as_int64) ); s.read( (char*)&usec_as_int64, sizeof(usec_as_int64) );
@ -120,30 +127,32 @@ namespace fc {
} FC_RETHROW_EXCEPTIONS( warn, "" ) } } FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream, typename T, size_t N> template<typename Stream, typename T, size_t N>
inline void pack( Stream& s, const fc::array<T,N>& v) { inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) {
s.write((const char*)&v.data[0],N*sizeof(T)); s.write((const char*)&v.data[0],N*sizeof(T));
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::shared_ptr<T>& v) inline void pack( Stream& s, const std::shared_ptr<T>& v, uint32_t _max_depth )
{ {
fc::raw::pack( s, *v ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, *v, _max_depth - 1 );
} }
template<typename Stream, typename T, size_t N> template<typename Stream, typename T, size_t N>
inline void unpack( Stream& s, fc::array<T,N>& v) inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth )
{ try { { try {
s.read((char*)&v.data[0],N*sizeof(T)); s.read((char*)&v.data[0],N*sizeof(T));
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) } } FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::shared_ptr<T>& v) inline void unpack( Stream& s, std::shared_ptr<T>& v, uint32_t _max_depth )
{ try { { try {
v = std::make_shared<T>(); FC_ASSERT( _max_depth > 0 );
fc::raw::unpack( s, *v ); v = std::make_shared<T>();
fc::raw::unpack( s, *v, _max_depth - 1 );
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) } } FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }
template<typename Stream> inline void pack( Stream& s, const signed_int& v ) { template<typename Stream> inline void pack( Stream& s, const signed_int& v, uint32_t _max_depth ) {
uint32_t val = (v.value<<1) ^ (v.value>>31); uint32_t val = (v.value<<1) ^ (v.value>>31);
do { do {
uint8_t b = uint8_t(val) & 0x7f; uint8_t b = uint8_t(val) & 0x7f;
@ -153,7 +162,7 @@ namespace fc {
} while( val ); } while( val );
} }
template<typename Stream> inline void pack( Stream& s, const unsigned_int& v ) { template<typename Stream> inline void pack( Stream& s, const unsigned_int& v, uint32_t _max_depth ) {
uint64_t val = v.value; uint64_t val = v.value;
do { do {
uint8_t b = uint8_t(val) & 0x7f; uint8_t b = uint8_t(val) & 0x7f;
@ -163,7 +172,7 @@ namespace fc {
}while( val ); }while( val );
} }
template<typename Stream> inline void unpack( Stream& s, signed_int& vi ) { template<typename Stream> inline void unpack( Stream& s, signed_int& vi, uint32_t _max_depth ) {
uint32_t v = 0; char b = 0; int by = 0; uint32_t v = 0; char b = 0; int by = 0;
do { do {
s.get(b); s.get(b);
@ -174,7 +183,7 @@ namespace fc {
vi.value = v&0x01 ? vi.value : -vi.value; vi.value = v&0x01 ? vi.value : -vi.value;
vi.value = -vi.value; vi.value = -vi.value;
} }
template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi ) { template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi, uint32_t _max_depth ) {
uint64_t v = 0; char b = 0; uint8_t by = 0; uint64_t v = 0; char b = 0; uint8_t by = 0;
do { do {
s.get(b); s.get(b);
@ -184,83 +193,117 @@ namespace fc {
vi.value = static_cast<uint32_t>(v); vi.value = static_cast<uint32_t>(v);
} }
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi ) template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
T tmp; T tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
FC_ASSERT( vi == tmp ); FC_ASSERT( vi == tmp );
} }
template<typename Stream> inline void pack( Stream& s, const char* v ) { fc::raw::pack( s, fc::string(v) ); } template<typename Stream> inline void pack( Stream& s, const char* v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, fc::string(v), _max_depth - 1 );
}
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const safe<T>& v ) { fc::raw::pack( s, v.value ); } void pack( Stream& s, const safe<T>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, v.value, _max_depth - 1 );
}
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, fc::safe<T>& v ) { fc::raw::unpack( s, v.value ); } void unpack( Stream& s, fc::safe<T>& v, uint32_t _max_depth )
{
template<typename Stream, typename T, unsigned int S, typename Align> FC_ASSERT( _max_depth > 0 );
void pack( Stream& s, const fc::fwd<T,S,Align>& v ) { fc::raw::unpack( s, v.value, _max_depth - 1 );
fc::raw::pack( *v );
} }
template<typename Stream, typename T, unsigned int S, typename Align> template<typename Stream, typename T, unsigned int S, typename Align>
void unpack( Stream& s, fc::fwd<T,S,Align>& v ) { void pack( Stream& s, const fc::fwd<T,S,Align>& v, uint32_t _max_depth ) {
fc::raw::unpack( *v ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( *v, _max_depth - 1 ); // TODO not sure about this
}
template<typename Stream, typename T, unsigned int S, typename Align>
void unpack( Stream& s, fc::fwd<T,S,Align>& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
fc::raw::unpack( *v, _max_depth - 1 ); // TODO not sure about this
} }
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const fc::smart_ref<T>& v ) { fc::raw::pack( s, *v ); } void pack( Stream& s, const fc::smart_ref<T>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, *v, _max_depth - 1 );
}
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, fc::smart_ref<T>& v ) { fc::raw::unpack( s, *v ); } void unpack( Stream& s, fc::smart_ref<T>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::unpack( s, *v, _max_depth - 1 );
}
// optional // optional
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const fc::optional<T>& v ) { void pack( Stream& s, const fc::optional<T>& v, uint32_t _max_depth ) {
fc::raw::pack( s, bool(!!v) ); FC_ASSERT( _max_depth > 0 );
if( !!v ) fc::raw::pack( s, *v ); fc::raw::pack( s, bool(!!v), _max_depth - 1 );
if( !!v ) fc::raw::pack( s, *v, _max_depth - 1 );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, fc::optional<T>& v ) void unpack( Stream& s, fc::optional<T>& v, uint32_t _max_depth )
{ try { { try {
bool b; fc::raw::unpack( s, b ); FC_ASSERT( _max_depth > 0 );
if( b ) { v = T(); fc::raw::unpack( s, *v ); } bool b; fc::raw::unpack( s, b, _max_depth - 1 );
if( b ) { v = T(); fc::raw::unpack( s, *v, _max_depth - 1 ); }
} FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) }
// std::vector<char> // std::vector<char>
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) { template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
if( value.size() ) fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
s.write( &value.front(), (uint32_t)value.size() ); if( value.size() )
s.write( &value.front(), (uint32_t)value.size() );
} }
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) { template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value, uint32_t _max_depth ) {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
FC_ASSERT( size.value < MAX_ARRAY_ALLOC_SIZE ); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
value.resize(size.value); FC_ASSERT( size.value < MAX_ARRAY_ALLOC_SIZE );
if( value.size() ) value.resize(size.value);
s.read( value.data(), value.size() ); if( value.size() )
s.read( value.data(), value.size() );
} }
// fc::string // fc::string
template<typename Stream> inline void pack( Stream& s, const fc::string& v ) { template<typename Stream> inline void pack( Stream& s, const fc::string& v, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)v.size())); FC_ASSERT( _max_depth > 0 );
if( v.size() ) s.write( v.c_str(), v.size() ); fc::raw::pack( s, unsigned_int((uint32_t)v.size()), _max_depth - 1 );
if( v.size() ) s.write( v.c_str(), v.size() );
} }
template<typename Stream> inline void unpack( Stream& s, fc::string& v ) { template<typename Stream> inline void unpack( Stream& s, fc::string& v, uint32_t _max_depth ) {
std::vector<char> tmp; fc::raw::unpack(s,tmp); FC_ASSERT( _max_depth > 0 );
if( tmp.size() ) std::vector<char> tmp; fc::raw::unpack( s, tmp, _max_depth - 1 );
v = fc::string(tmp.data(),tmp.data()+tmp.size()); if( tmp.size() )
else v = fc::string(); v = fc::string( tmp.data(), tmp.data()+tmp.size() );
else v = fc::string();
} }
// bool // bool
template<typename Stream> inline void pack( Stream& s, const bool& v ) { fc::raw::pack( s, uint8_t(v) ); } template<typename Stream> inline void pack( Stream& s, const bool& v, uint32_t _max_depth )
template<typename Stream> inline void unpack( Stream& s, bool& v )
{ {
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, uint8_t(v), _max_depth - 1 );
}
template<typename Stream> inline void unpack( Stream& s, bool& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
uint8_t b; uint8_t b;
fc::raw::unpack( s, b ); fc::raw::unpack( s, b, _max_depth - 1 );
FC_ASSERT( (b & ~1) == 0 ); FC_ASSERT( (b & ~1) == 0 );
v=(b!=0); v=(b!=0);
} }
@ -269,49 +312,56 @@ namespace fc {
template<typename Stream, typename Class> template<typename Stream, typename Class>
struct pack_object_visitor { struct pack_object_visitor {
pack_object_visitor(const Class& _c, Stream& _s) pack_object_visitor( const Class& _c, Stream& _s, uint32_t _max_depth )
:c(_c),s(_s){} :c(_c),s(_s),max_depth(_max_depth)
{
FC_ASSERT( _max_depth > 0 );
}
template<typename T, typename C, T(C::*p)> template<typename T, typename C, T(C::*p)>
void operator()( const char* name )const { void operator()( const char* name )const {
fc::raw::pack( s, c.*p ); fc::raw::pack( s, c.*p, max_depth - 1 );
} }
private: private:
const Class& c; const Class& c;
Stream& s; Stream& s;
uint32_t max_depth;
}; };
template<typename Stream, typename Class> template<typename Stream, typename Class>
struct unpack_object_visitor { struct unpack_object_visitor {
unpack_object_visitor(Class& _c, Stream& _s) unpack_object_visitor( Class& _c, Stream& _s, uint32_t _max_depth ) : c(_c),s(_s),max_depth(_max_depth)
:c(_c),s(_s){} {
FC_ASSERT( _max_depth > 0 );
}
template<typename T, typename C, T(C::*p)> template<typename T, typename C, T(C::*p)>
inline void operator()( const char* name )const inline void operator()( const char* name )const
{ try { { try {
fc::raw::unpack( s, c.*p ); fc::raw::unpack( s, c.*p, max_depth - 1 );
} FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) } } FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }
private: private:
Class& c; Class& c;
Stream& s; Stream& s;
uint32_t max_depth;
}; };
template<typename IsClass=fc::true_type> template<typename IsClass=fc::true_type>
struct if_class{ struct if_class{
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { s << v; } static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) { s << v; }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { s >> v; } static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) { s >> v; }
}; };
template<> template<>
struct if_class<fc::false_type> { struct if_class<fc::false_type> {
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
s.write( (char*)&v, sizeof(v) ); s.write( (char*)&v, sizeof(v) );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
s.read( (char*)&v, sizeof(v) ); s.read( (char*)&v, sizeof(v) );
} }
}; };
@ -319,24 +369,28 @@ namespace fc {
template<typename IsEnum=fc::false_type> template<typename IsEnum=fc::false_type>
struct if_enum { struct if_enum {
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s ) ); FC_ASSERT( _max_depth > 0 );
fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
fc::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s ) ); FC_ASSERT( _max_depth > 0 );
fc::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
} }
}; };
template<> template<>
struct if_enum<fc::true_type> { struct if_enum<fc::true_type> {
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
fc::raw::pack(s, (int64_t)v); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, (int64_t)v, _max_depth - 1 );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
int64_t temp; int64_t temp;
fc::raw::unpack(s, temp); fc::raw::unpack( s, temp, _max_depth - 1 );
v = (T)temp; v = (T)temp;
} }
}; };
@ -344,283 +398,314 @@ namespace fc {
template<typename IsReflected=fc::false_type> template<typename IsReflected=fc::false_type>
struct if_reflected { struct if_reflected {
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
if_class<typename fc::is_class<T>::type>::pack(s,v); FC_ASSERT( _max_depth > 0 );
if_class<typename fc::is_class<T>::type>::pack( s, v, _max_depth - 1 );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
if_class<typename fc::is_class<T>::type>::unpack(s,v); FC_ASSERT( _max_depth > 0 );
if_class<typename fc::is_class<T>::type>::unpack( s, v, _max_depth - 1 );
} }
}; };
template<> template<>
struct if_reflected<fc::true_type> { struct if_reflected<fc::true_type> {
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) { static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
if_enum< typename fc::reflector<T>::is_enum >::pack(s,v); FC_ASSERT( _max_depth > 0 );
if_enum< typename fc::reflector<T>::is_enum >::pack( s, v, _max_depth - 1 );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v ) { static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
if_enum< typename fc::reflector<T>::is_enum >::unpack(s,v); FC_ASSERT( _max_depth > 0 );
if_enum< typename fc::reflector<T>::is_enum >::unpack( s, v, _max_depth - 1 );
} }
}; };
} // namesapce detail } // namesapce detail
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::unordered_set<T>& value ) { inline void pack( Stream& s, const std::unordered_set<T>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::unordered_set<T>& value ) { inline void unpack( Stream& s, std::unordered_set<T>& value, uint32_t _max_depth ) {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
value.clear(); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); value.clear();
value.reserve(size.value); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
for( uint32_t i = 0; i < size.value; ++i ) value.reserve(size.value);
{ for( uint32_t i = 0; i < size.value; ++i )
{
T tmp; T tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void pack( Stream& s, const std::pair<K,V>& value ) { inline void pack( Stream& s, const std::pair<K,V>& value, uint32_t _max_depth ) {
fc::raw::pack( s, value.first ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, value.second ); fc::raw::pack( s, value.first, _max_depth - 1 );
fc::raw::pack( s, value.second, _max_depth - 1 );
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void unpack( Stream& s, std::pair<K,V>& value ) inline void unpack( Stream& s, std::pair<K,V>& value, uint32_t _max_depth )
{ {
fc::raw::unpack( s, value.first ); FC_ASSERT( _max_depth > 0 );
fc::raw::unpack( s, value.second ); fc::raw::unpack( s, value.first, _max_depth - 1 );
fc::raw::unpack( s, value.second, _max_depth - 1 );
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void pack( Stream& s, const std::unordered_map<K,V>& value ) { inline void pack( Stream& s, const std::unordered_map<K,V>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void unpack( Stream& s, std::unordered_map<K,V>& value ) inline void unpack( Stream& s, std::unordered_map<K,V>& value, uint32_t _max_depth )
{ {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
value.clear(); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE ); value.clear();
value.reserve(size.value); FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
for( uint32_t i = 0; i < size.value; ++i ) value.reserve(size.value);
{ for( uint32_t i = 0; i < size.value; ++i )
{
std::pair<K,V> tmp; std::pair<K,V> tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void pack( Stream& s, const std::map<K,V>& value ) { inline void pack( Stream& s, const std::map<K,V>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void unpack( Stream& s, std::map<K,V>& value ) inline void unpack( Stream& s, std::map<K,V>& value, uint32_t _max_depth )
{ {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
value.clear(); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE ); value.clear();
for( uint32_t i = 0; i < size.value; ++i ) FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
{ for( uint32_t i = 0; i < size.value; ++i )
{
std::pair<K,V> tmp; std::pair<K,V> tmp;
fc::raw::unpack( s, tmp ); fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::deque<T>& value ) { inline void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::deque<T>& value ) { inline void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth ) {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
value.resize(size.value); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
auto itr = value.begin(); value.resize(size.value);
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::unpack( s, *itr ); while( itr != end ) {
++itr; fc::raw::unpack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::vector<T>& value ) { inline void pack( Stream& s, const std::vector<T>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::vector<T>& value ) { inline void unpack( Stream& s, std::vector<T>& value, uint32_t _max_depth ) {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
value.resize(size.value); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
auto itr = value.begin(); value.resize(size.value);
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::unpack( s, *itr ); while( itr != end ) {
++itr; fc::raw::unpack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::set<T>& value ) { inline void pack( Stream& s, const std::set<T>& value, uint32_t _max_depth ) {
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) ); FC_ASSERT( _max_depth > 0 );
auto itr = value.begin(); fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto end = value.end(); auto itr = value.begin();
while( itr != end ) { auto end = value.end();
fc::raw::pack( s, *itr ); while( itr != end ) {
++itr; fc::raw::pack( s, *itr, _max_depth - 1 );
} ++itr;
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::set<T>& value ) { inline void unpack( Stream& s, std::set<T>& value, uint32_t _max_depth ) {
unsigned_int size; fc::raw::unpack( s, size ); FC_ASSERT( _max_depth > 0 );
for( uint64_t i = 0; i < size.value; ++i ) unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
{ for( uint64_t i = 0; i < size.value; ++i )
T tmp; {
fc::raw::unpack( s, tmp ); T tmp;
value.insert( std::move(tmp) ); fc::raw::unpack( s, tmp, _max_depth - 1 );
} value.insert( std::move(tmp) );
}
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const T& v ) { inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::pack(s,v); FC_ASSERT( _max_depth > 0 );
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::pack( s, v, _max_depth - 1 );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, T& v ) inline void unpack( Stream& s, T& v, uint32_t _max_depth )
{ try { { try {
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::unpack(s,v); FC_ASSERT( _max_depth > 0 );
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::unpack( s, v, _max_depth - 1 );
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename T> template<typename T>
inline size_t pack_size( const T& v ) inline size_t pack_size( const T& v )
{ {
datastream<size_t> ps; datastream<size_t> ps;
fc::raw::pack(ps,v ); fc::raw::pack( ps, v );
return ps.tellp(); return ps.tellp();
} }
template<typename T> template<typename T>
inline std::vector<char> pack( const T& v ) { inline std::vector<char> pack( const T& v, uint32_t _max_depth ) {
datastream<size_t> ps; FC_ASSERT( _max_depth > 0 );
fc::raw::pack(ps,v ); datastream<size_t> ps;
std::vector<char> vec(ps.tellp()); fc::raw::pack( ps, v, _max_depth - 1 );
std::vector<char> vec(ps.tellp());
if( vec.size() ) { if( vec.size() ) {
datastream<char*> ds( vec.data(), size_t(vec.size()) ); datastream<char*> ds( vec.data(), size_t(vec.size()) );
fc::raw::pack(ds,v); fc::raw::pack( ds, v, _max_depth - 1 );
} }
return vec; return vec;
} }
template<typename T, typename... Next> template<typename T, typename... Next>
inline std::vector<char> pack( const T& v, Next... next ) { inline std::vector<char> pack( const T& v, Next... next, uint32_t _max_depth ) {
datastream<size_t> ps; FC_ASSERT( _max_depth > 0 );
fc::raw::pack(ps,v,next...); datastream<size_t> ps;
std::vector<char> vec(ps.tellp()); fc::raw::pack( ps, v, next..., _max_depth - 1 );
std::vector<char> vec(ps.tellp());
if( vec.size() ) { if( vec.size() ) {
datastream<char*> ds( vec.data(), size_t(vec.size()) ); datastream<char*> ds( vec.data(), size_t(vec.size()) );
fc::raw::pack(ds,v,next...); fc::raw::pack( ds, v, next..., _max_depth - 1 );
} }
return vec; return vec;
} }
template<typename T> template<typename T>
inline T unpack( const std::vector<char>& s ) inline T unpack( const std::vector<char>& s, uint32_t _max_depth )
{ try { { try {
T tmp; FC_ASSERT( _max_depth > 0 );
if( s.size() ) { T tmp;
datastream<const char*> ds( s.data(), size_t(s.size()) ); if( s.size() ) {
fc::raw::unpack(ds,tmp); datastream<const char*> ds( s.data(), size_t(s.size()) );
} fc::raw::unpack( ds, tmp, _max_depth - 1 );
return tmp; }
return tmp;
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename T> template<typename T>
inline void unpack( const std::vector<char>& s, T& tmp ) inline void unpack( const std::vector<char>& s, T& tmp, uint32_t _max_depth )
{ try { { try {
if( s.size() ) { FC_ASSERT( _max_depth > 0 );
datastream<const char*> ds( s.data(), size_t(s.size()) ); if( s.size() ) {
fc::raw::unpack(ds,tmp); datastream<const char*> ds( s.data(), size_t(s.size()) );
} fc::raw::unpack( ds, tmp, _max_depth - 1 );
}
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename T> template<typename T>
inline void pack( char* d, uint32_t s, const T& v ) { inline void pack( char* d, uint32_t s, const T& v, uint32_t _max_depth ) {
datastream<char*> ds(d,s); FC_ASSERT( _max_depth > 0 );
fc::raw::pack(ds,v ); datastream<char*> ds(d,s);
fc::raw::pack( ds, v, _max_depth - 1 );
} }
template<typename T> template<typename T>
inline T unpack( const char* d, uint32_t s ) inline T unpack( const char* d, uint32_t s, uint32_t _max_depth )
{ try { { try {
T v; FC_ASSERT( _max_depth > 0 );
datastream<const char*> ds( d, s ); T v;
fc::raw::unpack(ds,v); datastream<const char*> ds( d, s );
return v; fc::raw::unpack( ds, v, _max_depth - 1 );
return v;
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename T> template<typename T>
inline void unpack( const char* d, uint32_t s, T& v ) inline void unpack( const char* d, uint32_t s, T& v, uint32_t _max_depth )
{ try { { try {
datastream<const char*> ds( d, s ); FC_ASSERT( _max_depth > 0 );
fc::raw::unpack(ds,v); datastream<const char*> ds( d, s );
return v; fc::raw::unpack( ds, v, _max_depth - 1 );
return v;
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) } } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename Stream> template<typename Stream>
struct pack_static_variant struct pack_static_variant
{ {
Stream& stream; Stream& stream;
pack_static_variant( Stream& s ):stream(s){} uint32_t max_depth;
pack_static_variant( Stream& s, uint32_t _max_depth ):stream(s),max_depth(_max_depth)
{
FC_ASSERT( _max_depth > 0 );
}
typedef void result_type; typedef void result_type;
template<typename T> void operator()( const T& v )const template<typename T> void operator()( const T& v )const
{ {
fc::raw::pack( stream, v ); fc::raw::pack( stream, v, max_depth - 1 );
} }
}; };
@ -628,29 +713,35 @@ namespace fc {
struct unpack_static_variant struct unpack_static_variant
{ {
Stream& stream; Stream& stream;
unpack_static_variant( Stream& s ):stream(s){} uint32_t max_depth;
unpack_static_variant( Stream& s, uint32_t _max_depth ) : stream(s),max_depth(_max_depth)
{
FC_ASSERT( _max_depth > 0 );
}
typedef void result_type; typedef void result_type;
template<typename T> void operator()( T& v )const template<typename T> void operator()( T& v )const
{ {
fc::raw::unpack( stream, v ); fc::raw::unpack( stream, v, max_depth - 1 );
} }
}; };
template<typename Stream, typename... T> template<typename Stream, typename... T>
void pack( Stream& s, const static_variant<T...>& sv ) void pack( Stream& s, const static_variant<T...>& sv, uint32_t _max_depth )
{ {
fc::raw::pack( s, unsigned_int(sv.which()) ); FC_ASSERT( _max_depth > 0 );
sv.visit( pack_static_variant<Stream>(s) ); fc::raw::pack( s, unsigned_int(sv.which()), _max_depth - 1 );
sv.visit( pack_static_variant<Stream>( s, _max_depth - 1 ) );
} }
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv ) template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
unsigned_int w; unsigned_int w;
fc::raw::unpack( s, w ); fc::raw::unpack( s, w, _max_depth - 1 );
sv.set_which(w.value); sv.set_which(w.value);
sv.visit( unpack_static_variant<Stream>(s) ); sv.visit( unpack_static_variant<Stream>( s, _max_depth - 1 ) );
} }
} } // namespace fc::raw } } // namespace fc::raw

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <fc/config.hpp>
#include <fc/container/flat_fwd.hpp> #include <fc/container/flat_fwd.hpp>
#include <fc/container/deque_fwd.hpp> #include <fc/container/deque_fwd.hpp>
#include <fc/io/varint.hpp> #include <fc/io/varint.hpp>
@ -11,9 +12,9 @@
#include <unordered_map> #include <unordered_map>
#include <set> #include <set>
#define MAX_ARRAY_ALLOC_SIZE (1024*1024*10) #define MAX_ARRAY_ALLOC_SIZE (1024*1024*10)
namespace fc { namespace fc {
class time_point; class time_point;
class time_point_sec; class time_point_sec;
class variant; class variant;
@ -31,94 +32,94 @@ namespace fc {
template<typename T> template<typename T>
inline size_t pack_size( const T& v ); inline size_t pack_size( const T& v );
template<typename Stream, typename Storage> inline void pack( Stream& s, const fc::fixed_string<Storage>& u ); template<typename Stream, typename Storage> inline void pack( Stream& s, const fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename Storage> inline void unpack( Stream& s, fc::fixed_string<Storage>& u ); template<typename Stream, typename Storage> inline void unpack( Stream& s, fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename IntType, typename EnumType> template<typename Stream, typename IntType, typename EnumType>
inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp ); inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename IntType, typename EnumType> template<typename Stream, typename IntType, typename EnumType>
inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp ); inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const std::set<T>& value ); template<typename Stream, typename T> inline void pack( Stream& s, const std::set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, std::set<T>& value ); template<typename Stream, typename T> inline void unpack( Stream& s, std::set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const std::unordered_set<T>& value ); template<typename Stream, typename T> inline void pack( Stream& s, const std::unordered_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, std::unordered_set<T>& value ); template<typename Stream, typename T> inline void unpack( Stream& s, std::unordered_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename... T> void pack( Stream& s, const static_variant<T...>& sv ); template<typename Stream, typename... T> void pack( Stream& s, const static_variant<T...>& sv, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv ); template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const flat_set<T>& value ); //template<typename Stream, typename T> inline void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, flat_set<T>& value ); //template<typename Stream, typename T> inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const std::deque<T>& value ); //template<typename Stream, typename T> inline void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, std::deque<T>& value ); //template<typename Stream, typename T> inline void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::unordered_map<K,V>& value ); template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::unordered_map<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::unordered_map<K,V>& value ); template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::unordered_map<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::map<K,V>& value ); template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::map<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::map<K,V>& value ); template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::map<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename... V> inline void pack( Stream& s, const flat_map<K,V...>& value ); //template<typename Stream, typename K, typename... V> inline void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V, typename... A> inline void unpack( Stream& s, flat_map<K,V,A...>& value ); //template<typename Stream, typename K, typename V, typename... A> inline void unpack( Stream& s, flat_map<K,V,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::pair<K,V>& value ); template<typename Stream, typename K, typename V> inline void pack( Stream& s, const std::pair<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::pair<K,V>& value ); template<typename Stream, typename K, typename V> inline void unpack( Stream& s, std::pair<K,V>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const variant_object& v ); template<typename Stream> inline void pack( Stream& s, const variant_object& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, variant_object& v ); template<typename Stream> inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const variant& v ); template<typename Stream> inline void pack( Stream& s, const variant& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, variant& v ); template<typename Stream> inline void unpack( Stream& s, variant& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const path& v ); template<typename Stream> inline void pack( Stream& s, const path& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, path& v ); template<typename Stream> inline void unpack( Stream& s, path& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const ip::endpoint& v ); template<typename Stream> inline void pack( Stream& s, const ip::endpoint& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, ip::endpoint& v ); template<typename Stream> inline void unpack( Stream& s, ip::endpoint& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> void unpack( Stream& s, fc::optional<T>& v ); template<typename Stream, typename T> void unpack( Stream& s, fc::optional<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> void unpack( Stream& s, const T& v ); template<typename Stream, typename T> void unpack( Stream& s, const T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> void pack( Stream& s, const fc::optional<T>& v ); template<typename Stream, typename T> void pack( Stream& s, const fc::optional<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> void pack( Stream& s, const safe<T>& v ); template<typename Stream, typename T> void pack( Stream& s, const safe<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> void unpack( Stream& s, fc::safe<T>& v ); template<typename Stream, typename T> void unpack( Stream& s, fc::safe<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void unpack( Stream& s, time_point& ); template<typename Stream> void unpack( Stream& s, time_point&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void pack( Stream& s, const time_point& ); template<typename Stream> void pack( Stream& s, const time_point&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void unpack( Stream& s, time_point_sec& ); template<typename Stream> void unpack( Stream& s, time_point_sec&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void pack( Stream& s, const time_point_sec& ); template<typename Stream> void pack( Stream& s, const time_point_sec&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void unpack( Stream& s, std::string& ); template<typename Stream> void unpack( Stream& s, std::string&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void pack( Stream& s, const std::string& ); template<typename Stream> void pack( Stream& s, const std::string&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void unpack( Stream& s, fc::ecc::public_key& ); template<typename Stream> void unpack( Stream& s, fc::ecc::public_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void pack( Stream& s, const fc::ecc::public_key& ); template<typename Stream> void pack( Stream& s, const fc::ecc::public_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void unpack( Stream& s, fc::ecc::private_key& ); template<typename Stream> void unpack( Stream& s, fc::ecc::private_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> void pack( Stream& s, const fc::ecc::private_key& ); template<typename Stream> void pack( Stream& s, const fc::ecc::private_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const T& v ); template<typename Stream, typename T> inline void pack( Stream& s, const T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, T& v ); template<typename Stream, typename T> inline void unpack( Stream& s, T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void pack( Stream& s, const std::vector<T>& v ); template<typename Stream, typename T> inline void pack( Stream& s, const std::vector<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T> inline void unpack( Stream& s, std::vector<T>& v ); template<typename Stream, typename T> inline void unpack( Stream& s, std::vector<T>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const signed_int& v ); template<typename Stream> inline void pack( Stream& s, const signed_int& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, signed_int& vi ); template<typename Stream> inline void unpack( Stream& s, signed_int& vi, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const unsigned_int& v ); template<typename Stream> inline void pack( Stream& s, const unsigned_int& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi ); template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const char* v ); template<typename Stream> inline void pack( Stream& s, const char* v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ); template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ); template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, size_t N> inline void pack( Stream& s, const fc::array<T,N>& v); template<typename Stream, typename T, size_t N> inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, size_t N> inline void unpack( Stream& s, fc::array<T,N>& v); template<typename Stream, typename T, size_t N> inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
template<typename Stream> inline void pack( Stream& s, const bool& v ); template<typename Stream> inline void pack( Stream& s, const bool& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, bool& v ); template<typename Stream> inline void unpack( Stream& s, bool& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename T> inline std::vector<char> pack( const T& v ); template<typename T> inline std::vector<char> pack( const T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename T> inline T unpack( const std::vector<char>& s ); template<typename T> inline T unpack( const std::vector<char>& s, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename T> inline T unpack( const char* d, uint32_t s ); template<typename T> inline T unpack( const char* d, uint32_t s, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename T> inline void unpack( const char* d, uint32_t s, T& v ); template<typename T> inline void unpack( const char* d, uint32_t s, T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
} } } }

View file

@ -10,53 +10,59 @@ namespace fc { namespace raw {
class variant_packer : public variant::visitor class variant_packer : public variant::visitor
{ {
public: public:
variant_packer( Stream& _s ):s(_s){} variant_packer( Stream& _s, uint32_t _max_depth ):s(_s),max_depth(_max_depth)
{
FC_ASSERT( _max_depth > 0 );
}
virtual void handle()const { } virtual void handle()const { }
virtual void handle( const int64_t& v )const virtual void handle( const int64_t& v )const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const uint64_t& v )const virtual void handle( const uint64_t& v )const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const double& v )const virtual void handle( const double& v )const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const bool& v )const virtual void handle( const bool& v )const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const string& v )const virtual void handle( const string& v )const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const variant_object& v)const virtual void handle( const variant_object& v)const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
virtual void handle( const variants& v)const virtual void handle( const variants& v)const
{ {
fc::raw::pack( s, v ); fc::raw::pack( s, v, max_depth - 1 );
} }
Stream& s; Stream& s;
uint32_t max_depth;
}; };
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const variant& v ) inline void pack( Stream& s, const variant& v, uint32_t _max_depth )
{ {
pack( s, uint8_t(v.get_type()) ); FC_ASSERT( _max_depth > 0 );
v.visit( variant_packer<Stream>(s) ); pack( s, uint8_t(v.get_type()), _max_depth - 1 );
v.visit( variant_packer<Stream>( s, _max_depth - 1 ) );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, variant& v ) inline void unpack( Stream& s, variant& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
uint8_t t; uint8_t t;
unpack( s, t ); unpack( s, t, _max_depth - 1 );
switch( t ) switch( t )
{ {
case variant::null_type: case variant::null_type:
@ -64,49 +70,49 @@ namespace fc { namespace raw {
case variant::int64_type: case variant::int64_type:
{ {
int64_t val; int64_t val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = val; v = val;
return; return;
} }
case variant::uint64_type: case variant::uint64_type:
{ {
uint64_t val; uint64_t val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = val; v = val;
return; return;
} }
case variant::double_type: case variant::double_type:
{ {
double val; double val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = val; v = val;
return; return;
} }
case variant::bool_type: case variant::bool_type:
{ {
bool val; bool val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = val; v = val;
return; return;
} }
case variant::string_type: case variant::string_type:
{ {
fc::string val; fc::string val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = fc::move(val); v = fc::move(val);
return; return;
} }
case variant::array_type: case variant::array_type:
{ {
variants val; variants val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = fc::move(val); v = fc::move(val);
return; return;
} }
case variant::object_type: case variant::object_type:
{ {
variant_object val; variant_object val;
raw::unpack(s,val); raw::unpack( s, val, _max_depth - 1 );
v = fc::move(val); v = fc::move(val);
return; return;
} }
@ -115,22 +121,24 @@ namespace fc { namespace raw {
} }
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const variant_object& v ) inline void pack( Stream& s, const variant_object& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
unsigned_int vs = (uint32_t)v.size(); unsigned_int vs = (uint32_t)v.size();
pack( s, vs ); pack( s, vs, _max_depth - 1 );
for( auto itr = v.begin(); itr != v.end(); ++itr ) for( auto itr = v.begin(); itr != v.end(); ++itr )
{ {
pack( s, itr->key() ); pack( s, itr->key(), _max_depth - 1 );
pack( s, itr->value() ); pack( s, itr->value(), _max_depth - 1 );
} }
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, variant_object& v ) inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
unsigned_int vs; unsigned_int vs;
unpack( s, vs ); unpack( s, vs, _max_depth - 1 );
mutable_variant_object mvo; mutable_variant_object mvo;
mvo.reserve(vs.value); mvo.reserve(vs.value);
@ -138,8 +146,8 @@ namespace fc { namespace raw {
{ {
fc::string key; fc::string key;
fc::variant value; fc::variant value;
fc::raw::unpack(s,key); fc::raw::unpack( s, key, _max_depth - 1 );
fc::raw::unpack(s,value); fc::raw::unpack( s, value, _max_depth - 1 );
mvo.set( fc::move(key), fc::move(value) ); mvo.set( fc::move(key), fc::move(value) );
} }
v = fc::move(mvo); v = fc::move(mvo);

View file

@ -40,7 +40,7 @@ namespace fc {
private: private:
uint32_t _ip; uint32_t _ip;
}; };
class endpoint { class endpoint {
public: public:
endpoint(); endpoint();
@ -58,16 +58,16 @@ namespace fc {
friend bool operator==( const endpoint& a, const endpoint& b ); friend bool operator==( const endpoint& a, const endpoint& b );
friend bool operator!=( const endpoint& a, const endpoint& b ); friend bool operator!=( const endpoint& a, const endpoint& b );
friend bool operator< ( const endpoint& a, const endpoint& b ); friend bool operator< ( const endpoint& a, const endpoint& b );
private: private:
/** /**
* The compiler pads endpoint to a full 8 bytes, so while * The compiler pads endpoint to a full 8 bytes, so while
* a port number is limited in range to 16 bits, we specify * a port number is limited in range to 16 bits, we specify
* a full 32 bits so that memcmp can be used with sizeof(), * a full 32 bits so that memcmp can be used with sizeof(),
* otherwise 2 bytes will be 'random' and you do not know * otherwise 2 bytes will be 'random' and you do not know
* where they are stored. * where they are stored.
*/ */
uint32_t _port; uint32_t _port;
address _ip; address _ip;
}; };
@ -80,41 +80,45 @@ namespace fc {
void from_variant( const variant& var, ip::address& vo ); void from_variant( const variant& var, ip::address& vo );
namespace raw namespace raw
{ {
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const ip::address& v ) inline void pack( Stream& s, const ip::address& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
fc::raw::pack( s, uint32_t(v) ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, uint32_t(v), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, ip::address& v ) inline void unpack( Stream& s, ip::address& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ {
FC_ASSERT( _max_depth > 0 );
uint32_t _ip; uint32_t _ip;
fc::raw::unpack( s, _ip ); fc::raw::unpack( s, _ip, _max_depth - 1 );
v = ip::address(_ip); v = ip::address(_ip);
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const ip::endpoint& v ) inline void pack( Stream& s, const ip::endpoint& v, uint32_t _max_depth )
{ {
fc::raw::pack( s, v.get_address() ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, v.port() ); fc::raw::pack( s, v.get_address(), _max_depth - 1 );
fc::raw::pack( s, v.port(), _max_depth - 1 );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, ip::endpoint& v ) inline void unpack( Stream& s, ip::endpoint& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 );
ip::address a; ip::address a;
uint16_t p; uint16_t p;
fc::raw::unpack( s, a ); fc::raw::unpack( s, a, _max_depth - 1 );
fc::raw::unpack( s, p ); fc::raw::unpack( s, p, _max_depth - 1 );
v = ip::endpoint(a,p); v = ip::endpoint(a,p);
} }
} }
} // namespace fc } // namespace fc
FC_REFLECT_TYPENAME( fc::ip::address ) FC_REFLECT_TYPENAME( fc::ip::address )
FC_REFLECT_TYPENAME( fc::ip::endpoint ) FC_REFLECT_TYPENAME( fc::ip::endpoint )
namespace std namespace std
{ {
template<> template<>

View file

@ -1,5 +1,5 @@
#pragma once #pragma once
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#define FC_REAL128_PRECISION (uint64_t(1000000) * uint64_t(1000000) * uint64_t(1000000)) #define FC_REAL128_PRECISION (uint64_t(1000000) * uint64_t(1000000) * uint64_t(1000000))
@ -27,7 +27,7 @@ namespace fc {
real128& operator -= ( const real128& o ); real128& operator -= ( const real128& o );
real128& operator /= ( const real128& o ); real128& operator /= ( const real128& o );
real128& operator *= ( const real128& o ); real128& operator *= ( const real128& o );
static real128 from_fixed( const uint128& fixed ); static real128 from_fixed( const uint128& fixed );
uint64_t to_uint64()const; uint64_t to_uint64()const;
@ -39,12 +39,15 @@ namespace fc {
void to_variant( const real128& var, variant& vo ); void to_variant( const real128& var, variant& vo );
void from_variant( const variant& var, real128& vo ); void from_variant( const variant& var, real128& vo );
namespace raw namespace raw
{ {
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const real128& value_to_pack ) { s.write( (char*)&value_to_pack, sizeof(value_to_pack) ); } inline void pack( Stream& s, const real128& value_to_pack, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ s.write( (char*)&value_to_pack, sizeof(value_to_pack) ); }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, real128& value_to_unpack ) { s.read( (char*)&value_to_unpack, sizeof(value_to_unpack) ); } inline void unpack( Stream& s, real128& value_to_unpack, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ s.read( (char*)&value_to_unpack, sizeof(value_to_unpack) ); }
} }

View file

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <fc/config.hpp>
#include <fc/exception/exception.hpp> #include <fc/exception/exception.hpp>
#include <fc/crypto/city.hpp> #include <fc/crypto/city.hpp>
@ -126,9 +127,9 @@ namespace fc
namespace raw namespace raw
{ {
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const uint128& u ) { s.write( (char*)&u, sizeof(u) ); } inline void pack( Stream& s, const uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.write( (char*)&u, sizeof(u) ); }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, uint128& u ) { s.read( (char*)&u, sizeof(u) ); } inline void unpack( Stream& s, uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.read( (char*)&u, sizeof(u) ); }
} }
size_t city_hash_size_t(const char *buf, size_t len); size_t city_hash_size_t(const char *buf, size_t len);