Slightly improve performance for pack/unpack

This commit is contained in:
abitmore 2018-03-13 13:03:37 -04:00
parent 86e18663a0
commit 43ac0b0520
5 changed files with 148 additions and 111 deletions

View file

@ -10,36 +10,39 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth ) { inline void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth ) { inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; unpack( s, size, _max_depth );
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, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
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, uint32_t _max_depth ) { inline void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -47,14 +50,15 @@ namespace fc {
inline void unpack( Stream& s, flat_map<K,V,A...>& value, uint32_t _max_depth ) inline void unpack( Stream& s, flat_map<K,V,A...>& value, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; unpack( s, size, _max_depth );
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, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
@ -62,12 +66,13 @@ namespace fc {
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth ) { void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} else { } else {
@ -78,12 +83,13 @@ 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, uint32_t _max_depth ) { void unpack( Stream& s, bip::vector<T,A>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int size; unsigned_int size;
unpack( s, size, _max_depth - 1 ); unpack( s, size, _max_depth );
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, _max_depth - 1 ); unpack( s, item, _max_depth );
} else { } else {
s.read( (char*)value.data(), value.size() ); s.read( (char*)value.data(), value.size() );
} }

View file

@ -124,22 +124,24 @@ namespace fc {
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, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { inline void pack( Stream& s, const bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++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, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { inline void unpack( Stream& s, bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int size; unsigned_int size;
unpack( s, size, _max_depth - 1 ); unpack( s, size, _max_depth );
value.clear(); value.resize(size); value.clear(); value.resize(size);
for( auto& item : value ) for( auto& item : value )
fc::raw::unpack( s, item, _max_depth - 1 ); fc::raw::unpack( s, item, _max_depth );
} }
} }
} }

View file

@ -21,31 +21,34 @@ namespace fc {
template<typename Stream, typename Arg0, typename... Args> template<typename Stream, typename Arg0, typename... Args>
inline void pack( Stream& s, const Arg0& a0, Args... args, uint32_t _max_depth ) { inline void pack( Stream& s, const Arg0& a0, Args... args, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, a0, _max_depth - 1 ); --_max_depth;
pack( s, args..., _max_depth - 1 ); pack( s, a0, _max_depth );
pack( s, args..., _max_depth );
} }
template<typename Stream> template<typename Stream>
inline void pack( Stream& s, const fc::exception& e, uint32_t _max_depth ) inline void pack( Stream& s, const fc::exception& e, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, e.code(), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, std::string(e.name()), _max_depth - 1 ); fc::raw::pack( s, e.code(), _max_depth );
fc::raw::pack( s, std::string(e.what()), _max_depth - 1 ); fc::raw::pack( s, std::string(e.name()), _max_depth );
fc::raw::pack( s, e.get_log(), _max_depth - 1 ); fc::raw::pack( s, std::string(e.what()), _max_depth );
fc::raw::pack( s, e.get_log(), _max_depth );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::exception& e, uint32_t _max_depth ) inline void unpack( Stream& s, fc::exception& e, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
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, _max_depth - 1 ); fc::raw::unpack( s, code, _max_depth );
fc::raw::unpack( s, name, _max_depth - 1 ); fc::raw::unpack( s, name, _max_depth );
fc::raw::unpack( s, what, _max_depth - 1 ); fc::raw::unpack( s, what, _max_depth );
fc::raw::unpack( s, msgs, _max_depth - 1 ); fc::raw::unpack( s, msgs, _max_depth );
e = fc::exception( fc::move(msgs), code, name, what ); e = fc::exception( fc::move(msgs), code, name, what );
} }
@ -54,7 +57,7 @@ namespace fc {
inline void pack( Stream& s, const fc::log_message& msg, uint32_t _max_depth ) inline void pack( Stream& s, const fc::log_message& msg, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, variant(msg), _max_depth - 1 ); fc::raw::pack( s, variant(msg), _max_depth - 1 ); // TODO check variant depth?
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, fc::log_message& msg, uint32_t _max_depth ) inline void unpack( Stream& s, fc::log_message& msg, uint32_t _max_depth )
@ -62,7 +65,7 @@ namespace fc {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::variant vmsg; fc::variant vmsg;
fc::raw::unpack( s, vmsg, _max_depth - 1 ); fc::raw::unpack( s, vmsg, _max_depth - 1 );
msg = vmsg.as<log_message>(); msg = vmsg.as<log_message>(); // TODO check depth?
} }
template<typename Stream> template<typename Stream>
@ -250,16 +253,18 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
void pack( Stream& s, const fc::optional<T>& v, uint32_t _max_depth ) { void pack( Stream& s, const fc::optional<T>& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, bool(!!v), _max_depth - 1 ); --_max_depth;
if( !!v ) fc::raw::pack( s, *v, _max_depth - 1 ); fc::raw::pack( s, bool(!!v), _max_depth );
if( !!v ) fc::raw::pack( s, *v, _max_depth );
} }
template<typename Stream, typename T> template<typename Stream, typename T>
void unpack( Stream& s, fc::optional<T>& v, uint32_t _max_depth ) void unpack( Stream& s, fc::optional<T>& v, uint32_t _max_depth )
{ try { { try {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
bool b; fc::raw::unpack( s, b, _max_depth - 1 ); --_max_depth;
if( b ) { v = T(); fc::raw::unpack( s, *v, _max_depth - 1 ); } bool b; fc::raw::unpack( s, b, _max_depth );
if( b ) { v = T(); fc::raw::unpack( s, *v, _max_depth ); }
} 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>
@ -313,24 +318,24 @@ 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, uint32_t _max_depth ) pack_object_visitor( const Class& _c, Stream& _s, uint32_t _max_depth )
:c(_c),s(_s),max_depth(_max_depth) :c(_c),s(_s),max_depth(_max_depth - 1)
{ {
FC_ASSERT( _max_depth > 0 ); 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, max_depth - 1 ); fc::raw::pack( s, c.*p, max_depth );
} }
private: private:
const Class& c; const Class& c;
Stream& s; Stream& s;
uint32_t max_depth; const 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, uint32_t _max_depth ) : c(_c),s(_s),max_depth(_max_depth) unpack_object_visitor( Class& _c, Stream& _s, uint32_t _max_depth ) : c(_c),s(_s),max_depth(_max_depth - 1)
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
} }
@ -338,12 +343,12 @@ namespace fc {
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, max_depth - 1 ); fc::raw::unpack( s, c.*p, max_depth );
} 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; const uint32_t max_depth;
}; };
template<typename IsClass=fc::true_type> template<typename IsClass=fc::true_type>
@ -427,25 +432,27 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::unordered_set<T>& value, uint32_t _max_depth ) { inline void pack( Stream& s, const std::unordered_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::unordered_set<T>& value, uint32_t _max_depth ) { inline void unpack( Stream& s, std::unordered_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
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, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
@ -454,25 +461,28 @@ namespace fc {
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, uint32_t _max_depth ) { inline void pack( Stream& s, const std::pair<K,V>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, value.first, _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, value.second, _max_depth - 1 ); fc::raw::pack( s, value.first, _max_depth );
fc::raw::pack( s, value.second, _max_depth );
} }
template<typename Stream, typename K, typename V> template<typename Stream, typename K, typename V>
inline void unpack( Stream& s, std::pair<K,V>& value, uint32_t _max_depth ) inline void unpack( Stream& s, std::pair<K,V>& value, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::unpack( s, value.first, _max_depth - 1 ); --_max_depth;
fc::raw::unpack( s, value.second, _max_depth - 1 ); fc::raw::unpack( s, value.first, _max_depth );
fc::raw::unpack( s, value.second, _max_depth );
} }
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, uint32_t _max_depth ) { inline void pack( Stream& s, const std::unordered_map<K,V>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -480,25 +490,27 @@ namespace fc {
inline void unpack( Stream& s, std::unordered_map<K,V>& value, uint32_t _max_depth ) inline void unpack( Stream& s, std::unordered_map<K,V>& value, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
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, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
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, uint32_t _max_depth ) { inline void pack( Stream& s, const std::map<K,V>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -506,13 +518,14 @@ namespace fc {
inline void unpack( Stream& s, std::map<K,V>& value, uint32_t _max_depth ) inline void unpack( Stream& s, std::map<K,V>& value, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
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 );
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, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
@ -520,11 +533,12 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth ) { inline void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -532,13 +546,14 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth ) { inline void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
value.resize(size.value); value.resize(size.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::unpack( s, *itr, _max_depth - 1 ); fc::raw::unpack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -546,11 +561,12 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::vector<T>& value, uint32_t _max_depth ) { inline void pack( Stream& s, const std::vector<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -558,13 +574,14 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::vector<T>& value, uint32_t _max_depth ) { inline void unpack( Stream& s, std::vector<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE ); FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
value.resize(size.value); value.resize(size.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::unpack( s, *itr, _max_depth - 1 ); fc::raw::unpack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -572,11 +589,12 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void pack( Stream& s, const std::set<T>& value, uint32_t _max_depth ) { inline void pack( Stream& s, const std::set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
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, _max_depth - 1 ); fc::raw::pack( s, *itr, _max_depth );
++itr; ++itr;
} }
} }
@ -584,11 +602,12 @@ namespace fc {
template<typename Stream, typename T> template<typename Stream, typename T>
inline void unpack( Stream& s, std::set<T>& value, uint32_t _max_depth ) { inline void unpack( Stream& s, std::set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 ); --_max_depth;
unsigned_int size; fc::raw::unpack( s, size, _max_depth );
for( uint64_t i = 0; i < size.value; ++i ) for( uint64_t i = 0; i < size.value; ++i )
{ {
T tmp; T tmp;
fc::raw::unpack( s, tmp, _max_depth - 1 ); fc::raw::unpack( s, tmp, _max_depth );
value.insert( std::move(tmp) ); value.insert( std::move(tmp) );
} }
} }
@ -618,13 +637,14 @@ namespace fc {
template<typename T> template<typename T>
inline std::vector<char> pack( const T& v, uint32_t _max_depth ) { inline std::vector<char> pack( const T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
datastream<size_t> ps; datastream<size_t> ps;
fc::raw::pack( ps, v, _max_depth - 1 ); fc::raw::pack( ps, v, _max_depth );
std::vector<char> vec(ps.tellp()); 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, _max_depth - 1 ); fc::raw::pack( ds, v, _max_depth );
} }
return vec; return vec;
} }
@ -632,13 +652,14 @@ namespace fc {
template<typename T, typename... Next> template<typename T, typename... Next>
inline std::vector<char> pack( const T& v, Next... next, uint32_t _max_depth ) { inline std::vector<char> pack( const T& v, Next... next, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
datastream<size_t> ps; datastream<size_t> ps;
fc::raw::pack( ps, v, next..., _max_depth - 1 ); fc::raw::pack( ps, v, next..., _max_depth );
std::vector<char> vec(ps.tellp()); 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..., _max_depth - 1 ); fc::raw::pack( ds, v, next..., _max_depth );
} }
return vec; return vec;
} }
@ -696,8 +717,8 @@ namespace fc {
struct pack_static_variant struct pack_static_variant
{ {
Stream& stream; Stream& stream;
uint32_t max_depth; const uint32_t max_depth;
pack_static_variant( Stream& s, uint32_t _max_depth ):stream(s),max_depth(_max_depth) pack_static_variant( Stream& s, uint32_t _max_depth ):stream(s),max_depth(_max_depth - 1)
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
} }
@ -705,7 +726,7 @@ namespace fc {
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, max_depth - 1 ); fc::raw::pack( stream, v, max_depth );
} }
}; };
@ -713,8 +734,8 @@ namespace fc {
struct unpack_static_variant struct unpack_static_variant
{ {
Stream& stream; Stream& stream;
uint32_t max_depth; const uint32_t max_depth;
unpack_static_variant( Stream& s, uint32_t _max_depth ) : stream(s),max_depth(_max_depth) unpack_static_variant( Stream& s, uint32_t _max_depth ) : stream(s),max_depth(_max_depth - 1)
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
} }
@ -722,7 +743,7 @@ namespace fc {
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, max_depth - 1 ); fc::raw::unpack( stream, v, max_depth );
} }
}; };
@ -731,17 +752,19 @@ namespace fc {
void pack( Stream& s, const static_variant<T...>& sv, uint32_t _max_depth ) void pack( Stream& s, const static_variant<T...>& sv, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, unsigned_int(sv.which()), _max_depth - 1 ); --_max_depth;
sv.visit( pack_static_variant<Stream>( s, _max_depth - 1 ) ); fc::raw::pack( s, unsigned_int(sv.which()), _max_depth );
sv.visit( pack_static_variant<Stream>( s, _max_depth ) );
} }
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv, uint32_t _max_depth ) template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int w; unsigned_int w;
fc::raw::unpack( s, w, _max_depth - 1 ); fc::raw::unpack( s, w, _max_depth );
sv.set_which(w.value); sv.set_which(w.value);
sv.visit( unpack_static_variant<Stream>( s, _max_depth - 1 ) ); sv.visit( unpack_static_variant<Stream>( s, _max_depth ) );
} }
} } // namespace fc::raw } } // namespace fc::raw

