You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

json_spirit_value.h 14KB

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