MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/raw/raw.hpp
00001 #ifndef _MACE_RPC_RAW_HPP_
00002 #define _MACE_RPC_RAW_HPP_
00003 #include <mace/reflect/reflect.hpp>
00004 
00005 #include <mace/rpc/varint.hpp>
00006 #include <mace/rpc/required.hpp>
00007 #include <mace/rpc/errors.hpp>
00008 #include <mace/cmt/log/log.hpp>
00009 #include <sstream>
00010 #include <iostream>
00011 #include <map>
00012 #include <iomanip>
00013 
00014 #include <boost/fusion/container/vector.hpp>
00015 #include <boost/fusion/algorithm.hpp>
00016 #include <boost/fusion/support/is_sequence.hpp>
00017 #include <boost/fusion/sequence/intrinsic/size.hpp>
00018 #include <mace/rpc/datastream.hpp>
00019 
00020 namespace mace { namespace rpc { namespace raw {
00021 
00022 
00023     template<typename Stream, typename T>
00024     void unpack( Stream& s, boost::optional<T>& v );
00025     template<typename Stream, typename T>
00026     void pack( Stream& s, const boost::optional<T>& v );
00027     template<typename Stream> inline void unpack( Stream& s, std::string& v );
00028 
00029     template<typename Stream, typename T>
00030     inline void pack( Stream& s, const T& v );
00031     template<typename Stream, typename T>
00032     inline void unpack( Stream& s, T& v );
00033 
00034     template<typename Stream, typename T, template<typename> class Alloc, template<typename,typename> class Container>
00035     inline void pack( Stream& s, const Container<T,Alloc<T> >& value );
00036     template<typename Stream, typename T, template<typename> class Alloc, template<typename,typename> class Container>
00037     inline void unpack( Stream& s, Container<T,Alloc<T> >& value );
00038 
00039 
00040     template<typename Stream, typename T>
00041     void pack( Stream&, const std::set<T>& value );
00042     template<typename Stream, typename T>
00043     void unpack( Stream&, std::set<T>& value );
00044 
00045 
00046     template<typename Stream, typename Key, typename Value>
00047     void pack( Stream& s, const std::map<Key,Value>& value );
00048     template<typename Stream, typename Key, typename Value>
00049     void unpack( Stream& s, std::map<Key,Value>& value );
00050 
00051     template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
00052       uint32_t val = (v.value<<1) ^ (v.value>>31);
00053       do {
00054         uint8_t b = uint8_t(val) & 0x7f;
00055         val >>= 7;
00056         b |= ((val > 0) << 7);
00057         s.put(b);
00058       } while( val );
00059     }
00060     template<typename Stream> inline void pack( Stream& s, const unsigned_int& v ) {
00061       uint64_t val = v.value;
00062       do {
00063         uint8_t b = uint8_t(val) & 0x7f;
00064         val >>= 7;
00065         b |= ((val > 0) << 7);
00066         s.put(b);
00067       }while( val );
00068     }
00069 
00070 
00071     template<typename Stream> inline void pack( Stream& s, const bool& v ) { pack( s, uint8_t(v) );     }
00072     template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, std::string(v) ); }
00073 
00074     template<typename Stream, typename T> 
00075     inline void pack( Stream& s, const required<T>& v ) { pack( s, *v); }
00076 
00077     template<typename Stream, typename T> 
00078     inline void pack( Stream& s, const boost::optional<T>& v ) {
00079       pack( s, bool(v) );
00080       if( v ) 
00081         pack( s, *v );
00082     }
00083     template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) { 
00084       pack( s, unsigned_int(value.size()) );
00085       if( value.size() )
00086         s.write( &value.front(), value.size() );
00087     }
00088     template<typename Stream> inline void pack( Stream& s, const std::string& v )  {
00089       pack( s, unsigned_int(v.size()) );     
00090       if( v.size() )
00091         s.write( v.c_str(), v.size() );
00092     }
00093 
00094     template<typename Stream> inline void unpack( Stream& s, signed_int& vi ) {
00095       uint32_t v = 0; char b = 0; int by = 0;
00096       do {
00097         s.get(b);
00098         v |= uint32_t(uint8_t(b) & 0x7f) << by;
00099         by += 7;
00100       } while( uint8_t(b) & 0x80 );
00101       vi.value = ((v>>1) ^ (v>>31)) + (v&0x01);
00102       vi.value = v&0x01 ? vi.value : -vi.value;
00103       vi.value = -vi.value;
00104     }
00105     template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi ) {
00106       uint64_t v = 0; char b = 0; uint8_t by = 0;
00107       do {
00108           s.get(b);
00109           v |= uint32_t(uint8_t(b) & 0x7f) << by;
00110           by += 7;
00111       } while( uint8_t(b) & 0x80 );
00112       vi.value = v;
00113     }
00114     template<typename Stream> inline void unpack( Stream& s, bool& v ) {
00115       uint8_t b; 
00116       unpack( s, b ); 
00117       v=b;    
00118     }
00119     template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) { 
00120       unsigned_int size; unpack( s, size );
00121       value.resize(size.value);
00122       if( value.size() )
00123         s.read( &value.front(), value.size() );
00124     }
00125     template<typename Stream> inline void unpack( Stream& s, std::string& v )  {
00126       std::vector<char> tmp; unpack(s,tmp);
00127       v = std::string(tmp.begin(),tmp.end());
00128     }
00129 
00130     template<typename Stream, typename T>
00131     void unpack( Stream& s, boost::optional<T>& v ) {
00132       bool b; unpack( s, b ); 
00133       if( b ) { v = T(); unpack( s, *v ); }
00134     }
00135     template<typename Stream, typename T>
00136     void unpack( const Stream& s, required<T>& v ) {
00137       v = T(); unpack( s, *v );
00138     }
00139     //template<typename Stream, typename T, template<typename> class Alloc, template<typename,typename> class Container>
00140     //void unpack( const Stream& s, Container<T,Alloc<T> >& value );
00141 
00142     template<typename Stream, typename Key, typename Value>
00143     void unpack( const Stream& s, std::map<Key,Value>& value );
00144     template<typename Stream, typename Key, typename Value>
00145     void unpack( const Stream& s, std::pair<Key,Value>& value );
00146     template<typename Stream, typename Value>
00147     void unpack( const Stream& s, std::map<std::string,Value>& val );
00148 
00149     namespace detail {
00150     
00151       template<typename Stream, typename Class>
00152       struct pack_object_visitor {
00153         pack_object_visitor(const Class& _c, Stream& _s)
00154         :c(_c),s(_s){}
00155 
00156         template<typename T, typename C, T(C::*p)>
00157         inline void operator()( const char* name )const {
00158           //pack_helper( c.*p, name );
00159           mace::rpc::raw::pack( s, c.*p );
00160         }
00161         private:            
00162           const Class& c;
00163           Stream&      s;
00164       };
00165 
00166       template<typename Stream, typename Class>
00167       struct unpack_object_visitor {
00168         unpack_object_visitor(Class& _c, Stream& _s)
00169         :c(_c),s(_s){}
00170 
00171         template<typename T, typename C, T(C::*p)>
00172         inline void operator()( const char* name )const {
00173           mace::rpc::raw::unpack( s, c.*p );
00174         }
00175         private:            
00176           Class&  c;
00177           Stream& s;
00178       };
00179 
00180       template<typename Stream>
00181       struct pack_sequence {
00182          pack_sequence( Stream& _s ):s(_s){}
00183          template<typename T>
00184          void operator() ( const T& v )const { mace::rpc::raw::pack(s,v); }
00185          Stream&    s;
00186       };
00187 
00188       template<typename Stream>
00189       struct unpack_sequence {
00190          unpack_sequence( Stream& _s ):s(_s){}
00191          template<typename T>
00192          void operator() ( T& v )const { mace::rpc::raw::unpack(s,v); }
00193          Stream&  s;
00194       };
00195 
00196       template<typename IsPod=boost::false_type>
00197       struct if_pod{
00198         template<typename Stream, typename T>
00199         static inline void pack( Stream& s, const T& v ) { 
00200           s << v;
00201         }
00202         template<typename Stream, typename T>
00203         static inline void unpack( Stream& s, T& v ) { 
00204           s >> v;
00205         }
00206       };
00207 
00208       template<>
00209       struct if_pod<boost::true_type> {
00210         template<typename Stream, typename T>
00211         static inline void pack( Stream& s, const T& v ) { 
00212           s.write( (char*)&v, sizeof(v) );   
00213         }
00214         template<typename Stream, typename T>
00215         static inline void unpack( Stream& s, T& v ) { 
00216           s.read( (char*)&v, sizeof(v) );   
00217         }
00218       };
00219 
00220       template<typename IsReflected=boost::false_type>
00221       struct if_reflected {
00222         template<typename Stream, typename T>
00223         static inline void pack( Stream& s, const T& v ) { 
00224           if_pod<typename boost::is_pod<T>::type>::pack(s,v);
00225         }
00226         template<typename Stream, typename T>
00227         static inline void unpack( Stream& s, T& v ) { 
00228           if_pod<typename boost::is_pod<T>::type>::unpack(s,v);
00229         }
00230       };
00231       template<>
00232       struct if_reflected<boost::true_type> {
00233         template<typename Stream, typename T>
00234         static inline void pack( Stream& s, const T& v ) { 
00235           mace::reflect::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s ) );
00236         }
00237         template<typename Stream, typename T>
00238         static inline void unpack( Stream& s, T& v ) { 
00239           mace::reflect::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s ) );
00240         }
00241       };
00242 
00243       template<typename IsFusionSeq> 
00244       struct if_fusion_seq {
00245         template<typename Stream, typename T> 
00246         inline static void pack( Stream& s, const T& v ) {
00247           pack_sequence<Stream> pack_vector( s );
00248           boost::fusion::for_each( v, pack_vector );
00249         }
00250         template<typename Stream, typename T> 
00251         inline static void unpack( Stream& s, T& v ) {
00252           unpack_sequence<Stream> unpack_vector(s);
00253           boost::fusion::for_each( v, unpack_vector );
00254         }
00255       };
00256 
00257       template<> 
00258       struct if_fusion_seq<boost::mpl::false_> {
00259         template<typename Stream, typename T> 
00260         inline static void pack( Stream& s, const T& v ) {
00261           if_reflected<typename mace::reflect::reflector<T>::is_defined>::pack(s,v);
00262         }
00263         template<typename Stream, typename T> 
00264         inline static void unpack( Stream& s, T& v ) {
00265           if_reflected<typename mace::reflect::reflector<T>::is_defined>::unpack(s,v);
00266         }
00267       };
00268     } // namesapce detail
00269 
00270 
00271     template<typename Stream, typename T>
00272     inline void pack( Stream& s, const std::set<T>& value ) {
00273          pack( s, unsigned_int(value.size()) );
00274          typename std::set<T>::const_iterator itr = value.begin();
00275          typename std::set<T>::const_iterator end = value.end();
00276          while( itr != end ) {
00277            mace::rpc::raw::pack( s, *itr );
00278            ++itr;
00279          }
00280     }
00281 
00282     template<typename Stream, typename T>
00283     inline void unpack( Stream& s, std::set<T>& value ) {
00284         unsigned_int ss;
00285         unpack( s, ss );
00286         for( uint32_t i = 0; i < ss.value; ++i ) {
00287             T v;
00288             unpack( s, v );
00289             value.insert(v);
00290         }
00291     }
00292 
00293     template<typename Stream, typename T, template<typename> class Alloc, template<typename,typename> class Container>
00294     inline void pack( Stream& s, const Container<T,Alloc<T> >& value ) {
00295       pack( s, unsigned_int(value.size()) );
00296       typename Container<T,Alloc<T> >::const_iterator itr = value.begin();
00297       typename Container<T,Alloc<T> >::const_iterator end = value.end();
00298       while( itr != end ) {
00299         mace::rpc::raw::pack( s, *itr );
00300         ++itr;
00301       }
00302     }
00303 
00304     template<typename Stream, typename T, template<typename> class Alloc, template<typename,typename> class Container>
00305     inline void unpack( Stream& s, Container<T,Alloc<T> >& value ) {
00306       unsigned_int size; unpack( s, size );
00307       value.resize(size.value);
00308       typename Container<T,Alloc<T> >::iterator itr = value.begin();
00309       typename Container<T,Alloc<T> >::iterator end = value.end();
00310       while( itr != end ) {
00311         mace::rpc::raw::unpack( s, *itr );
00312         ++itr;
00313       }
00314     }
00315 
00316     // support for pair!
00317     template<typename Stream, typename Key, typename Value>
00318     inline void pack( Stream& s, const std::pair<Key,Value>& val ) {
00319       mace::rpc::raw::pack( s, val.first );
00320       mace::rpc::raw::pack( s, val.second );
00321     }
00322     // support for pair!
00323     template<typename Stream, typename Key, typename Value>
00324     void unpack( Stream& s, std::pair<Key,Value>& val ) {
00325       mace::rpc::raw::unpack( s, val.first );
00326       mace::rpc::raw::unpack( s, val.second );
00327     }
00328 
00329 
00330     // support arbitrary key/value containers as an array of pairs
00331     template<typename Stream, typename Key, typename Value>
00332     void pack( Stream& s, const std::map<Key,Value>& value ) {
00333       pack( s, unsigned_int(value.size()) );
00334       typename std::map<Key,Value>::const_iterator itr = value.begin();
00335       typename std::map<Key,Value>::const_iterator end = value.end();
00336       while( itr != end ) {
00337         mace::rpc::raw::pack( s, *itr );
00338         ++itr;
00339       }
00340     }
00341 
00342     template<typename Stream, typename Key, typename Value>
00343     inline void unpack( Stream& s, std::map<Key,Value>& value ) {
00344       unsigned_int size; unpack( s, size );
00345       value.clear();
00346       for( uint32_t i = 0; i < size.value; ++i ) {
00347         Key k; 
00348         mace::rpc::raw::unpack(s,k);
00349         mace::rpc::raw::unpack(s,value[k]);
00350       }
00351     }
00352 
00353     template<typename Stream, typename T> 
00354     inline void pack( Stream& s, const T& v ) {
00355       detail::if_fusion_seq< typename boost::fusion::traits::is_sequence<T>::type >::pack(s,v);
00356     }
00357     template<typename Stream, typename T> 
00358     inline void unpack( Stream& s, T& v ) {
00359       detail::if_fusion_seq< typename boost::fusion::traits::is_sequence<T>::type >::unpack(s,v);
00360     }
00361 
00362 
00363     template<typename T>
00364     inline void pack_vec( std::vector<char>& s, const T& v ) {
00365       datastream<size_t> ps; 
00366       raw::pack(ps,v );
00367       s.resize(ps.tellp());
00368       if( s.size() ) {
00369         datastream<char*>  ds( &s.front(), s.size() ); 
00370         raw::pack(ds,v);
00371       }
00372     }
00373 
00374     template<typename T>
00375     inline void unpack_vec( const std::vector<char>& s, T& v ) {
00376       if( s.size() ) {
00377         datastream<const char*>  ds( &s.front(), s.size() ); 
00378         raw::unpack(ds,v);
00379       }
00380     }
00381 
00382     template<typename T>
00383     inline void pack( char* d, uint32_t s, const T& v ) {
00384       datastream<char*> ds(d,s); 
00385       raw::pack(ds,v );
00386     }
00387 
00388     template<typename T>
00389     inline void unpack( const char* d, uint32_t s, T& v ) {
00390       datastream<const char*>  ds( d, s );
00391       raw::unpack(ds,v);
00392     }
00393     
00394 } } } // namespace mace::rpc::raw
00395 
00396 #endif // MACE_RPC_RAW_HPP