~ubuntu-branches/ubuntu/precise/bitcoin/precise

« back to all changes in this revision

Viewing changes to src/json/json_spirit_value.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2011-01-17 19:48:35 UTC
  • Revision ID: james.westby@ubuntu.com-20110117194835-a3kljf7m1pcv2bbn
Tags: upstream-0.3.19~dfsg
ImportĀ upstreamĀ versionĀ 0.3.19~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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