View file

@ -10,42 +10,42 @@ namespace fc { namespace raw {
class variant_packer : public variant::visitor class variant_packer : public variant::visitor
{ {
public: public:
variant_packer( Stream& _s, uint32_t _max_depth ):s(_s),max_depth(_max_depth) variant_packer( Stream& _s, uint32_t _max_depth ):s(_s),max_depth(_max_depth - 1)
{ {
FC_ASSERT( _max_depth > 0 ); 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, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const uint64_t& v )const virtual void handle( const uint64_t& v )const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const double& v )const virtual void handle( const double& v )const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const bool& v )const virtual void handle( const bool& v )const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const string& v )const virtual void handle( const string& v )const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const variant_object& v)const virtual void handle( const variant_object& v)const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
virtual void handle( const variants& v)const virtual void handle( const variants& v)const
{ {
fc::raw::pack( s, v, max_depth - 1 ); fc::raw::pack( s, v, max_depth );
} }
Stream& s; Stream& s;
uint32_t max_depth; const uint32_t max_depth;
}; };
@ -54,15 +54,17 @@ namespace fc { namespace raw {
inline void pack( Stream& s, const variant& v, uint32_t _max_depth ) inline void pack( Stream& s, const variant& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
pack( s, uint8_t(v.get_type()), _max_depth - 1 ); --_max_depth;
v.visit( variant_packer<Stream>( s, _max_depth - 1 ) ); pack( s, uint8_t(v.get_type()), _max_depth );
v.visit( variant_packer<Stream>( s, _max_depth ) );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, variant& v, uint32_t _max_depth ) inline void unpack( Stream& s, variant& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
uint8_t t; uint8_t t;
unpack( s, t, _max_depth - 1 ); unpack( s, t, _max_depth );
switch( t ) switch( t )
{ {
case variant::null_type: case variant::null_type:
@ -70,49 +72,49 @@ namespace fc { namespace raw {
case variant::int64_type: case variant::int64_type:
{ {
int64_t val; int64_t val;
raw::unpack( s, val, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
v = val; v = val;
return; return;
} }
case variant::uint64_type: case variant::uint64_type:
{ {
uint64_t val; uint64_t val;
raw::unpack( s, val, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
v = val; v = val;
return; return;
} }
case variant::double_type: case variant::double_type:
{ {
double val; double val;
raw::unpack( s, val, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
v = val; v = val;
return; return;
} }
case variant::bool_type: case variant::bool_type:
{ {
bool val; bool val;
raw::unpack( s, val, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
v = val; v = val;
return; return;
} }
case variant::string_type: case variant::string_type:
{ {
fc::string val; fc::string val;
raw::unpack( s, val, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
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, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
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, _max_depth - 1 ); raw::unpack( s, val, _max_depth );
v = fc::move(val); v = fc::move(val);
return; return;
} }
@ -125,20 +127,22 @@ namespace fc { namespace raw {
inline void pack( Stream& s, const variant_object& v, uint32_t _max_depth ) inline void pack( Stream& s, const variant_object& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int vs = (uint32_t)v.size(); unsigned_int vs = (uint32_t)v.size();
pack( s, vs, _max_depth - 1 ); pack( s, vs, _max_depth );
for( auto itr = v.begin(); itr != v.end(); ++itr ) for( auto itr = v.begin(); itr != v.end(); ++itr )
{ {
pack( s, itr->key(), _max_depth - 1 ); pack( s, itr->key(), _max_depth );
pack( s, itr->value(), _max_depth - 1 ); pack( s, itr->value(), _max_depth );
} }
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth ) inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int vs; unsigned_int vs;
unpack( s, vs, _max_depth - 1 ); unpack( s, vs, _max_depth );
mutable_variant_object mvo; mutable_variant_object mvo;
mvo.reserve(vs.value); mvo.reserve(vs.value);
@ -146,8 +150,8 @@ namespace fc { namespace raw {
{ {
fc::string key; fc::string key;
fc::variant value; fc::variant value;
fc::raw::unpack( s, key, _max_depth - 1 ); fc::raw::unpack( s, key, _max_depth );
fc::raw::unpack( s, value, _max_depth - 1 ); fc::raw::unpack( s, value, _max_depth );
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

@ -101,17 +101,19 @@ namespace fc {
inline void pack( Stream& s, const ip::endpoint& v, uint32_t _max_depth ) inline void pack( Stream& s, const ip::endpoint& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, v.get_address(), _max_depth - 1 ); --_max_depth;
fc::raw::pack( s, v.port(), _max_depth - 1 ); fc::raw::pack( s, v.get_address(), _max_depth );
fc::raw::pack( s, v.port(), _max_depth );
} }
template<typename Stream> template<typename Stream>
inline void unpack( Stream& s, ip::endpoint& v, uint32_t _max_depth ) inline void unpack( Stream& s, ip::endpoint& v, uint32_t _max_depth )
{ {
FC_ASSERT( _max_depth > 0 ); FC_ASSERT( _max_depth > 0 );
--_max_depth;
ip::address a; ip::address a;
uint16_t p; uint16_t p;
fc::raw::unpack( s, a, _max_depth - 1 ); fc::raw::unpack( s, a, _max_depth );
fc::raw::unpack( s, p, _max_depth - 1 ); fc::raw::unpack( s, p, _max_depth );
v = ip::endpoint(a,p); v = ip::endpoint(a,p);
} }