Merge pull request #20 from abitmore/fix-serialization
Fix pack/unpack serialization
This commit is contained in:
parent
838da0d8dd
commit
10a857ee78
17 changed files with 760 additions and 479 deletions
4
include/fc/config.hpp
Normal file
4
include/fc/config.hpp
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -8,61 +8,71 @@
|
||||||
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 );
|
||||||
|
--_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 );
|
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 ) {
|
inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth ) {
|
||||||
unsigned_int size; unpack( s, size );
|
FC_ASSERT( _max_depth > 0 );
|
||||||
|
--_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 );
|
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 ) {
|
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 );
|
||||||
|
--_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 );
|
fc::raw::pack( s, *itr, _max_depth );
|
||||||
++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 );
|
||||||
|
--_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 );
|
fc::raw::unpack( s, tmp, _max_depth );
|
||||||
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 );
|
||||||
|
--_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 );
|
fc::raw::pack( s, *itr, _max_depth );
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -71,13 +81,15 @@ 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 );
|
||||||
|
--_max_depth;
|
||||||
unsigned_int size;
|
unsigned_int size;
|
||||||
unpack( s, size );
|
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 );
|
unpack( s, item, _max_depth );
|
||||||
} else {
|
} else {
|
||||||
s.read( (char*)value.data(), value.size() );
|
s.read( (char*)value.data(), value.size() );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#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
|
||||||
|
|
|
||||||
|
|
@ -238,31 +238,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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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) );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -122,22 +122,26 @@ 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();
|
--_max_depth;
|
||||||
auto end = value.end();
|
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
|
||||||
while( itr != end ) {
|
auto itr = value.begin();
|
||||||
fc::raw::pack( s, *itr );
|
auto end = value.end();
|
||||||
++itr;
|
while( itr != end ) {
|
||||||
}
|
fc::raw::pack( s, *itr, _max_depth );
|
||||||
|
++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 );
|
--_max_depth;
|
||||||
value.clear(); value.resize(size);
|
unsigned_int size;
|
||||||
for( auto& item : value )
|
unpack( s, size, _max_depth );
|
||||||
fc::raw::unpack( s, item );
|
value.clear(); value.resize(size);
|
||||||
|
for( auto& item : value )
|
||||||
|
fc::raw::unpack( s, item, _max_depth );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,16 +63,18 @@ namespace fc
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -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>
|
||||||
|
|
@ -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 );
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -10,53 +10,61 @@ 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 - 1)
|
||||||
|
{
|
||||||
|
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream& s;
|
Stream& s;
|
||||||
|
const 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) );
|
--_max_depth;
|
||||||
|
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 )
|
inline void unpack( Stream& s, variant& v, uint32_t _max_depth )
|
||||||
{
|
{
|
||||||
|
FC_ASSERT( _max_depth > 0 );
|
||||||
|
--_max_depth;
|
||||||
uint8_t t;
|
uint8_t t;
|
||||||
unpack( s, t );
|
unpack( s, t, _max_depth );
|
||||||
switch( t )
|
switch( t )
|
||||||
{
|
{
|
||||||
case variant::null_type:
|
case variant::null_type:
|
||||||
|
|
@ -64,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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
raw::unpack( s, val, _max_depth );
|
||||||
v = fc::move(val);
|
v = fc::move(val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -116,21 +124,25 @@ 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 );
|
||||||
|
--_max_depth;
|
||||||
unsigned_int vs = (uint32_t)v.size();
|
unsigned_int vs = (uint32_t)v.size();
|
||||||
pack( s, vs );
|
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() );
|
pack( s, itr->key(), _max_depth );
|
||||||
pack( s, itr->value() );
|
pack( s, itr->value(), _max_depth );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 );
|
||||||
|
--_max_depth;
|
||||||
unsigned_int vs;
|
unsigned_int vs;
|
||||||
unpack( s, vs );
|
unpack( s, vs, _max_depth );
|
||||||
|
|
||||||
mutable_variant_object mvo;
|
mutable_variant_object mvo;
|
||||||
mvo.reserve(vs.value);
|
mvo.reserve(vs.value);
|
||||||
|
|
@ -138,8 +150,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 );
|
||||||
fc::raw::unpack(s,value);
|
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);
|
||||||
|
|
|
||||||
|
|
@ -83,31 +83,37 @@ namespace fc {
|
||||||
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() );
|
--_max_depth;
|
||||||
|
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 )
|
inline void unpack( Stream& s, ip::endpoint& v, uint32_t _max_depth )
|
||||||
{
|
{
|
||||||
|
FC_ASSERT( _max_depth > 0 );
|
||||||
|
--_max_depth;
|
||||||
ip::address a;
|
ip::address a;
|
||||||
uint16_t p;
|
uint16_t p;
|
||||||
fc::raw::unpack( s, a );
|
fc::raw::unpack( s, a, _max_depth );
|
||||||
fc::raw::unpack( s, p );
|
fc::raw::unpack( s, p, _max_depth );
|
||||||
v = ip::endpoint(a,p);
|
v = ip::endpoint(a,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,12 @@ namespace fc {
|
||||||
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) ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ add_executable( all_tests all_tests.cpp
|
||||||
thread/thread_tests.cpp
|
thread/thread_tests.cpp
|
||||||
bloom_test.cpp
|
bloom_test.cpp
|
||||||
real128_test.cpp
|
real128_test.cpp
|
||||||
|
serialization_test.cpp
|
||||||
|
time_test.cpp
|
||||||
utf8_test.cpp
|
utf8_test.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries( all_tests fc )
|
target_link_libraries( all_tests fc )
|
||||||
|
|
|
||||||
108
tests/serialization_test.cpp
Normal file
108
tests/serialization_test.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <fc/log/logger.hpp>
|
||||||
|
|
||||||
|
#include <fc/container/flat.hpp>
|
||||||
|
#include <fc/io/raw.hpp>
|
||||||
|
|
||||||
|
namespace fc { namespace test {
|
||||||
|
|
||||||
|
struct item;
|
||||||
|
inline bool operator < ( const item& a, const item& b );
|
||||||
|
inline bool operator == ( const item& a, const item& b );
|
||||||
|
|
||||||
|
struct item_wrapper
|
||||||
|
{
|
||||||
|
item_wrapper() {}
|
||||||
|
item_wrapper(item&& it) { v.reserve(1); v.insert( it ); }
|
||||||
|
boost::container::flat_set<struct item> v;
|
||||||
|
};
|
||||||
|
inline bool operator < ( const item_wrapper& a, const item_wrapper& b );
|
||||||
|
inline bool operator == ( const item_wrapper& a, const item_wrapper& b );
|
||||||
|
|
||||||
|
struct item
|
||||||
|
{
|
||||||
|
item(int32_t lvl = 0) : level(lvl) {}
|
||||||
|
item(item_wrapper&& wp, int32_t lvl = 0) : level(lvl), w(wp) {}
|
||||||
|
int32_t level;
|
||||||
|
item_wrapper w;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator == ( const item& a, const item& b )
|
||||||
|
{ return ( std::tie( a.level, a.w ) == std::tie( b.level, b.w ) ); }
|
||||||
|
|
||||||
|
inline bool operator < ( const item& a, const item& b )
|
||||||
|
{ return ( std::tie( a.level, a.w ) < std::tie( b.level, b.w ) ); }
|
||||||
|
|
||||||
|
inline bool operator == ( const item_wrapper& a, const item_wrapper& b )
|
||||||
|
{ return ( std::tie( a.v ) == std::tie( b.v ) ); }
|
||||||
|
|
||||||
|
inline bool operator < ( const item_wrapper& a, const item_wrapper& b )
|
||||||
|
{ return ( std::tie( a.v ) < std::tie( b.v ) ); }
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
||||||
|
FC_REFLECT( fc::test::item_wrapper, (v) );
|
||||||
|
FC_REFLECT( fc::test::item, (level)(w) );
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(fc_serialization)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( nested_objects_test )
|
||||||
|
{ try {
|
||||||
|
|
||||||
|
auto create_nested_object = []( uint32_t level )
|
||||||
|
{
|
||||||
|
ilog( "Creating nested object with ${lv} level(s)", ("lv",level) );
|
||||||
|
fc::test::item nested;
|
||||||
|
for( uint32_t i = 1; i <= level; i++ )
|
||||||
|
{
|
||||||
|
if( i % 100 == 0 )
|
||||||
|
ilog( "Creating level ${lv}", ("lv",i) );
|
||||||
|
fc::test::item_wrapper wp( std::move(nested) );
|
||||||
|
nested = fc::test::item( std::move(wp), i );
|
||||||
|
}
|
||||||
|
return nested;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 100 levels, should be allowed
|
||||||
|
{
|
||||||
|
auto nested = create_nested_object( 100 );
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "About to pack." );
|
||||||
|
fc::raw::pack( ss, nested );
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "About to unpack." );
|
||||||
|
fc::test::item unpacked;
|
||||||
|
fc::raw::unpack( ss, unpacked );
|
||||||
|
|
||||||
|
BOOST_CHECK( unpacked == nested );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 150 levels, by default packing will fail
|
||||||
|
{
|
||||||
|
auto nested = create_nested_object( 150 );
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "About to pack." );
|
||||||
|
BOOST_CHECK_THROW( fc::raw::pack( ss, nested ), fc::assert_exception );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 150 levels and allow packing, unpacking will fail
|
||||||
|
{
|
||||||
|
auto nested = create_nested_object( 150 );
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "About to pack." );
|
||||||
|
fc::raw::pack( ss, nested, 1500 );
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "About to unpack." );
|
||||||
|
fc::test::item unpacked;
|
||||||
|
BOOST_CHECK_THROW( fc::raw::unpack( ss, unpacked ), fc::assert_exception );
|
||||||
|
}
|
||||||
|
|
||||||
|
} FC_CAPTURE_LOG_AND_RETHROW ( (0) ) }
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
Loading…
Reference in a new issue