Better wording for transaction fee notification messages
[novacoin.git] / 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/cstdint.hpp> 
21 #include <boost/shared_ptr.hpp> 
22 #include <boost/variant.hpp> 
23
24 namespace 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