diff --git a/libraries/chain/include/graphene/chain/protocol/ext.hpp b/libraries/chain/include/graphene/chain/protocol/ext.hpp index 6c974630..75364525 100644 --- a/libraries/chain/include/graphene/chain/protocol/ext.hpp +++ b/libraries/chain/include/graphene/chain/protocol/ext.hpp @@ -29,6 +29,8 @@ namespace graphene { namespace chain { +using fc::unsigned_int; + template< typename T > struct extension { @@ -55,15 +57,19 @@ struct graphene_extension_pack_count_visitor template< typename Stream, typename T > struct graphene_extension_pack_read_visitor { - graphene_extension_pack_read_visitor( Stream& s, const T& v ) : stream(s), value(v) {} + graphene_extension_pack_read_visitor( Stream& s, const T& v, uint32_t _max_depth ) + : stream(s), value(v), max_depth(_max_depth - 1) + { + FC_ASSERT( _max_depth > 0 ); + } template void operator()( const char* name )const { if( (value.*member).valid() ) { - fc::raw::pack( stream, unsigned_int( which ) ); - fc::raw::pack( stream, *(value.*member) ); + fc::raw::pack( stream, unsigned_int( which ), max_depth ); + fc::raw::pack( stream, *(value.*member), max_depth ); } ++which; } @@ -71,27 +77,19 @@ struct graphene_extension_pack_read_visitor Stream& stream; const T& value; mutable uint32_t which = 0; + const uint32_t max_depth; }; -template< typename Stream, class T > -void operator<<( Stream& stream, const graphene::chain::extension& value ) -{ - graphene_extension_pack_count_visitor count_vtor( value.value ); - fc::reflector::visit( count_vtor ); - fc::raw::pack( stream, unsigned_int( count_vtor.count ) ); - graphene_extension_pack_read_visitor read_vtor( stream, value.value ); - fc::reflector::visit( read_vtor ); -} - - template< typename Stream, typename T > struct graphene_extension_unpack_visitor { - graphene_extension_unpack_visitor( Stream& s, T& v ) : stream(s), value(v) + graphene_extension_unpack_visitor( Stream& s, T& v, uint32_t _max_depth ) + : stream(s), value(v), max_depth(_max_depth - 1) { + FC_ASSERT( _max_depth > 0 ); unsigned_int c; - fc::raw::unpack( stream, c ); + fc::raw::unpack( stream, c, max_depth ); count_left = c.value; maybe_read_next_which(); } @@ -101,7 +99,7 @@ struct graphene_extension_unpack_visitor if( count_left > 0 ) { unsigned_int w; - fc::raw::unpack( stream, w ); + fc::raw::unpack( stream, w, max_depth ); next_which = w.value; } } @@ -112,7 +110,7 @@ struct graphene_extension_unpack_visitor if( (count_left > 0) && (which == next_which) ) { typename Member::value_type temp; - fc::raw::unpack( stream, temp ); + fc::raw::unpack( stream, temp, max_depth ); (value.*member) = temp; --count_left; maybe_read_next_which(); @@ -128,17 +126,9 @@ struct graphene_extension_unpack_visitor Stream& stream; T& value; + const uint32_t max_depth; }; -template< typename Stream, typename T > -void operator>>( Stream& s, graphene::chain::extension& value ) -{ - value = graphene::chain::extension(); - graphene_extension_unpack_visitor vtor( s, value.value ); - fc::reflector::visit( vtor ); - FC_ASSERT( vtor.count_left == 0 ); // unrecognized extension throws here -} - } } // graphene::chain namespace fc { @@ -212,4 +202,32 @@ void to_variant( const graphene::chain::extension& value, fc::variant& var, u var = vtor.mvo; } +namespace raw { + +template< typename Stream, typename T > +void pack( Stream& stream, const graphene::chain::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) +{ + FC_ASSERT( _max_depth > 0 ); + --_max_depth; + graphene::chain::graphene_extension_pack_count_visitor count_vtor( value.value ); + fc::reflector::visit( count_vtor ); + fc::raw::pack( stream, unsigned_int( count_vtor.count ), _max_depth ); + graphene::chain::graphene_extension_pack_read_visitor read_vtor( stream, value.value, _max_depth ); + fc::reflector::visit( read_vtor ); +} + + +template< typename Stream, typename T > +void unpack( Stream& s, graphene::chain::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) +{ + FC_ASSERT( _max_depth > 0 ); + --_max_depth; + value = graphene::chain::extension(); + graphene::chain::graphene_extension_unpack_visitor vtor( s, value.value, _max_depth ); + fc::reflector::visit( vtor ); + FC_ASSERT( vtor.count_left == 0 ); // unrecognized extension throws here +} + +} // fc::raw + } // fc diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp index e617c395..47f22878 100644 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ b/libraries/chain/include/graphene/chain/protocol/types.hpp @@ -35,7 +35,11 @@ #include #include #include -#include +#include + +#include + +#include #include #include