Analysis EOS fc::raw::pack code

in eos •  7 years ago  (edited)

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 )
                  *************
          }
         }
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!