Back to home page

Bitcoin sources

 
 

    


File indexing completed on 2020-06-25 15:43:22

0001 #ifndef JSON_SPIRIT_VALUE
0002 #define JSON_SPIRIT_VALUE
0003 
0004 //          Copyright John W. Wilkinson 2007 - 2009.
0005 // Distributed under the MIT License, see accompanying file LICENSE.txt
0006 
0007 // json spirit version 4.03
0008 
0009 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0010 # pragma once
0011 #endif
0012 
0013 #include <vector>
0014 #include <map>
0015 #include <string>
0016 #include <cassert>
0017 #include <sstream>
0018 #include <stdexcept>
0019 #include <boost/config.hpp> 
0020 #include <boost/cstdint.hpp> 
0021 #include <boost/shared_ptr.hpp> 
0022 #include <boost/variant.hpp> 
0023 
0024 namespace json_spirit
0025 {
0026     enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
0027     static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
0028 
0029     template< class Config >    // Config determines whether the value uses std::string or std::wstring and
0030                                 // whether JSON Objects are represented as vectors or maps
0031     class Value_impl
0032     {
0033     public:
0034 
0035         typedef Config Config_type;
0036         typedef typename Config::String_type String_type;
0037         typedef typename Config::Object_type Object;
0038         typedef typename Config::Array_type Array;
0039         typedef typename String_type::const_pointer Const_str_ptr;  // eg const char*
0040 
0041         Value_impl();  // creates null value
0042         Value_impl( Const_str_ptr      value ); 
0043         Value_impl( const String_type& value );
0044         Value_impl( const Object&      value );
0045         Value_impl( const Array&       value );
0046         Value_impl( bool               value );
0047         Value_impl( int                value );
0048         Value_impl( boost::int64_t     value );
0049         Value_impl( boost::uint64_t    value );
0050         Value_impl( double             value );
0051 
0052         Value_impl( const Value_impl& other );
0053 
0054         bool operator==( const Value_impl& lhs ) const;
0055 
0056         Value_impl& operator=( const Value_impl& lhs );
0057 
0058         Value_type type() const;
0059 
0060         bool is_uint64() const;
0061         bool is_null() const;
0062 
0063         const String_type& get_str()    const;
0064         const Object&      get_obj()    const;
0065         const Array&       get_array()  const;
0066         bool               get_bool()   const;
0067         int                get_int()    const;
0068         boost::int64_t     get_int64()  const;
0069         boost::uint64_t    get_uint64() const;
0070         double             get_real()   const;
0071 
0072         Object& get_obj();
0073         Array&  get_array();
0074 
0075         template< typename T > T get_value() const;  // example usage: int    i = value.get_value< int >();
0076                                                      // or             double d = value.get_value< double >();
0077 
0078         static const Value_impl null;
0079 
0080     private:
0081 
0082         void check_type( const Value_type vtype ) const;
0083 
0084         typedef boost::variant< String_type, 
0085                                 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, 
0086                                 bool, boost::int64_t, double > Variant;
0087 
0088         Value_type type_;
0089         Variant v_;
0090         bool is_uint64_;
0091     };
0092 
0093     // vector objects
0094 
0095     template< class Config >
0096     struct Pair_impl
0097     {
0098         typedef typename Config::String_type String_type;
0099         typedef typename Config::Value_type Value_type;
0100 
0101         Pair_impl( const String_type& name, const Value_type& value );
0102 
0103         bool operator==( const Pair_impl& lhs ) const;
0104 
0105         String_type name_;
0106         Value_type value_;
0107     };
0108 
0109     template< class String >
0110     struct Config_vector
0111     {
0112         typedef String String_type;
0113         typedef Value_impl< Config_vector > Value_type;
0114         typedef Pair_impl < Config_vector > Pair_type;
0115         typedef std::vector< Value_type > Array_type;
0116         typedef std::vector< Pair_type > Object_type;
0117 
0118         static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
0119         {
0120             obj.push_back( Pair_type( name , value ) );
0121 
0122             return obj.back().value_;
0123         }
0124                 
0125         static String_type get_name( const Pair_type& pair )
0126         {
0127             return pair.name_;
0128         }
0129                 
0130         static Value_type get_value( const Pair_type& pair )
0131         {
0132             return pair.value_;
0133         }
0134     };
0135 
0136     // typedefs for ASCII
0137 
0138     typedef Config_vector< std::string > Config;
0139 
0140     typedef Config::Value_type  Value;
0141     typedef Config::Pair_type   Pair;
0142     typedef Config::Object_type Object;
0143     typedef Config::Array_type  Array;
0144 
0145     // typedefs for Unicode
0146 
0147 #ifndef BOOST_NO_STD_WSTRING
0148 
0149     typedef Config_vector< std::wstring > wConfig;
0150 
0151     typedef wConfig::Value_type  wValue;
0152     typedef wConfig::Pair_type   wPair;
0153     typedef wConfig::Object_type wObject;
0154     typedef wConfig::Array_type  wArray;
0155 #endif
0156 
0157     // map objects
0158 
0159     template< class String >
0160     struct Config_map
0161     {
0162         typedef String String_type;
0163         typedef Value_impl< Config_map > Value_type;
0164         typedef std::vector< Value_type > Array_type;
0165         typedef std::map< String_type, Value_type > Object_type;
0166         typedef typename Object_type::value_type Pair_type;
0167 
0168         static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
0169         {
0170             return obj[ name ] = value;
0171         }
0172                 
0173         static String_type get_name( const Pair_type& pair )
0174         {
0175             return pair.first;
0176         }
0177                 
0178         static Value_type get_value( const Pair_type& pair )
0179         {
0180             return pair.second;
0181         }
0182     };
0183 
0184     // typedefs for ASCII
0185 
0186     typedef Config_map< std::string > mConfig;
0187 
0188     typedef mConfig::Value_type  mValue;
0189     typedef mConfig::Object_type mObject;
0190     typedef mConfig::Array_type  mArray;
0191 
0192     // typedefs for Unicode
0193 
0194 #ifndef BOOST_NO_STD_WSTRING
0195 
0196     typedef Config_map< std::wstring > wmConfig;
0197 
0198     typedef wmConfig::Value_type  wmValue;
0199     typedef wmConfig::Object_type wmObject;
0200     typedef wmConfig::Array_type  wmArray;
0201 
0202 #endif
0203 
0204     ///////////////////////////////////////////////////////////////////////////////////////////////
0205     //
0206     // implementation
0207 
0208     template< class Config >
0209     const Value_impl< Config > Value_impl< Config >::null;
0210 
0211     template< class Config >
0212     Value_impl< Config >::Value_impl()
0213     :   type_( null_type )
0214     ,   is_uint64_( false )
0215     {
0216     }
0217 
0218     template< class Config >
0219     Value_impl< Config >::Value_impl( const Const_str_ptr value )
0220     :   type_( str_type )
0221     ,   v_( String_type( value ) )
0222     ,   is_uint64_( false )
0223     {
0224     }
0225 
0226     template< class Config >
0227     Value_impl< Config >::Value_impl( const String_type& value )
0228     :   type_( str_type )
0229     ,   v_( value )
0230     ,   is_uint64_( false )
0231     {
0232     }
0233 
0234     template< class Config >
0235     Value_impl< Config >::Value_impl( const Object& value )
0236     :   type_( obj_type )
0237     ,   v_( value )
0238     ,   is_uint64_( false )
0239     {
0240     }
0241 
0242     template< class Config >
0243     Value_impl< Config >::Value_impl( const Array& value )
0244     :   type_( array_type )
0245     ,   v_( value )
0246     ,   is_uint64_( false )
0247     {
0248     }
0249 
0250     template< class Config >
0251     Value_impl< Config >::Value_impl( bool value )
0252     :   type_( bool_type )
0253     ,   v_( value )
0254     ,   is_uint64_( false )
0255     {
0256     }
0257 
0258     template< class Config >
0259     Value_impl< Config >::Value_impl( int value )
0260     :   type_( int_type )
0261     ,   v_( static_cast< boost::int64_t >( value ) )
0262     ,   is_uint64_( false )
0263     {
0264     }
0265 
0266     template< class Config >
0267     Value_impl< Config >::Value_impl( boost::int64_t value )
0268     :   type_( int_type )
0269     ,   v_( value )
0270     ,   is_uint64_( false )
0271     {
0272     }
0273 
0274     template< class Config >
0275     Value_impl< Config >::Value_impl( boost::uint64_t value )
0276     :   type_( int_type )
0277     ,   v_( static_cast< boost::int64_t >( value ) )
0278     ,   is_uint64_( true )
0279     {
0280     }
0281 
0282     template< class Config >
0283     Value_impl< Config >::Value_impl( double value )
0284     :   type_( real_type )
0285     ,   v_( value )
0286     ,   is_uint64_( false )
0287     {
0288     }
0289 
0290     template< class Config >
0291     Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
0292     :   type_( other.type() )
0293     ,   v_( other.v_ )
0294     ,   is_uint64_( other.is_uint64_ )
0295     {
0296     }
0297 
0298     template< class Config >
0299     Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
0300     {
0301         Value_impl tmp( lhs );
0302 
0303         std::swap( type_, tmp.type_ );
0304         std::swap( v_, tmp.v_ );
0305         std::swap( is_uint64_, tmp.is_uint64_ );
0306 
0307         return *this;
0308     }
0309 
0310     template< class Config >
0311     bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
0312     {
0313         if( this == &lhs ) return true;
0314 
0315         if( type() != lhs.type() ) return false;
0316 
0317         return v_ == lhs.v_; 
0318     }
0319 
0320     template< class Config >
0321     Value_type Value_impl< Config >::type() const
0322     {
0323         return type_;
0324     }
0325 
0326     template< class Config >
0327     bool Value_impl< Config >::is_uint64() const
0328     {
0329         return is_uint64_;
0330     }
0331 
0332     template< class Config >
0333     bool Value_impl< Config >::is_null() const
0334     {
0335         return type() == null_type;
0336     }
0337 
0338     template< class Config >
0339     void Value_impl< Config >::check_type( const Value_type vtype ) const
0340     {
0341         if( type() != vtype ) 
0342         {
0343             std::ostringstream os;
0344 
0345             ///// Bitcoin: Tell the types by name instead of by number
0346             os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
0347 
0348             throw std::runtime_error( os.str() );
0349         }
0350     }
0351 
0352     template< class Config >
0353     const typename Config::String_type& Value_impl< Config >::get_str() const
0354     {
0355         check_type(  str_type );
0356 
0357         return *boost::get< String_type >( &v_ );
0358     }
0359 
0360     template< class Config >
0361     const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
0362     {
0363         check_type( obj_type );
0364 
0365         return *boost::get< Object >( &v_ );
0366     }
0367      
0368     template< class Config >
0369     const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
0370     {
0371         check_type(  array_type );
0372 
0373         return *boost::get< Array >( &v_ );
0374     }
0375      
0376     template< class Config >
0377     bool Value_impl< Config >::get_bool() const
0378     {
0379         check_type(  bool_type );
0380 
0381         return boost::get< bool >( v_ );
0382     }
0383      
0384     template< class Config >
0385     int Value_impl< Config >::get_int() const
0386     {
0387         check_type(  int_type );
0388 
0389         return static_cast< int >( get_int64() );
0390     }
0391     
0392     template< class Config >
0393     boost::int64_t Value_impl< Config >::get_int64() const
0394     {
0395         check_type(  int_type );
0396 
0397         return boost::get< boost::int64_t >( v_ );
0398     }
0399     
0400     template< class Config >
0401     boost::uint64_t Value_impl< Config >::get_uint64() const
0402     {
0403         check_type(  int_type );
0404 
0405         return static_cast< boost::uint64_t >( get_int64() );
0406     }
0407 
0408     template< class Config >
0409     double Value_impl< Config >::get_real() const
0410     {
0411         if( type() == int_type )
0412         {
0413             return is_uint64() ? static_cast< double >( get_uint64() )
0414                                : static_cast< double >( get_int64() );
0415         }
0416 
0417         check_type(  real_type );
0418 
0419         return boost::get< double >( v_ );
0420     }
0421 
0422     template< class Config >
0423     typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
0424     {
0425         check_type(  obj_type );
0426 
0427         return *boost::get< Object >( &v_ );
0428     }
0429 
0430     template< class Config >
0431     typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
0432     {
0433         check_type(  array_type );
0434 
0435         return *boost::get< Array >( &v_ );
0436     }
0437 
0438     template< class Config >
0439     Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
0440     :   name_( name )
0441     ,   value_( value )
0442     {
0443     }
0444 
0445     template< class Config >
0446     bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
0447     {
0448         if( this == &lhs ) return true;
0449 
0450         return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
0451     }
0452 
0453     // converts a C string, ie. 8 bit char array, to a string object
0454     //
0455     template < class String_type >
0456     String_type to_str( const char* c_str )
0457     {
0458         String_type result;
0459 
0460         for( const char* p = c_str; *p != 0; ++p )
0461         {
0462             result += *p;
0463         }
0464 
0465         return result;
0466     }
0467 
0468     //
0469 
0470     namespace internal_
0471     {
0472         template< typename T >
0473         struct Type_to_type
0474         {
0475         };
0476 
0477         template< class Value > 
0478         int get_value( const Value& value, Type_to_type< int > )
0479         {
0480             return value.get_int();
0481         }
0482        
0483         template< class Value > 
0484         boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
0485         {
0486             return value.get_int64();
0487         }
0488        
0489         template< class Value > 
0490         boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
0491         {
0492             return value.get_uint64();
0493         }
0494        
0495         template< class Value > 
0496         double get_value( const Value& value, Type_to_type< double > )
0497         {
0498             return value.get_real();
0499         }
0500        
0501         template< class Value > 
0502         typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
0503         {
0504             return value.get_str();
0505         }
0506        
0507         template< class Value > 
0508         typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
0509         {
0510             return value.get_array();
0511         }
0512        
0513         template< class Value > 
0514         typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
0515         {
0516             return value.get_obj();
0517         }
0518        
0519         template< class Value > 
0520         bool get_value( const Value& value, Type_to_type< bool > )
0521         {
0522             return value.get_bool();
0523         }
0524     }
0525 
0526     template< class Config >
0527     template< typename T > 
0528     T Value_impl< Config >::get_value() const
0529     {
0530         return internal_::get_value( *this, internal_::Type_to_type< T >() );
0531     }
0532 }
0533 
0534 #endif