wanghuangang avatar

Analysis EOS fc::raw::pack code

wanghuangang

Published: 04 Feb 2018 › Updated: 04 Feb 2018Analysis  EOS fc::raw::pack code

Analysis EOS fc::raw::pack code

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 )
                  *************
          }
         }

Leave Analysis EOS fc::raw::pack code to:

Written by

Read more #eos posts


Best Posts From wanghuangang

We have not curated any of wanghuangang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From wanghuangang