json_spirit_value.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. #ifndef JSON_SPIRIT_VALUE
  2. #define JSON_SPIRIT_VALUE
  3. // Copyright John W. Wilkinson 2007 - 2009.
  4. // Distributed under the MIT License, see accompanying file LICENSE.txt
  5. // json spirit version 4.03
  6. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  7. # pragma once
  8. #endif
  9. #include <vector>
  10. #include <map>
  11. #include <string>
  12. #include <cassert>
  13. #include <sstream>
  14. #include <stdexcept>
  15. #include <boost/config.hpp>
  16. #include <boost/cstdint.hpp>
  17. #include <boost/shared_ptr.hpp>
  18. #include <boost/variant.hpp>
  19. namespace json_spirit
  20. {
  21. enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
  22. template< class Config > // Config determines whether the value uses std::string or std::wstring and
  23. // whether JSON Objects are represented as vectors or maps
  24. class Value_impl
  25. {
  26. public:
  27. typedef Config Config_type;
  28. typedef typename Config::String_type String_type;
  29. typedef typename Config::Object_type Object;
  30. typedef typename Config::Array_type Array;
  31. typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
  32. Value_impl(); // creates null value
  33. Value_impl( Const_str_ptr value );
  34. Value_impl( const String_type& value );
  35. Value_impl( const Object& value );
  36. Value_impl( const Array& value );
  37. Value_impl( bool value );
  38. Value_impl( int value );
  39. Value_impl( boost::int64_t value );
  40. Value_impl( boost::uint64_t value );
  41. Value_impl( double value );
  42. Value_impl( const Value_impl& other );
  43. bool operator==( const Value_impl& lhs ) const;
  44. Value_impl& operator=( const Value_impl& lhs );
  45. Value_type type() const;
  46. bool is_uint64() const;
  47. bool is_null() const;
  48. const String_type& get_str() const;
  49. const Object& get_obj() const;
  50. const Array& get_array() const;
  51. bool get_bool() const;
  52. int get_int() const;
  53. boost::int64_t get_int64() const;
  54. boost::uint64_t get_uint64() const;
  55. double get_real() const;
  56. Object& get_obj();
  57. Array& get_array();
  58. template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
  59. // or double d = value.get_value< double >();
  60. static const Value_impl null;
  61. private:
  62. void check_type( const Value_type vtype ) const;
  63. typedef boost::variant< String_type,
  64. boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
  65. bool, boost::int64_t, double > Variant;
  66. Value_type type_;
  67. Variant v_;
  68. bool is_uint64_;
  69. };
  70. // vector objects
  71. template< class Config >
  72. struct Pair_impl
  73. {
  74. typedef typename Config::String_type String_type;
  75. typedef typename Config::Value_type Value_type;
  76. Pair_impl( const String_type& name, const Value_type& value );
  77. bool operator==( const Pair_impl& lhs ) const;
  78. String_type name_;
  79. Value_type value_;
  80. };
  81. template< class String >
  82. struct Config_vector
  83. {
  84. typedef String String_type;
  85. typedef Value_impl< Config_vector > Value_type;
  86. typedef Pair_impl < Config_vector > Pair_type;
  87. typedef std::vector< Value_type > Array_type;
  88. typedef std::vector< Pair_type > Object_type;
  89. static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
  90. {
  91. obj.push_back( Pair_type( name , value ) );
  92. return obj.back().value_;
  93. }
  94. static String_type get_name( const Pair_type& pair )
  95. {
  96. return pair.name_;
  97. }
  98. static Value_type get_value( const Pair_type& pair )
  99. {
  100. return pair.value_;
  101. }
  102. };
  103. // typedefs for ASCII
  104. typedef Config_vector< std::string > Config;
  105. typedef Config::Value_type Value;
  106. typedef Config::Pair_type Pair;
  107. typedef Config::Object_type Object;
  108. typedef Config::Array_type Array;
  109. // typedefs for Unicode
  110. #ifndef BOOST_NO_STD_WSTRING
  111. typedef Config_vector< std::wstring > wConfig;
  112. typedef wConfig::Value_type wValue;
  113. typedef wConfig::Pair_type wPair;
  114. typedef wConfig::Object_type wObject;
  115. typedef wConfig::Array_type wArray;
  116. #endif
  117. // map objects
  118. template< class String >
  119. struct Config_map
  120. {
  121. typedef String String_type;
  122. typedef Value_impl< Config_map > Value_type;
  123. typedef std::vector< Value_type > Array_type;
  124. typedef std::map< String_type, Value_type > Object_type;
  125. typedef typename Object_type::value_type Pair_type;
  126. static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
  127. {
  128. return obj[ name ] = value;
  129. }
  130. static String_type get_name( const Pair_type& pair )
  131. {
  132. return pair.first;
  133. }
  134. static Value_type get_value( const Pair_type& pair )
  135. {
  136. return pair.second;
  137. }
  138. };
  139. // typedefs for ASCII
  140. typedef Config_map< std::string > mConfig;
  141. typedef mConfig::Value_type mValue;
  142. typedef mConfig::Object_type mObject;
  143. typedef mConfig::Array_type mArray;
  144. // typedefs for Unicode
  145. #ifndef BOOST_NO_STD_WSTRING
  146. typedef Config_map< std::wstring > wmConfig;
  147. typedef wmConfig::Value_type wmValue;
  148. typedef wmConfig::Object_type wmObject;
  149. typedef wmConfig::Array_type wmArray;
  150. #endif
  151. ///////////////////////////////////////////////////////////////////////////////////////////////
  152. //
  153. // implementation
  154. template< class Config >
  155. const Value_impl< Config > Value_impl< Config >::null;
  156. template< class Config >
  157. Value_impl< Config >::Value_impl()
  158. : type_( null_type )
  159. , is_uint64_( false )
  160. {
  161. }
  162. template< class Config >
  163. Value_impl< Config >::Value_impl( const Const_str_ptr value )
  164. : type_( str_type )
  165. , v_( String_type( value ) )
  166. , is_uint64_( false )
  167. {
  168. }
  169. template< class Config >
  170. Value_impl< Config >::Value_impl( const String_type& value )
  171. : type_( str_type )
  172. , v_( value )
  173. , is_uint64_( false )
  174. {
  175. }
  176. template< class Config >
  177. Value_impl< Config >::Value_impl( const Object& value )
  178. : type_( obj_type )
  179. , v_( value )
  180. , is_uint64_( false )
  181. {
  182. }
  183. template< class Config >
  184. Value_impl< Config >::Value_impl( const Array& value )
  185. : type_( array_type )
  186. , v_( value )
  187. , is_uint64_( false )
  188. {
  189. }
  190. template< class Config >
  191. Value_impl< Config >::Value_impl( bool value )
  192. : type_( bool_type )
  193. , v_( value )
  194. , is_uint64_( false )
  195. {
  196. }
  197. template< class Config >
  198. Value_impl< Config >::Value_impl( int value )
  199. : type_( int_type )
  200. , v_( static_cast< boost::int64_t >( value ) )
  201. , is_uint64_( false )
  202. {
  203. }
  204. template< class Config >
  205. Value_impl< Config >::Value_impl( boost::int64_t value )
  206. : type_( int_type )
  207. , v_( value )
  208. , is_uint64_( false )
  209. {
  210. }
  211. template< class Config >
  212. Value_impl< Config >::Value_impl( boost::uint64_t value )
  213. : type_( int_type )
  214. , v_( static_cast< boost::int64_t >( value ) )
  215. , is_uint64_( true )
  216. {
  217. }
  218. template< class Config >
  219. Value_impl< Config >::Value_impl( double value )
  220. : type_( real_type )
  221. , v_( value )
  222. , is_uint64_( false )
  223. {
  224. }
  225. template< class Config >
  226. Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
  227. : type_( other.type() )
  228. , v_( other.v_ )
  229. , is_uint64_( other.is_uint64_ )
  230. {
  231. }
  232. template< class Config >
  233. Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
  234. {
  235. Value_impl tmp( lhs );
  236. std::swap( type_, tmp.type_ );
  237. std::swap( v_, tmp.v_ );
  238. std::swap( is_uint64_, tmp.is_uint64_ );
  239. return *this;
  240. }
  241. template< class Config >
  242. bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
  243. {
  244. if( this == &lhs ) return true;
  245. if( type() != lhs.type() ) return false;
  246. return v_ == lhs.v_;
  247. }
  248. template< class Config >
  249. Value_type Value_impl< Config >::type() const
  250. {
  251. return type_;
  252. }
  253. template< class Config >
  254. bool Value_impl< Config >::is_uint64() const
  255. {
  256. return is_uint64_;
  257. }
  258. template< class Config >
  259. bool Value_impl< Config >::is_null() const
  260. {
  261. return type() == null_type;
  262. }
  263. template< class Config >
  264. void Value_impl< Config >::check_type( const Value_type vtype ) const
  265. {
  266. if( type() != vtype )
  267. {
  268. std::ostringstream os;
  269. os << "value type is " << type() << " not " << vtype;
  270. throw std::runtime_error( os.str() );
  271. }
  272. }
  273. template< class Config >
  274. const typename Config::String_type& Value_impl< Config >::get_str() const
  275. {
  276. check_type( str_type );
  277. return *boost::get< String_type >( &v_ );
  278. }
  279. template< class Config >
  280. const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
  281. {
  282. check_type( obj_type );
  283. return *boost::get< Object >( &v_ );
  284. }
  285. template< class Config >
  286. const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
  287. {
  288. check_type( array_type );
  289. return *boost::get< Array >( &v_ );
  290. }
  291. template< class Config >
  292. bool Value_impl< Config >::get_bool() const
  293. {
  294. check_type( bool_type );
  295. return boost::get< bool >( v_ );
  296. }
  297. template< class Config >
  298. int Value_impl< Config >::get_int() const
  299. {
  300. check_type( int_type );
  301. return static_cast< int >( get_int64() );
  302. }
  303. template< class Config >
  304. boost::int64_t Value_impl< Config >::get_int64() const
  305. {
  306. check_type( int_type );
  307. return boost::get< boost::int64_t >( v_ );
  308. }
  309. template< class Config >
  310. boost::uint64_t Value_impl< Config >::get_uint64() const
  311. {
  312. check_type( int_type );
  313. return static_cast< boost::uint64_t >( get_int64() );
  314. }
  315. template< class Config >
  316. double Value_impl< Config >::get_real() const
  317. {
  318. if( type() == int_type )
  319. {
  320. return is_uint64() ? static_cast< double >( get_uint64() )
  321. : static_cast< double >( get_int64() );
  322. }
  323. check_type( real_type );
  324. return boost::get< double >( v_ );
  325. }
  326. template< class Config >
  327. typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
  328. {
  329. check_type( obj_type );
  330. return *boost::get< Object >( &v_ );
  331. }
  332. template< class Config >
  333. typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
  334. {
  335. check_type( array_type );
  336. return *boost::get< Array >( &v_ );
  337. }
  338. template< class Config >
  339. Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
  340. : name_( name )
  341. , value_( value )
  342. {
  343. }
  344. template< class Config >
  345. bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
  346. {
  347. if( this == &lhs ) return true;
  348. return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
  349. }
  350. // converts a C string, ie. 8 bit char array, to a string object
  351. //
  352. template < class String_type >
  353. String_type to_str( const char* c_str )
  354. {
  355. String_type result;
  356. for( const char* p = c_str; *p != 0; ++p )
  357. {
  358. result += *p;
  359. }
  360. return result;
  361. }
  362. //
  363. namespace internal_
  364. {
  365. template< typename T >
  366. struct Type_to_type
  367. {
  368. };
  369. template< class Value >
  370. int get_value( const Value& value, Type_to_type< int > )
  371. {
  372. return value.get_int();
  373. }
  374. template< class Value >
  375. boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
  376. {
  377. return value.get_int64();
  378. }
  379. template< class Value >
  380. boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
  381. {
  382. return value.get_uint64();
  383. }
  384. template< class Value >
  385. double get_value( const Value& value, Type_to_type< double > )
  386. {
  387. return value.get_real();
  388. }
  389. template< class Value >
  390. typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
  391. {
  392. return value.get_str();
  393. }
  394. template< class Value >
  395. typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
  396. {
  397. return value.get_array();
  398. }
  399. template< class Value >
  400. typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
  401. {
  402. return value.get_obj();
  403. }
  404. template< class Value >
  405. bool get_value( const Value& value, Type_to_type< bool > )
  406. {
  407. return value.get_bool();
  408. }
  409. }
  410. template< class Config >
  411. template< typename T >
  412. T Value_impl< Config >::get_value() const
  413. {
  414. return internal_::get_value( *this, internal_::Type_to_type< T >() );
  415. }
  416. }
  417. #endif