MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/json/value_io.hpp
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