Bytemaster's Boost Libraries
|
00001 #ifndef _BOOST_RPC_RAW_HPP_ 00002 #define _BOOST_RPC_RAW_HPP_ 00003 #include <boost/reflect/reflect.hpp> 00004 00005 #include <boost/rpc/varint.hpp> 00006 #include <boost/rpc/required.hpp> 00007 #include <boost/rpc/errors.hpp> 00008 #include <boost/cmt/log/log.hpp> 00009 #include <boost/rpc/base64.hpp> 00010 #include <sstream> 00011 #include <iostream> 00012 #include <map> 00013 #include <iomanip> 00014 00015 #include <boost/fusion/container/vector.hpp> 00016 #include <boost/fusion/algorithm.hpp> 00017 #include <boost/fusion/support/is_sequence.hpp> 00018 #include <boost/fusion/sequence/intrinsic/size.hpp> 00019 00020 namespace boost { namespace rpc { namespace raw { 00021 00022 template<typename Stream, typename T> 00023 inline void pack( Stream& s, const T& v ); 00024 template<typename Stream, typename T> 00025 inline void unpack( Stream& s, T& v ); 00026 template<typename Stream, typename T, typename Alloc, template<typename,typename> class Container> 00027 inline void pack( Stream& s, const Container<T,Alloc>& value ); 00028 template<typename Stream, typename T, typename Alloc, template<typename,typename> class Container> 00029 inline void unpack( Stream& s, Container<T,Alloc>& value ); 00030 template<typename Stream, typename Key, typename Value> 00031 void pack( Stream& s, const std::map<Key,Value>& value ); 00032 template<typename Stream, typename Key, typename Value> 00033 void unpack( Stream& s, std::map<Key,Value>& value ); 00034 00035 template<typename Stream> inline void pack( Stream& s, const signed_int& v ) { 00036 uint32_t val = (v.value<<1) ^ (v.value>>31); 00037 do { 00038 uint8_t b = uint8_t(val) & 0x7f; 00039 val >>= 7; 00040 b |= ((val > 0) << 7); 00041 s.put(b); 00042 } while( val ); 00043 } 00044 template<typename Stream> inline void pack( Stream& s, const unsigned_int& v ) { 00045 uint64_t val = v.value; 00046 do { 00047 uint8_t b = uint8_t(val) & 0x7f; 00048 val >>= 7; 00049 b |= ((val > 0) << 7); 00050 s.put(b); 00051 }while( val ); 00052 } 00053 00054 00055 template<typename Stream> inline void pack( Stream& s, const bool& v ) { pack( s, uint8_t(v) ); } 00056 template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, std::string(v) ); } 00057 00058 template<typename Stream, typename T> 00059 inline void pack( Stream& s, const required<T>& v ) { pack( s, *v); } 00060 00061 template<typename Stream, typename T> 00062 inline void pack( Stream& s, const boost::optional<T>& v ) { 00063 pack( s, bool(v) ); 00064 if( v ) 00065 pack( s, *v ); 00066 } 00067 template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) { 00068 pack( s, unsigned_int(value.size()) ); 00069 if( value.size() ) 00070 s.write( &value.front(), value.size() ); 00071 } 00072 template<typename Stream> inline void pack( Stream& s, const std::string& v ) { 00073 pack( s, unsigned_int(v.size()) ); 00074 if( v.size() ) 00075 s.write( v.c_str(), v.size() ); 00076 } 00077 00078 template<typename Stream> inline void unpack( Stream& s, signed_int& vi ) { 00079 uint32_t v = 0; char b = 0; int by = 0; 00080 do { 00081 s.get(b); 00082 v |= uint32_t(uint8_t(b) & 0x7f) << by; 00083 by += 7; 00084 } while( uint8_t(b) & 0x80 ); 00085 vi.value = ((v>>1) ^ (v>>31)) + (v&0x01); 00086 vi.value = v&0x01 ? vi.value : -vi.value; 00087 vi.value = -vi.value; 00088 } 00089 template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi ) { 00090 uint64_t v = 0; char b = 0; uint8_t by = 0; 00091 do { 00092 s.get(b); 00093 v |= uint32_t(uint8_t(b) & 0x7f) << by; 00094 by += 7; 00095 } while( uint8_t(b) & 0x80 ); 00096 vi.value = v; 00097 } 00098 template<typename Stream> inline void unpack( Stream& s, bool& v ) { 00099 uint8_t b; 00100 unpack( s, b ); 00101 v=b; 00102 } 00103 template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) { 00104 unsigned_int size; unpack( s, size ); 00105 value.resize(size.value); 00106 if( value.size() ) 00107 s.read( &value.front(), value.size() ); 00108 } 00109 template<typename Stream> inline void unpack( Stream& s, std::string& v ) { 00110 std::vector<char> tmp; unpack(s,tmp); 00111 v = std::string(tmp.begin(),tmp.end()); 00112 } 00113 00114 template<typename Stream, typename T> 00115 void unpack( const Stream& s, boost::optional<T>& v ) { 00116 bool b; unpack( s, b ); 00117 if( b ) { v = T(); unpack( s, *v ); } 00118 } 00119 template<typename Stream, typename T> 00120 void unpack( const Stream& s, required<T>& v ) { 00121 v = T(); unpack( s, *v ); 00122 } 00123 template<typename Stream, typename T, typename Alloc, template<typename,typename> class Container> 00124 void unpack( const Stream& s, Container<T,Alloc>& value ); 00125 template<typename Stream, typename Key, typename Value> 00126 void unpack( const Stream& s, std::map<Key,Value>& value ); 00127 template<typename Stream, typename Key, typename Value> 00128 void unpack( const Stream& s, std::pair<Key,Value>& value ); 00129 template<typename Stream, typename Value> 00130 void unpack( const Stream& s, std::map<std::string,Value>& val ); 00131 00132 namespace detail { 00133 00134 template<typename Stream, typename Class> 00135 struct pack_object_visitor { 00136 pack_object_visitor(const Class& _c, Stream& _s) 00137 :c(_c),s(_s){} 00138 00143 template<typename T> 00144 inline void pack_helper( const T& v, const char* name )const { 00145 boost::rpc::raw::pack( s, v ); 00146 } 00147 template<typename T> 00148 inline void pack_helper( const boost::optional<T>& v, const char* name )const { 00149 if( !!v ) boost::rpc::raw::pack( s, *v ); 00150 } 00151 template<typename T, typename C, T(C::*p)> 00152 inline void operator()( const char* name )const { 00153 pack_helper( c.*p, name ); 00154 } 00155 private: 00156 const Class& c; 00157 Stream& s; 00158 }; 00159 00160 template<typename Stream, typename Class> 00161 struct unpack_object_visitor { 00162 unpack_object_visitor(Class& _c, Stream& _s) 00163 :c(_c),s(_s){} 00164 00165 template<typename T, typename C, T(C::*p)> 00166 inline void operator()( const char* name )const { 00167 boost::rpc::raw::unpack( s, c.*p ); 00168 } 00169 private: 00170 Class& c; 00171 Stream& s; 00172 }; 00173 00174 template<typename Stream> 00175 struct pack_sequence { 00176 pack_sequence( Stream& _s ):s(_s){} 00177 template<typename T> 00178 void operator() ( const T& v )const { boost::rpc::raw::pack(s,v); } 00179 Stream& s; 00180 }; 00181 00182 template<typename Stream> 00183 struct unpack_sequence { 00184 unpack_sequence( Stream& _s ):s(_s){} 00185 template<typename T> 00186 void operator() ( T& v )const { boost::rpc::raw::unpack(s,v); } 00187 Stream& s; 00188 }; 00189 00190 00191 template<typename IsReflected=boost::false_type> 00192 struct if_reflected { 00193 template<typename Stream, typename T> 00194 static inline void pack( Stream& s, const T& v ) { 00195 BOOST_STATIC_ASSERT( boost::is_pod<T>::value ); 00196 s.write( (char*)&v, sizeof(v) ); 00197 } 00198 template<typename Stream, typename T> 00199 static inline void unpack( Stream& s, T& v ) { 00200 BOOST_STATIC_ASSERT( boost::is_pod<T>::value ); 00201 s.read( (char*)&v, sizeof(v) ); 00202 } 00203 }; 00204 template<> 00205 struct if_reflected<boost::true_type> { 00206 template<typename Stream, typename T> 00207 static inline void pack( Stream& s, const T& v ) { 00208 boost::reflect::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s ) ); 00209 } 00210 template<typename Stream, typename T> 00211 static inline void unpack( Stream& s, T& v ) { 00212 boost::reflect::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s ) ); 00213 } 00214 }; 00215 00216 template<typename IsFusionSeq> 00217 struct if_fusion_seq { 00218 template<typename Stream, typename T> 00219 inline static void pack( Stream& s, const T& v ) { 00220 pack_sequence<Stream> pack_vector( s ); 00221 boost::fusion::for_each( v, pack_vector ); 00222 } 00223 template<typename Stream, typename T> 00224 inline static void unpack( Stream& s, T& v ) { 00225 unpack_sequence<Stream> unpack_vector(s); 00226 boost::fusion::for_each( v, unpack_vector ); 00227 } 00228 }; 00229 00230 template<> 00231 struct if_fusion_seq<boost::mpl::false_> { 00232 template<typename Stream, typename T> 00233 inline static void pack( Stream& s, const T& v ) { 00234 if_reflected<typename boost::reflect::reflector<T>::is_defined>::pack(s,v); 00235 } 00236 template<typename Stream, typename T> 00237 inline static void unpack( Stream& s, T& v ) { 00238 if_reflected<typename boost::reflect::reflector<T>::is_defined>::unpack(s,v); 00239 } 00240 }; 00241 } // namesapce detail 00242 00243 00244 00245 template<typename Stream, typename T, typename Alloc, template<typename,typename> class Container> 00246 inline void pack( Stream& s, const Container<T,Alloc>& value ) { 00247 pack( s, unsigned_int(value.size()) ); 00248 typename Container<T,Alloc>::const_iterator itr = value.begin(); 00249 typename Container<T,Alloc>::const_iterator end = value.end(); 00250 while( itr != end ) { 00251 boost::rpc::raw::pack( s, *itr ); 00252 ++itr; 00253 } 00254 } 00255 00256 template<typename Stream, typename T, typename Alloc, template<typename,typename> class Container> 00257 inline void unpack( Stream& s, Container<T,Alloc>& value ) { 00258 unsigned_int size; unpack( s, size ); 00259 value.resize(size.value); 00260 typename Container<T,Alloc>::iterator itr = value.begin(); 00261 typename Container<T,Alloc>::iterator end = value.end(); 00262 while( itr != end ) { 00263 boost::rpc::raw::unpack( s, *itr ); 00264 ++itr; 00265 } 00266 } 00267 00268 // support for pair! 00269 template<typename Stream, typename Key, typename Value> 00270 inline void pack( Stream& s, const std::pair<Key,Value>& val ) { 00271 boost::rpc::raw::pack( s, val.first ); 00272 boost::rpc::raw::pack( s, val.second ); 00273 } 00274 // support for pair! 00275 template<typename Stream, typename Key, typename Value> 00276 void unpack( Stream& s, std::pair<Key,Value>& val ) { 00277 boost::rpc::raw::unpack( s, val.first ); 00278 boost::rpc::raw::unpack( s, val.second ); 00279 } 00280 00281 00282 // support arbitrary key/value containers as an array of pairs 00283 template<typename Stream, typename Key, typename Value> 00284 void pack( Stream& s, const std::map<Key,Value>& value ) { 00285 pack( s, unsigned_int(value.size()) ); 00286 typename std::map<Key,Value>::const_iterator itr = value.begin(); 00287 typename std::map<Key,Value>::const_iterator end = value.end(); 00288 while( itr != end ) { 00289 boost::rpc::raw::pack( s, *itr ); 00290 ++itr; 00291 } 00292 } 00293 00294 template<typename Stream, typename Key, typename Value> 00295 inline void unpack( Stream& s, std::map<Key,Value>& value ) { 00296 unsigned_int size; unpack( s, size ); 00297 value.clear(); 00298 for( uint32_t i = 0; i < size.value; ++i ) { 00299 Key k; 00300 boost::rpc::raw::unpack(s,k); 00301 boost::rpc::raw::unpack(s,value[k]); 00302 } 00303 } 00304 template<typename Stream, typename T> 00305 inline void pack( Stream& s, const T& v ) { 00306 detail::if_fusion_seq< typename boost::fusion::traits::is_sequence<T>::type >::pack(s,v); 00307 } 00308 template<typename Stream, typename T> 00309 inline void unpack( Stream& s, T& v ) { 00310 detail::if_fusion_seq< typename boost::fusion::traits::is_sequence<T>::type >::unpack(s,v); 00311 } 00312 00313 } } } // namespace boost::rpc::raw 00314 00315 #endif // BOOST_RPC_RAW_HPP