json_spirit_value.h 13 KB

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