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