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