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