#pragma once #include #include #include #include namespace fc { namespace raw { template class variant_packer : public variant::visitor { public: 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 int64_t& v )const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const uint64_t& v )const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const double& v )const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const bool& v )const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const string& v )const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const variant_object& v)const { fc::raw::pack( s, v, max_depth ); } virtual void handle( const variants& v)const { fc::raw::pack( s, v, max_depth ); } Stream& s; const uint32_t max_depth; }; template inline void pack( Stream& s, const variant& v, uint32_t _max_depth ) { FC_ASSERT( _max_depth > 0 ); --_max_depth; pack( s, uint8_t(v.get_type()), _max_depth ); v.visit( variant_packer( s, _max_depth ) ); } template inline void unpack( Stream& s, variant& v, uint32_t _max_depth ) { FC_ASSERT( _max_depth > 0 ); --_max_depth; uint8_t t; unpack( s, t, _max_depth ); switch( t ) { case variant::null_type: return; case variant::int64_type: { int64_t val; raw::unpack( s, val, _max_depth ); v = val; return; } case variant::uint64_type: { uint64_t val; raw::unpack( s, val, _max_depth ); v = val; return; } case variant::double_type: { double val; raw::unpack( s, val, _max_depth ); v = val; return; } case variant::bool_type: { bool val; raw::unpack( s, val, _max_depth ); v = val; return; } case variant::string_type: { fc::string val; raw::unpack( s, val, _max_depth ); v = fc::move(val); return; } case variant::array_type: { variants val; raw::unpack( s, val, _max_depth ); v = fc::move(val); return; } case variant::object_type: { variant_object val; raw::unpack( s, val, _max_depth ); v = fc::move(val); return; } default: FC_THROW_EXCEPTION( parse_error_exception, "Unknown Variant Type ${t}", ("t", t) ); } } template 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(); pack( s, vs, _max_depth ); for( auto itr = v.begin(); itr != v.end(); ++itr ) { pack( s, itr->key(), _max_depth ); pack( s, itr->value(), _max_depth ); } } template inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth ) { FC_ASSERT( _max_depth > 0 ); --_max_depth; unsigned_int vs; unpack( s, vs, _max_depth ); mutable_variant_object mvo; mvo.reserve(vs.value); for( uint32_t i = 0; i < vs.value; ++i ) { fc::string key; fc::variant value; fc::raw::unpack( s, key, _max_depth ); fc::raw::unpack( s, value, _max_depth ); mvo.set( fc::move(key), fc::move(value) ); } v = fc::move(mvo); } } } // fc::raw