MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/json/value.hpp
00001 #ifndef _JSON_VALUE_HPP_
00002 #define _JSON_VALUE_HPP_
00003 #include <boost/variant/recursive_variant.hpp>
00004 #include <boost/lexical_cast.hpp>
00005 #include <boost/variant.hpp>
00006 #include <stdexcept>
00007 #include <vector>
00008 #include <map>
00009 #include <stdint.h>
00010 
00011 namespace mace { namespace rpc { namespace json {
00012 
00013 
00014     struct null_t{ 
00015         null_t(){}
00016         friend std::ostream& operator<<( std::ostream& os, const null_t&  ){ return os; }
00017     };
00018     class object;
00019     class array;
00020 
00021     typedef boost::variant<  null_t, double, bool, std::string, 
00022                              boost::recursive_wrapper<object>, 
00023                              boost::recursive_wrapper<array> > value_variant;
00024 
00028     class value {
00029       public:
00030        value();
00031        value( const value& c );
00032        value( const std::string& v );
00033        value( const array& a );
00034        value( const object& a );
00035        value( double v );
00036        value( bool v );
00037 
00038        operator int()const;
00039        operator int64_t()const;
00040        operator uint64_t()const;
00041        operator uint32_t()const;
00042        operator uint16_t()const;
00043        operator uint8_t()const;
00044        operator int16_t()const;
00045        operator int8_t()const;
00046        operator double()const;
00047        operator float()const;
00048        operator bool()const;
00049        operator std::string()const;
00050        //operator std::string&();
00051        operator const json::object&()const;
00052        operator json::object&();
00053        operator const json::array&()const;
00054        operator json::array&();
00055 
00056        value get( const std::string& key )const {
00057         if( contains(key) ) return (*this)[key];
00058         return key;
00059        }
00060        bool is_array()const;
00061        bool is_object()const;
00062        bool is_string()const;
00063        bool is_null()const;
00064        bool is_bool()const;
00065        bool is_real()const;
00066 
00067        bool operator == ( const null_t& t )const;
00068        inline bool   operator ==( const std::string& v )const { 
00069           return boost::get<const std::string&>(val) == v;
00070        }
00071        bool contains( const std::string& key )const;
00072 
00073 
00074        value& operator = ( int64_t v );
00075        value& operator = ( uint64_t v );
00076        value& operator = ( int32_t v );
00077        value& operator = ( uint32_t v );
00078        value& operator = ( int16_t v );
00079        value& operator = ( uint16_t v );
00080        value& operator = ( int8_t v );
00081        value& operator = ( uint8_t v );
00082        value& operator = ( double v );
00083        value& operator = ( bool v );
00084        value& operator = ( null_t v );
00085        value& operator = ( const std::string& v );
00086        value& operator = ( const char* v ) { return *this = std::string(v); }
00087        value& operator = ( const json::object& v );
00088        value& operator = ( const json::array& v );
00089 
00090        // treat it like an array or object
00091        value&        operator[]( const std::string& index );
00092        const value&  operator[]( const std::string& )const;
00093        value&        operator[]( const char* index );
00094        const value&  operator[]( const char* index )const;
00095        value&        operator[]( uint32_t index );
00096        const value&  operator[]( uint32_t index )const;
00097 
00098        size_t size();
00099        void   resize( uint32_t size );
00100        void   clear();
00101 
00102       // friend std::ostream& operator << ( std::ostream& os, const value& v );
00103       // friend std::istream& operator >> ( std::istream& os, const value& v );
00104 
00105         value_variant val;
00106     };
00107 
00108     void from_string( const std::string& j, value& v );
00109     void to_string( const value& v, std::string& j, bool pretty = false );
00110     std::ostream& write(std::ostream& os, const json::value& v, bool pretty = false );
00111 
00112     template<typename T>
00113     std::string to_string( const T& v, bool pretty = false ) {
00114       value jv; 
00115       jv <<  v;
00116       std::string str;
00117       to_string( jv, str );
00118       return str;
00119     }
00120 
00121 
00122     namespace detail {
00123         struct key_val {
00124             key_val( const std::string& k = "" ):key(k){}
00125             std::string key;
00126             value       val;
00127         };
00128     }
00129 
00130     class object {
00131       public:
00132         value& operator[]( const std::string& index );
00133         const value& operator[]( const std::string& index )const;
00134         friend std::ostream& operator<<( std::ostream& os, const object&  ){ return os; }
00135         inline void         clear() { keys.clear(); }
00136         inline void reserve( size_t s ) { keys.reserve(s); }
00137         bool contains( const std::string& key )const;
00138 
00139         std::vector< detail::key_val > keys;
00140     };
00141 
00142     class array {
00143       public:
00144         typedef std::vector<value>::const_iterator const_iterator;
00145 
00146         inline void            clear() { vals.clear(); }
00147         inline size_t          size()const { return vals.size(); }
00148         inline value&          operator[]( uint32_t idx )      { return vals[idx]; }
00149         inline const value&    operator[]( uint32_t idx )const { return vals[idx]; }
00150         inline value&          back()       { return vals.back();  }
00151         inline const value&    back()const  { return vals.back();  }
00152         inline const_iterator  begin()const { return vals.begin(); }
00153         inline void            push_back( const value& v ) { vals.push_back(v); }
00154         inline void            resize( size_t s ) { vals.resize(s); }
00155         inline void reserve( size_t s ) { vals.reserve(s); }
00156 
00157         friend std::ostream& operator<<( std::ostream& os, const array&  ){ return os; }
00158         std::vector< value > vals;
00159     };
00160 
00161 
00162 
00163     namespace detail {
00164        template<typename Result>
00165        struct cast_visitor : public boost::static_visitor<Result> {
00166           template<typename InType>
00167           Result operator()( const InType& d )const {
00168             return boost::lexical_cast<Result>(d);
00169           }
00170        };
00171        template<>
00172        struct cast_visitor<std::string> : public boost::static_visitor<std::string> {
00173           template<typename InType>
00174           std::string operator()( const InType& d )const {
00175             return boost::lexical_cast<std::string>(d);
00176           }
00177           std::string operator()( const null_t& d )const {
00178             return "null";
00179           }
00180           std::string operator()( const bool& d )const {
00181             return d ? "true" : "false";
00182           }
00183           std::string operator()( const json::array& d )const {
00184             return to_string(value(d));
00185           }
00186           std::string operator()( const json::object& d )const {
00187             return to_string(value(d));
00188           }
00189        };
00190 
00191        template<typename T>
00192        struct index_visitor : public boost::static_visitor<T> {
00193           index_visitor( int index = 0 ):m_index(index){}
00194           T operator()( const boost::variant<int,std::string,double,null_t>& )const {
00195             BOOST_THROW_EXCEPTION( std::out_of_range( "not an object or array" ) );
00196             typename boost::remove_reference<T>::type* val;
00197             return *val;
00198           }
00199           T operator()( const json::array& d )const {
00200             return d[m_index];
00201           }
00202           T operator()( const json::object& d )const {
00203             return d[boost::lexical_cast<std::string>(m_index)];
00204           }
00205           T operator()( json::array& d )const {
00206             return d[m_index];
00207           }
00208           T operator()( json::object& d )const {
00209             return d[boost::lexical_cast<std::string>(m_index)];
00210           }
00211           int m_index;
00212        };
00213        template<typename T>
00214        struct key_visitor : public boost::static_visitor<T> {
00215           key_visitor( const std::string& key, value& v ):m_val(v),m_key(key){}
00216 
00217           T operator()( const boost::variant<int,std::string,double,null_t>& )const {
00218             BOOST_THROW_EXCEPTION( std::out_of_range( "not an object or array" ) );
00219             typename boost::remove_reference<T>::type* val;
00220             return *val;
00221           }
00222           T operator()( const json::array& d )const {
00223             return d[boost::lexical_cast<int>(m_key)];
00224           }
00225           T operator()( const json::object& d )const {
00226             return d[m_key];
00227           }
00228           T operator()( null_t& )const {
00229             m_val = json::object();
00230             return m_val[m_key];
00231           }
00232           T operator()( json::array& d )const {
00233             return d[boost::lexical_cast<int>(m_key)];
00234           }
00235           T operator()( json::object& d )const {
00236             return d[m_key];
00237           }
00238           value&      m_val;
00239           std::string m_key;
00240        };
00241        template<typename T>
00242        struct const_key_visitor : public boost::static_visitor<T> {
00243           const_key_visitor( const std::string& key, const value& v ):m_val(v),m_key(key){}
00244 
00245           T operator()( const boost::variant<int,std::string,double,null_t>& )const {
00246             BOOST_THROW_EXCEPTION( std::out_of_range( "not an object or array" ) );
00247             typename boost::remove_reference<T>::type* val;
00248             return *val;
00249           }
00250           T operator()( const json::array& d )const {
00251             return d[boost::lexical_cast<int>(m_key)];
00252           }
00253           T operator()( const json::object& d )const {
00254             return d[m_key];
00255           }
00256           T operator()( json::array& d )const {
00257             return d[boost::lexical_cast<int>(m_key)];
00258           }
00259           T operator()( json::object& d )const {
00260             return d[m_key];
00261           }
00262           const value&      m_val;
00263           std::string m_key;
00264        };
00265     }
00266 
00267     value&       operator<<(value& jv, const value& v );
00268     const value& operator>>(const value& jv, value& v );
00269 
00270     template<typename T>
00271     value& operator<<(value& jv, const std::vector<T>& v ) {
00272       json::array& a = jv = json::array();            
00273       a.resize(v.size());
00274       for( uint32_t i = 0; i < v.size(); ++i ) 
00275         a[i] << v[i];
00276       return jv;
00277     }
00278 
00279     template<typename T>
00280     const value& operator>>(const value& jv, std::vector<T>& v ) {
00281       const json::array& a = jv;
00282       v.resize(a.size());
00283       for( uint32_t i = 0; i < v.size(); ++i ) 
00284         a[i] >> v[i];
00285       return jv;
00286     }
00287 
00288 } } } // namespace mace::rpc::json
00289 
00290 
00291 #endif