MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/raw/raw_io.hpp
00001 #ifndef _MACE_RPC_RAW_RAW_IO_HPP_
00002 #define _MACE_RPC_RAW_RAW_IO_HPP_
00003 #include <mace/rpc/filter.hpp>
00004 #include <mace/reflect/reflect.hpp>
00005 #include <sstream>
00006 #include <iostream>
00007 #include <map>
00008 #include <iomanip>
00009 #include <mace/rpc/datastream.hpp>
00010 #include <sstream>
00011 
00012 #include <boost/optional.hpp>
00013 #include <boost/fusion/container/vector.hpp>
00014 #include <boost/fusion/algorithm.hpp>
00015 #include <boost/fusion/support/is_sequence.hpp>
00016 #include <boost/fusion/sequence/intrinsic/size.hpp>
00017 
00018 namespace mace { namespace rpc { namespace raw { 
00019     template<typename F, typename S, typename T>
00020     void apply_unpack_filter( F& f, S& s, T& t ); 
00021 
00022     template<typename T, typename Filter, typename Stream> 
00023     void pack( Filter&, Stream& st, const T& v ); 
00024 
00025     template<typename T, typename Filter, typename Stream> 
00026     void unpack( Filter&, Stream& st, T& v ); 
00027 
00028     template<typename Filter, typename Stream>
00029     inline void pack( Filter& f, Stream& st, const bool& v )         { char c(v?1:0); st.write(&c,sizeof(c)); }
00030     template<typename Filter, typename Stream>
00031     inline void pack( Filter& f, Stream& st, const float& v )        { st.write( (char*)&v, sizeof(v) ); }
00032     template<typename Filter, typename Stream>
00033     inline void pack( Filter& f, Stream& st, const double& v )       { st.write( (char*)&v, sizeof(v) ); }
00034     template<typename Filter, typename Stream>
00035     inline void pack( Filter& f, Stream& st, const uint8_t& v )      { st.write( (char*)&v, sizeof(v) ); }
00036     template<typename Filter, typename Stream>
00037     inline void pack( Filter& f, Stream& st, const uint16_t& v )     { st.write( (char*)&v, sizeof(v) ); }
00038     template<typename Filter, typename Stream>
00039     inline void pack( Filter& f, Stream& st, const uint32_t& v )     { st.write( (char*)&v, sizeof(v) ); }
00040     template<typename Filter, typename Stream>
00041     inline void pack( Filter& f, Stream& st, const uint64_t& v )     { st.write( (char*)&v, sizeof(v) ); }
00042     template<typename Filter, typename Stream>
00043     inline void pack( Filter& f, Stream& st, const int8_t& v )       { st.write( (char*)&v, sizeof(v) ); }
00044     template<typename Filter, typename Stream>
00045     inline void pack( Filter& f, Stream& st, const int16_t& v )      { st.write( (char*)&v, sizeof(v) ); }
00046     template<typename Filter, typename Stream>
00047     inline void pack( Filter& f, Stream& st, const int32_t& v )      { st.write( (char*)&v, sizeof(v) ); }
00048     template<typename Filter, typename Stream>
00049     inline void pack( Filter& f, Stream& st, const int64_t& v )      { st.write( (char*)&v, sizeof(v) ); }
00050 
00051     template<typename Filter, typename Stream> 
00052     inline void pack( Filter& f, Stream& s, const signed_int& v ) {
00053       uint32_t val = (v.value<<1) ^ (v.value>>31);
00054       do {
00055         uint8_t b = uint8_t(val) & 0x7f;
00056         val >>= 7;
00057         b |= ((val > 0) << 7);
00058         s.write((char*)&b,1);
00059       } while( val );
00060     }
00061     template<typename Filter, typename Stream> 
00062     inline void pack( Filter& f, Stream& s, const unsigned_int& v ) {
00063       uint64_t val = v.value;
00064       do {
00065         uint8_t b = uint8_t(val) & 0x7f;
00066         val >>= 7;
00067         b |= ((val > 0) << 7);
00068         s.write((char*)&b,1);
00069       }while( val );
00070     }
00071 
00072 
00074     template<typename Filter, typename Stream>
00075     inline void pack( Filter& f, Stream& st, const std::string& v )  {
00076       pack( f, st, unsigned_int(v.size())  );
00077       if( v.size() ) st.write( v.c_str(), v.size() );
00078     }
00079     template<typename Filter, typename Stream>
00080     inline void pack( Filter& f, Stream& st, const char* v ) {
00081       pack( f, st, std::string(v) );
00082     }
00083 
00084     template<typename Filter, typename Stream>
00085     void pack( Filter& c, Stream& st, const std::vector<char>& value );
00086     template<typename T, typename Filter, typename Stream>
00087     void pack( Filter& c, Stream& st, const boost::optional<T>& v );
00088     template<typename T, typename Filter, typename Stream>
00089     void pack( Filter& c, Stream& st, const std::vector<T>& value );
00090     template<typename T, typename Filter, typename Stream>
00091     void pack( Filter& c, Stream& st, const std::list<T>& value );
00092 
00093     template<typename T, typename Filter, typename Stream>
00094     void pack( Filter& c, Stream& st, const std::set<T>& value );
00095     template<typename Key, typename Value, typename Filter, typename Stream>
00096     void pack( Filter& c, Stream& st, const std::map<Key,Value>& value );
00097     template<typename Key, typename Value, typename Filter, typename Stream>
00098     void pack( Filter& c, Stream& st, const std::pair<Key,Value>& value );
00099     template<typename Value, typename Filter, typename Stream>
00100     void pack( Filter& c, Stream& st, const std::map<std::string,Value>& value );
00101 
00102 
00103     template<typename Filter, typename Stream> inline void unpack( Filter&, Stream& s, signed_int& vi ) {
00104       uint32_t v = 0; char b = 0; int by = 0;
00105       do {
00106         s.read(&b,sizeof(b));
00107         v |= uint32_t(uint8_t(b) & 0x7f) << by;
00108         by += 7;
00109       } while( uint8_t(b) & 0x80 );
00110       vi.value = ((v>>1) ^ (v>>31)) + (v&0x01);
00111       vi.value = v&0x01 ? vi.value : -vi.value;
00112       vi.value = -vi.value;
00113     }
00114     template<typename Filter, typename Stream> inline void unpack( Filter&, Stream& s, unsigned_int& vi ) {
00115       uint64_t v = 0; char b = 0; uint8_t by = 0;
00116       do {
00117           s.read(&b,sizeof(b));
00118           v |= uint32_t(uint8_t(b) & 0x7f) << by;
00119           by += 7;
00120       } while( uint8_t(b) & 0x80 );
00121       vi.value = v;
00122     }
00123 
00124     template<typename T, typename Filter, typename Stream>
00125     void unpack( Filter& c, Stream& st, const T& v ); 
00126     template<typename T, typename Filter, typename Stream> 
00127     void unpack( Filter& c, Stream& st, T& v ); 
00128     template<typename Filter, typename Stream>
00129     void unpack( Filter& c, Stream& st, bool& v );
00130     template<typename Filter, typename Stream>
00131     void unpack( Filter& c, Stream& st, float& v );
00132     template<typename Filter, typename Stream>
00133     void unpack( Filter& c, Stream& st, double& v );
00134     template<typename Filter, typename Stream>
00135     void unpack( Filter& c, Stream& st, uint8_t& v );
00136     template<typename Filter, typename Stream>
00137     void unpack( Filter& c, Stream& st, uint16_t& v );
00138     template<typename Filter, typename Stream>
00139     void unpack( Filter& c, Stream& st, uint32_t& v );
00140     template<typename Filter, typename Stream>
00141     void unpack( Filter& c, Stream& st, uint64_t& v );
00142     template<typename Filter, typename Stream>
00143     void unpack( Filter& c, Stream& st, int8_t& v );
00144     template<typename Filter, typename Stream>
00145     void unpack( Filter& c, Stream& st, int16_t& v );
00146     template<typename Filter, typename Stream>
00147     void unpack( Filter& c, Stream& st, int32_t& v );
00148     template<typename Filter, typename Stream>
00149     void unpack( Filter& c, Stream& st, int64_t& v );
00150     template<typename Filter, typename Stream>
00151     void unpack( Filter& c, Stream& st, std::string& v );
00152     template<typename Filter, typename Stream>
00153     void unpack( Filter& c, Stream& st, std::vector<char>& value );
00154     template<typename T, typename Filter, typename Stream>
00155     void unpack( Filter& c, Stream& st, boost::optional<T>& v );
00156     template<typename T, typename Filter, typename Stream>
00157     void unpack( Filter& c, Stream& st, std::vector<T>& value );
00158     template<typename T, typename Filter, typename Stream>
00159     void unpack( Filter& c, Stream& st, std::list<T>& value );
00160 
00161     template<typename T, typename Filter, typename Stream>
00162     void unpack( Filter& c, Stream& st, std::set<T>& value );
00163     template<typename Key, typename Value, typename Filter, typename Stream>
00164     void unpack( Filter& c, Stream& st, std::map<Key,Value>& value );
00165     template<typename Key, typename Value, typename Filter, typename Stream>
00166     void unpack( Filter& c, Stream& st, std::pair<Key,Value>& value );
00167     template<typename Value, typename Filter, typename Stream>
00168     void unpack( Filter& c, Stream& st, std::map<std::string,Value>& val );
00169 
00170     namespace detail {
00171       template<typename Class, typename Filter, typename Stream>
00172       struct pack_object_visitor {
00173         pack_object_visitor(Filter& _f, const Class& _c, Stream& _s)
00174         :f(_f),c(_c),s(_s){}
00175 
00179         template<typename T>
00180         inline void pack_helper( const T& v, const char* name )const {
00181           raw::pack( f, s, f(v) ); 
00182         }
00183         template<typename T>
00184         inline void pack_helper( const boost::optional<T>& v, const char* name )const {
00185           if( !!v ) {
00186             raw::pack( f, s, f(*v) ); 
00187           }
00188         }
00189         template<typename T, T  p>
00190         inline void operator()( const char* name )const {
00191           pack_helper( c.*p, name );
00192         }
00193 
00194         private:            
00195           Filter&       f;
00196           const Class&  c;
00197           Stream&       s;
00198       };
00199 
00200       template<typename Class, typename Filter, typename Stream>
00201       struct unpack_object_visitor  {
00202         unpack_object_visitor(Filter& _f, Class& _c, Stream& _s)
00203         :f(_f),c(_c),s(_s){}
00204 
00205         template<typename T, T p>
00206         void operator()( const char* name )const {
00207            apply_unpack_filter( f, s, c.*p );
00208            //raw::unpack( f, s, c.*p );
00209         }
00210         Filter&             f;
00211         Class&              c;
00212         Stream&             s;
00213       };
00214 
00215       template<typename Filter, typename Stream>
00216       struct pack_sequence {
00217          pack_sequence( Filter& _f, Stream& _s ):f(_f),s(_s){}
00218 
00219          Filter&    f;
00220          Stream&    s;
00221          
00222          template<typename T>
00223          void operator() ( const T& v )const {
00224             mace::rpc::raw::pack(f,s,f(v));
00225          }
00226       };
00227 
00228       template<typename Filter, typename Stream>
00229       struct unpack_sequence {
00230          unpack_sequence( Filter& _f, Stream& _s ):f(_f),s(_s){}
00231 
00232          Filter&  f;
00233          Stream&  s;
00234          
00235          template<typename T>
00236          void operator() ( T& v )const {
00237           apply_unpack_filter( f, s, v );
00238          }
00239       };
00240 
00241       template<bool IsFusionSeq> struct if_fusion_seq {
00242         template<typename T,typename Filter, typename Stream> 
00243         inline static void pack( Filter& f, Stream& st, const T& v ) {
00244             pack_sequence<Filter,Stream> pack_vector(f, st);
00245             boost::fusion::for_each( v, pack_vector );
00246         }
00247         template<typename T,typename Filter, typename Stream> 
00248         inline static void unpack( Filter& f, Stream& st, T& v ) {
00249             unpack_sequence<Filter,Stream> unpack_vector(f,st);
00250             boost::fusion::for_each( v, unpack_vector );
00251         }
00252       };
00253 
00254       template<typename IsReflected=boost::false_type>
00255       struct if_reflected {
00256         template<typename T,typename Filter, typename Stream>
00257         static inline void pack( Filter& f,Stream& s, const T& v ) { 
00258           //BOOST_STATIC_ASSERT_MSG( false, "Unknown type, not reflected" );
00259           elog( "Unknown type %1%", mace::reflect::get_typename<T>() );
00260           // TODO: Boost Serialize??
00261           //std::stringstream ss; ss << v;
00262           // TO BASE 64
00263           //raw::pack(f,s,f(mace::rpc::base64_encode((unsigned char const*)ss.str().c_str(),ss.str().size())));
00264         }
00265         template<typename T,typename Filter, typename Stream>
00266         static inline void unpack( Filter& f, Stream& s, T& v ) { 
00267           elog( "Unknown type %1%", mace::reflect::get_typename<T>() );
00268           //BOOST_STATIC_ASSERT_MSG( false, "Unknown type, not reflected" );
00269           // TODO: Boost Deserialize??
00270           //std::string str;
00271           //raw::unpack(f,s,str);
00272           //std::stringstream ss(mace::rpc::base64_decode(str)); 
00273           //ss >> v;
00274         }
00275       };
00276       template<>
00277       struct if_reflected<boost::true_type> {
00278         template<typename T,typename Filter, typename Stream>
00279         static inline void pack( Filter& f, Stream& st, const T& v ) { 
00280           detail::pack_object_visitor<T,Filter,Stream> pov(f,f(v),st);
00281           mace::reflect::reflector<T>::visit(pov);
00282         }
00283         template<typename T,typename Filter, typename Stream>
00284         static inline void unpack( Filter& f, Stream& st, T& v ) { 
00285           detail::unpack_object_visitor<T,Filter,Stream> pov(f,v,st );
00286           mace::reflect::reflector<T>::visit(pov);
00287         }
00288       };
00289 
00290       template<> struct if_fusion_seq<false> {
00291          template<typename T,typename Filter, typename Stream> 
00292          inline static void pack( Filter& f, Stream& st, const T& v ) {
00293            if_reflected<typename mace::reflect::reflector<T>::is_defined>::pack(f,st,v);
00294          }
00295          template<typename T,typename Filter, typename Stream> 
00296          inline static void unpack( Filter& f, Stream& st, T& v ) {
00297            if_reflected<typename mace::reflect::reflector<T>::is_defined>::unpack(f,st,v);
00298          }
00299       };
00300 
00301     } // namesapce detail
00302 
00303     template<typename Filter, typename Stream> 
00304     inline void unpack( Filter& f, Stream& st, bool& v )         { v = st.get(); }
00305     template<typename Filter, typename Stream> 
00306     inline void unpack( Filter& f, Stream& st, float& v )        { st.read( (char*)&v, sizeof(v) ); }
00307     template<typename Filter, typename Stream> 
00308     inline void unpack( Filter& f, Stream& st, double& v )       { st.read( (char*)&v, sizeof(v) ); }
00309     template<typename Filter, typename Stream> 
00310     inline void unpack( Filter& f, Stream& st, uint8_t& v )      { st.read( (char*)&v, sizeof(v) ); }
00311     template<typename Filter, typename Stream> 
00312     inline void unpack( Filter& f, Stream& st, uint16_t& v )     { st.read( (char*)&v, sizeof(v) ); }
00313     template<typename Filter, typename Stream> 
00314     inline void unpack( Filter& f, Stream& st, uint32_t& v )     { st.read( (char*)&v, sizeof(v) ); }
00315     template<typename Filter, typename Stream> 
00316     inline void unpack( Filter& f, Stream& st, uint64_t& v )     { st.read( (char*)&v, sizeof(v) ); }
00317     template<typename Filter, typename Stream> 
00318     inline void unpack( Filter& f, Stream& st, int8_t& v )       { st.read( (char*)&v, sizeof(v) ); }
00319     template<typename Filter, typename Stream> 
00320     inline void unpack( Filter& f, Stream& st, int16_t& v )      { st.read( (char*)&v, sizeof(v) ); }
00321     template<typename Filter, typename Stream> 
00322     inline void unpack( Filter& f, Stream& st, int32_t& v )      {st.read( (char*)&v, sizeof(v) ); }
00323     template<typename Filter, typename Stream> 
00324     inline void unpack( Filter& f, Stream& st, int64_t& v )      { st.read( (char*)&v, sizeof(v) ); }
00325 
00326     template<typename Filter, typename Stream> 
00327     inline void unpack( Filter& f, Stream& st, std::string& v )  { 
00328       unsigned_int i;
00329       unpack( f, st, i );
00330       v.resize(i.value);
00331       if( i.value ) {
00332         st.read( const_cast<char*>(v.c_str()), i );
00333       }
00334     }
00335 
00336     template<typename T, typename Filter, typename Stream> 
00337     inline void pack( Filter& f, Stream& st, const T& v ) {
00338         detail::if_fusion_seq< boost::fusion::traits::is_sequence<T>::value >::pack(f,st,v);
00339     }
00340 
00341     
00342     template<typename T, typename Filter, typename Stream> 
00343     inline void pack( Filter& f, Stream& st, const boost::optional<T>& v ) {
00344         raw::pack( f, st, f(*v) );
00345     }
00346 
00347     template<typename T, typename Filter, typename Stream>
00348     inline void unpack( Filter& f, Stream& st, boost::optional<T>& v ) {
00349         v = T();
00350         raw::unpack( f, st, *v );
00351     }
00352 
00353 
00354     template<typename T, typename Filter, typename Stream>
00355     inline void pack( Filter& f, Stream& st, const std::vector<T>& value ) {
00356         pack( f, st, unsigned_int(value.size()) );
00357         auto itr = value.begin();
00358         auto end = value.end();
00359         while( itr != end ) {
00360           raw::pack( f, st, f(*itr) );
00361           ++itr;
00362         }
00363     }
00364 
00365     template<typename T, typename Filter, typename Stream>
00366     inline void pack( Filter& f, Stream& st, const std::list<T>& value ) {
00367         pack( f, st, unsigned_int(value.size()) );
00368         auto itr = value.begin();
00369         auto end = value.end();
00370         while( itr != end ) {
00371           raw::pack( f, st, f(*itr) );
00372           ++itr;
00373         }
00374     }
00375 
00376 
00377     template<typename T, typename Filter, typename Stream>
00378     inline void pack( Filter& f, Stream& st, const std::set<T>& value ) {
00379         pack( f, st, unsigned_int(value.size()) );
00380         auto itr = value.begin();
00381         auto end = value.end();
00382         while( itr != end ) {
00383           raw::pack( f, st, f(*itr) );
00384           ++itr;
00385         }
00386     }
00387 
00388     template<typename T, typename Filter, typename Stream>
00389     inline void unpack( Filter& f, Stream& st, std::vector<T>& value ) {
00390         unsigned_int s;
00391         unpack( f, st, s );
00392         value.resize(s.value);
00393         for( uint32_t i = 0; i < value.size(); ++i ) {
00394           raw::unpack( f, st, value[i] );
00395         }
00396     }
00397     template<typename T, typename Filter, typename Stream>
00398     inline void unpack( Filter& f, Stream& st, std::list<T>& value ) {
00399         unsigned_int s;
00400         unpack( f, st, s );
00401         value.clear();
00402         for( uint32_t i = 0; i < s.value; ++i ) {
00403             T v;
00404             raw::unpack( f, st, v );
00405             value.push_back(std::move(v));
00406         }
00407     }
00408     template<typename T, typename Filter, typename Stream>
00409     inline void unpack( Filter& f, Stream& st, std::set<T>& value ) {
00410         unsigned_int s;
00411         unpack( f, st, s );
00412         for( uint32_t i = 0; i < s.value; ++i ) {
00413             T v;
00414             raw::unpack( f, st, v );
00415             value.insert(std::move(v));
00416         }
00417     }
00418 
00419     // support for pair!
00420     template<typename Key, typename Value, typename Filter, typename Stream>
00421     inline void pack( Filter& f, Stream& st, const std::pair<Key,Value>& val ) {
00422         pack( f, st, f(val.first) );
00423         pack( f, st, f(val.second) );
00424     }
00425     // support for pair!
00426     template<typename Key, typename Value, typename Filter, typename Stream>
00427     void unpack( Filter& f, Stream& st, std::pair<Key,Value>& val ) {
00428         apply_unpack_filter( f, st, val.first );
00429         apply_unpack_filter( f, st, val.second );
00430     }
00431 
00432 
00433     // support arbitrary key/value containers as an array of pairs
00434     template<typename Key, typename Value, typename Filter, typename Stream>
00435     void pack( Filter& f, Stream& st, const std::map<Key,Value>& value ) {
00436         pack( f, st, unsigned_int(value.size()) );
00437         auto itr = value.begin();
00438         auto end = value.end();
00439         while( itr != end ) {
00440           raw::pack( f, st, f(*itr) );
00441           ++itr;
00442         }
00443     }
00444 
00445     template<typename Key, typename Value, typename Filter, typename Stream>
00446     inline void unpack( Filter& f, Stream& st, std::map<Key,Value>& value ) {
00447         value.clear();
00448         unsigned_int s;
00449         unpack( f, st, s );
00450         for( uint32_t i = 0; i < s.value; ++i ) {
00451           Key k;
00452           Value v;
00453           apply_unpack_filter( f, st, k );
00454           apply_unpack_filter( f, st, v );
00455           value[k] = std::move(v);
00456         }
00457     }
00458 
00459     template<typename Filter, typename Stream>
00460     inline void pack( Filter& f, Stream& st, const std::vector<char>& data ) {
00461        unsigned_int i(data.size());
00462        pack( f, st, i );
00463        if( data.size() )
00464           st.write(&data.front(),data.size());
00465     }
00466     template<typename Filter, typename Stream>
00467     inline void unpack( Filter& f, Stream& st, std::vector<char>& data ) {
00468         unsigned_int s;
00469         unpack(f,st,s);
00471         data.resize(s.value);
00472         if( s.value )
00473             st.read( &data.front(), data.size() );
00474     }
00475 
00476     template<typename T, typename Filter, typename Stream> 
00477     inline void unpack( Filter& f, Stream& st, T& v ) {
00478         detail::if_fusion_seq< boost::fusion::traits::is_sequence<T>::value >::unpack(f, st,v);
00479     }
00480 
00481 
00482     template<typename Stream, typename T> 
00483     void pack( Stream& st, const T& v )  {
00484       mace::rpc::default_filter f;
00485       pack( f, st, v );
00486     }
00487 
00488     template<typename Stream, typename T> 
00489     void unpack( Stream& st, T& v ) {
00490       mace::rpc::default_filter f;
00491       unpack( f, st, v );
00492     }
00493 
00494     template<typename F, typename S, typename T>
00495     void apply_unpack_filter( F& f, S& s, T& t ) {
00496       if( f.is_filtered( &t ) ) {
00497         typename boost::remove_reference<decltype(f(T()))>::type r;
00498         unpack( f, s, r );
00499         f( r, t );
00500       } else {
00501         unpack( f, s, t );
00502       }
00503     }
00504     
00505 }  // namespace raw
00506 
00507   struct raw_io {
00508     template<typename T, typename Filter>
00509     static datavec pack( Filter& f, const T& v ) {
00510       std::stringstream ss;
00511       raw::pack( f, ss, v );
00512       std::string s = ss.str();
00513       slog( "s.size: %1%", s.size() );
00514       datavec rv(s.size());
00515       if( s.size() )
00516         memcpy(  &rv.front(), s.c_str(), s.size());
00517       return rv;
00518     }
00519     template<typename T, typename Filter>
00520     static T unpack( Filter& f, const datavec& d ) {
00521       T tmp;
00522       datastream<const char*> ds(&d.front(),d.size());
00523       raw::unpack( f, ds, tmp );
00524       return tmp;
00525     }
00526 
00527   };
00528 
00529 } } // mace::rpc
00530 
00531 #endif // MACE_RPC_RAW_RAW_IO_HPP