Example wallet_api_plugin code ,there is a struct
struct plain_keys {
fc::sha512 checksum;
map<public_key_type,string> keys;
};
In wallet_api_impl class there is a funtion
void encrypt_keys()
{
*************
plain_keys data;
data.keys = _keys;
data.checksum = _checksum;
auto plain_txt = fc::raw::pack(data);
********************
}
}
how fc::raw::pack Code flow???
Setp 1.
We must know the FC_REFLECT( eosio::wallet::plain_keys, (checksum)(keys) ) MARCO define.
See the macro code,follow is the code
namespace fc {
template<> struct get_typename< eosio :: wallet :: plain_keys > {
static const char* name() {
return "eosio::wallet::plain_keys" ;
}
};
template<> struct reflector< eosio :: wallet :: plain_keys > {
typedef eosio :: wallet :: plain_keys type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
enum member_count_enum {
local_member_count = 0 + 1 + 1 , total_member_count = local_member_count};
template<typename Visitor> static inline void visit( const Visitor& v ) {
{
typedef decltype((static_cast<type*>(nullptr))-> checksum ) member_type;
v . template operator()<member_type,type,&type:: checksum >( "checksum" );
}
{
typedef decltype((static_cast<type*>(nullptr))-> keys ) member_type;
v . template operator()<member_type,type,&type:: keys >( "keys" );
}
}
};
}
STEP 2.
plain_keys data;
auto plain_txt = fc::raw::pack(data);
Jump 1.Go to declare std::vector<char> pack( const T& v ).
template<typename T>
inline std::vector<char> pack( const T& v ) {
datastream<size_t> ps;
fc::raw::pack(ps,v ); // jumber where ?? see jump 2
std::vector<char> vec(ps.tellp());
************************************
return vec;
}
Jump 2: Go to declare fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::pack(s,v)
template<typename Stream, typename T>
inline void pack( Stream& s, const T& v ) {
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::pack(s,v);
}
Attention this if_reflected< typename fc::reflector<T>::is_defined > code line ,
Do you rember the FC_REFLECT( eosio::wallet::plain_keys, (checksum)(keys) ) MARCO define???
see the template<> struct reflector< eosio :: wallet :: plain_keys >
there is members
typedef fc::true_type is_defined;
so,contiune jump
Jump 3:.Go to declare struct if_reflected<fc::true_type>
template<>
struct if_reflected<fc::true_type> {
template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) {
if_enum< typename fc::reflector<T>::is_enum >::pack(s,v);
}
**************************
};
See the template<> struct reflector< eosio :: wallet :: plain_keys >
there is member typedef fc::false_type is_enum;
so continue jump
Jump 4:Go to declare template<typename IsEnum=fc::false_type>
template<typename IsEnum=fc::false_type>
struct if_enum {
template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v ) {
fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s ) ); // visit what?
}
**********************
};
see the
template<> struct reflector< eosio :: wallet :: plain_keys >
there a function template<typename Visitor> static inline void visit( const Visitor& v ),
the pack_object_visitor is define in raw.hpp,let me see the code.
template<typename Stream, typename Class>
struct pack_object_visitor {
pack_object_visitor(const Class& _c, Stream& _s)
:c(_c),s(_s){}
template<typename T, typename C, T(C::*p)>
void operator()( const char* name )const {
fc::raw::pack( s, c.*p );
}
private:
const Class& c;
Stream& s;
};
so fc::raw::pack( s, c.*p ) equal fc::raw::pack( s, c->&type:: checksum ) and fc::raw::pack( s, c->&type:: keys ),type:: checksum equal fc::sha512 and type:: keys equal map<public_key_type,string> ;
the finally:
fc::raw::pack( s, c.*p ) call sha512 class's function //void inline friend T& operator<<( T& ds, const sha512& ep )
AND
namespace fc {
************
namespace raw { inline void pack( Stream& s, const std::map<K,V>& value )
*************
}
}