Projects : bitcoin : bitcoin_checkblocks_cleanup

bitcoin/src/json/json_spirit_value.h

Dir - Raw

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