MACE
1.0.0
|
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