diff --git a/include/fc/crypto/aes.hpp b/include/fc/crypto/aes.hpp index f0c7616..e9f26af 100644 --- a/include/fc/crypto/aes.hpp +++ b/include/fc/crypto/aes.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include diff --git a/include/fc/crypto/ripemd160.hpp b/include/fc/crypto/ripemd160.hpp index 912c392..de8d04e 100644 --- a/include/fc/crypto/ripemd160.hpp +++ b/include/fc/crypto/ripemd160.hpp @@ -71,6 +71,20 @@ class ripemd160 uint32_t _hash[5]; }; +namespace raw { + + template + inline void pack( T& ds, const ripemd160& ep, uint32_t _max_depth ) { + ds << ep; + } + + template + inline void unpack( T& ds, ripemd160& ep, uint32_t _max_depth ) { + ds >> ep; + } + +} + class variant; void to_variant( const ripemd160& bi, variant& v ); void from_variant( const variant& v, ripemd160& bi ); diff --git a/include/fc/crypto/sha224.hpp b/include/fc/crypto/sha224.hpp index a621208..6f2a156 100644 --- a/include/fc/crypto/sha224.hpp +++ b/include/fc/crypto/sha224.hpp @@ -70,6 +70,20 @@ class sha224 uint32_t _hash[7]; }; +namespace raw { + + template + inline void pack( T& ds, const sha224& ep, uint32_t _max_depth ) { + ds << ep; + } + + template + inline void unpack( T& ds, sha224& ep, uint32_t _max_depth ) { + ds >> ep; + } + +} + class variant; void to_variant( const sha224& bi, variant& v ); void from_variant( const variant& v, sha224& bi ); diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index 58bba9e..0954fc7 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -98,6 +98,20 @@ class sha256 uint64_t _hash[4]; }; +namespace raw { + + template + inline void pack( T& ds, const sha256& ep, uint32_t _max_depth ) { + ds << ep; + } + + template + inline void unpack( T& ds, sha256& ep, uint32_t _max_depth ) { + ds >> ep; + } + +} + typedef sha256 uint256; class variant; diff --git a/include/fc/crypto/sha512.hpp b/include/fc/crypto/sha512.hpp index ef10887..a4406c0 100644 --- a/include/fc/crypto/sha512.hpp +++ b/include/fc/crypto/sha512.hpp @@ -66,6 +66,20 @@ class sha512 uint64_t _hash[8]; }; +namespace raw { + + template + inline void pack( T& ds, const sha512& ep, uint32_t _max_depth ) { + ds << ep; + } + + template + inline void unpack( T& ds, sha512& ep, uint32_t _max_depth ) { + ds >> ep; + } + +} + typedef fc::sha512 uint512; class variant; diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index ed6e81a..bea77a8 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -351,19 +351,10 @@ namespace fc { const uint32_t max_depth; }; + // Default pack/unpack functions for classes (if_class) are removed due to recursion issue. + // Classes should implement pack/unpack functions explicitly. template - struct if_class{ - template - static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) - { - FC_ASSERT( false, "Please implement pack(...)" ); - } - template - static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) - { - FC_ASSERT( false, "Please implement unpack(...)" ); - } - }; + struct if_class; template<> struct if_class { diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index 42e955a..157a745 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -22,6 +22,11 @@ namespace fc { class path; template class static_variant; + class sha224; + class sha256; + class sha512; + class ripemd160; + template class enum_type; namespace ip { class endpoint; } @@ -96,6 +101,15 @@ namespace fc { template void unpack( Stream& s, fc::ecc::private_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); template void pack( Stream& s, const fc::ecc::private_key&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::sha224&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void pack( Stream& s, const fc::sha224&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::sha256&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void pack( Stream& s, const fc::sha256&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::sha512&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void pack( Stream& s, const fc::sha512&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void unpack( Stream& s, fc::ripemd160&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void pack( Stream& s, const fc::ripemd160&, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template inline void pack( Stream& s, const T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); template inline void unpack( Stream& s, T& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH ); diff --git a/tests/serialization_test.cpp b/tests/serialization_test.cpp index eedc982..e1e9a54 100644 --- a/tests/serialization_test.cpp +++ b/tests/serialization_test.cpp @@ -35,60 +35,9 @@ namespace fc { namespace test { inline bool operator < ( const item& a, const item& b ) { return ( std::tie( a.level, a.w ) < std::tie( b.level, b.w ) ); } - class class_item; - - class class_item_wrapper - { - public: - class_item_wrapper() {} - class_item_wrapper(class_item&& it) { v.reserve(1); v.emplace_back( it ); } - std::vector v; - }; - inline bool operator == ( const class_item_wrapper& a, const class_item_wrapper& b ) - { return ( std::tie( a.v ) == std::tie( b.v ) ); } - - class class_item - { - public: - class_item(int32_t lvl = 0) : level(lvl) {} - class_item(class_item_wrapper&& wp, int32_t lvl = 0) : level(lvl), w(wp) {} - int32_t level; - class_item_wrapper w; - }; - inline bool operator == ( const class_item& a, const class_item& b ) - { return ( std::tie( a.level, a.w ) == std::tie( b.level, b.w ) ); } - - template - void operator >> ( Stream& s, class_item_wrapper& w ) - { - fc::raw::unpack( s, w.v ); - } - template - void operator << ( Stream& s, const class_item_wrapper& w ) - { - fc::raw::pack( s, w.v ); - } - - template - void operator >> ( Stream& s, class_item& it ) - { - fc::raw::unpack( s, it.level ); - fc::raw::unpack( s, it.w ); - } - template - void operator << ( Stream& s, const class_item& it ) - { - fc::raw::pack( s, it.level ); - fc::raw::pack( s, it.w ); - } } } // namespace fc::test -namespace fc { - template<> struct get_typename { static const char* name() { return "class_item"; } }; - template<> struct get_typename { static const char* name() { return "class_item_wrapper"; } }; -} - FC_REFLECT( fc::test::item_wrapper, (v) ); FC_REFLECT( fc::test::item, (level)(w) ); @@ -111,20 +60,6 @@ BOOST_AUTO_TEST_CASE( nested_objects_test ) return nested; }; - auto create_nested_class_object = []( uint32_t level ) - { - ilog( "Creating nested class object with ${lv} level(s)", ("lv",level) ); - fc::test::class_item nested; - for( uint32_t i = 1; i <= level; i++ ) - { - if( i % 100 == 0 ) - ilog( "Creating level ${lv}", ("lv",i) ); - fc::test::class_item_wrapper wp( std::move(nested) ); - nested = fc::test::class_item( std::move(wp), i ); - } - return nested; - }; - // 100 levels, should be allowed { auto nested = create_nested_object( 100 ); @@ -165,30 +100,6 @@ BOOST_AUTO_TEST_CASE( nested_objects_test ) BOOST_CHECK_THROW( fc::raw::unpack( ss, unpacked ), fc::assert_exception ); } - // 150 levels, by default packing will fail - { - auto nested = create_nested_class_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 as class object." ); - fc::test::class_item unpacked; - BOOST_CHECK_THROW( fc::raw::unpack( ss, unpacked ), fc::assert_exception ); - } - } FC_CAPTURE_LOG_AND_RETHROW ( (0) ) } BOOST_AUTO_TEST_SUITE_END()