2013-07-22 18:03:34 +00:00
|
|
|
#pragma once
|
2014-12-10 16:21:44 +00:00
|
|
|
#include <fc/exception/exception.hpp>
|
2013-07-22 18:03:34 +00:00
|
|
|
#include <fc/io/raw_fwd.hpp>
|
|
|
|
|
#include <fc/variant_object.hpp>
|
|
|
|
|
#include <fc/variant.hpp>
|
|
|
|
|
|
|
|
|
|
namespace fc { namespace raw {
|
|
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
|
class variant_packer : public variant::visitor
|
|
|
|
|
{
|
|
|
|
|
public:
|
2018-03-13 20:13:45 +00:00
|
|
|
variant_packer( Stream& _s, uint32_t _max_depth ):s(_s),max_depth(_max_depth - 1)
|
|
|
|
|
{
|
|
|
|
|
FC_ASSERT( _max_depth > 0 );
|
|
|
|
|
}
|
2013-07-22 18:03:34 +00:00
|
|
|
virtual void handle()const { }
|
|
|
|
|
virtual void handle( const int64_t& v )const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
virtual void handle( const uint64_t& v )const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
2018-03-13 20:13:45 +00:00
|
|
|
virtual void handle( const double& v )const
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
virtual void handle( const bool& v )const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
virtual void handle( const string& v )const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
virtual void handle( const variant_object& v)const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
virtual void handle( const variants& v)const
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::pack( s, v, max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
2018-03-13 20:13:45 +00:00
|
|
|
|
2013-07-22 18:03:34 +00:00
|
|
|
Stream& s;
|
2018-03-13 20:13:45 +00:00
|
|
|
const uint32_t max_depth;
|
|
|
|
|
|
2013-07-22 18:03:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2018-03-13 20:13:45 +00:00
|
|
|
template<typename Stream>
|
|
|
|
|
inline void pack( Stream& s, const variant& v, uint32_t _max_depth )
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
FC_ASSERT( _max_depth > 0 );
|
|
|
|
|
--_max_depth;
|
|
|
|
|
pack( s, uint8_t(v.get_type()), _max_depth );
|
|
|
|
|
v.visit( variant_packer<Stream>( s, _max_depth ) );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
2018-03-13 20:13:45 +00:00
|
|
|
template<typename Stream>
|
|
|
|
|
inline void unpack( Stream& s, variant& v, uint32_t _max_depth )
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
FC_ASSERT( _max_depth > 0 );
|
|
|
|
|
--_max_depth;
|
2013-07-22 18:03:34 +00:00
|
|
|
uint8_t t;
|
2018-03-13 20:13:45 +00:00
|
|
|
unpack( s, t, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
switch( t )
|
|
|
|
|
{
|
|
|
|
|
case variant::null_type:
|
|
|
|
|
return;
|
|
|
|
|
case variant::int64_type:
|
|
|
|
|
{
|
|
|
|
|
int64_t val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::uint64_type:
|
|
|
|
|
{
|
|
|
|
|
uint64_t val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::double_type:
|
|
|
|
|
{
|
|
|
|
|
double val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::bool_type:
|
|
|
|
|
{
|
|
|
|
|
bool val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::string_type:
|
|
|
|
|
{
|
|
|
|
|
fc::string val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = fc::move(val);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::array_type:
|
|
|
|
|
{
|
|
|
|
|
variants val;
|
2018-03-13 20:13:45 +00:00
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = fc::move(val);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case variant::object_type:
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
variant_object val;
|
|
|
|
|
raw::unpack( s, val, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
v = fc::move(val);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
FC_THROW_EXCEPTION( parse_error_exception, "Unknown Variant Type ${t}", ("t", t) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-13 20:13:45 +00:00
|
|
|
template<typename Stream>
|
|
|
|
|
inline void pack( Stream& s, const variant_object& v, uint32_t _max_depth )
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
FC_ASSERT( _max_depth > 0 );
|
|
|
|
|
--_max_depth;
|
2014-09-18 15:17:26 +00:00
|
|
|
unsigned_int vs = (uint32_t)v.size();
|
2018-03-13 20:13:45 +00:00
|
|
|
pack( s, vs, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
for( auto itr = v.begin(); itr != v.end(); ++itr )
|
|
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
pack( s, itr->key(), _max_depth );
|
|
|
|
|
pack( s, itr->value(), _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2018-03-13 20:13:45 +00:00
|
|
|
template<typename Stream>
|
|
|
|
|
inline void unpack( Stream& s, variant_object& v, uint32_t _max_depth )
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
2018-03-13 20:13:45 +00:00
|
|
|
FC_ASSERT( _max_depth > 0 );
|
|
|
|
|
--_max_depth;
|
2013-07-22 18:03:34 +00:00
|
|
|
unsigned_int vs;
|
2018-03-13 20:13:45 +00:00
|
|
|
unpack( s, vs, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
|
|
|
|
|
mutable_variant_object mvo;
|
|
|
|
|
mvo.reserve(vs.value);
|
2014-04-10 18:27:20 +00:00
|
|
|
for( uint32_t i = 0; i < vs.value; ++i )
|
2013-07-22 18:03:34 +00:00
|
|
|
{
|
|
|
|
|
fc::string key;
|
|
|
|
|
fc::variant value;
|
2018-03-13 20:13:45 +00:00
|
|
|
fc::raw::unpack( s, key, _max_depth );
|
|
|
|
|
fc::raw::unpack( s, value, _max_depth );
|
2013-07-22 18:03:34 +00:00
|
|
|
mvo.set( fc::move(key), fc::move(value) );
|
|
|
|
|
}
|
|
|
|
|
v = fc::move(mvo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} } // fc::raw
|