-
+ C2BCDC1E04F52791173BCD0AF2C7CFE63B6953BA108B2590F98DF767899CA15616C984FEBC4A9076720586B254D256B8A1C023DD5431DD88DF939F9519BAF18F
bitcoin/src/json/json_spirit_value.h
(0 . 0)(1 . 534)
7626 #ifndef JSON_SPIRIT_VALUE
7627 #define JSON_SPIRIT_VALUE
7628
7629 // Copyright John W. Wilkinson 2007 - 2009.
7630 // Distributed under the MIT License, see accompanying file LICENSE.txt
7631
7632 // json spirit version 4.03
7633
7634 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7635 # pragma once
7636 #endif
7637
7638 #include <vector>
7639 #include <map>
7640 #include <string>
7641 #include <cassert>
7642 #include <sstream>
7643 #include <stdexcept>
7644 #include <boost/config.hpp>
7645 #include <boost/cstdint.hpp>
7646 #include <boost/shared_ptr.hpp>
7647 #include <boost/variant.hpp>
7648
7649 namespace json_spirit
7650 {
7651 enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
7652 static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
7653
7654 template< class Config > // Config determines whether the value uses std::string or std::wstring and
7655 // whether JSON Objects are represented as vectors or maps
7656 class Value_impl
7657 {
7658 public:
7659
7660 typedef Config Config_type;
7661 typedef typename Config::String_type String_type;
7662 typedef typename Config::Object_type Object;
7663 typedef typename Config::Array_type Array;
7664 typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
7665
7666 Value_impl(); // creates null value
7667 Value_impl( Const_str_ptr value );
7668 Value_impl( const String_type& value );
7669 Value_impl( const Object& value );
7670 Value_impl( const Array& value );
7671 Value_impl( bool value );
7672 Value_impl( int value );
7673 Value_impl( boost::int64_t value );
7674 Value_impl( boost::uint64_t value );
7675 Value_impl( double value );
7676
7677 Value_impl( const Value_impl& other );
7678
7679 bool operator==( const Value_impl& lhs ) const;
7680
7681 Value_impl& operator=( const Value_impl& lhs );
7682
7683 Value_type type() const;
7684
7685 bool is_uint64() const;
7686 bool is_null() const;
7687
7688 const String_type& get_str() const;
7689 const Object& get_obj() const;
7690 const Array& get_array() const;
7691 bool get_bool() const;
7692 int get_int() const;
7693 boost::int64_t get_int64() const;
7694 boost::uint64_t get_uint64() const;
7695 double get_real() const;
7696
7697 Object& get_obj();
7698 Array& get_array();
7699
7700 template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
7701 // or double d = value.get_value< double >();
7702
7703 static const Value_impl null;
7704
7705 private:
7706
7707 void check_type( const Value_type vtype ) const;
7708
7709 typedef boost::variant< String_type,
7710 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
7711 bool, boost::int64_t, double > Variant;
7712
7713 Value_type type_;
7714 Variant v_;
7715 bool is_uint64_;
7716 };
7717
7718 // vector objects
7719
7720 template< class Config >
7721 struct Pair_impl
7722 {
7723 typedef typename Config::String_type String_type;
7724 typedef typename Config::Value_type Value_type;
7725
7726 Pair_impl( const String_type& name, const Value_type& value );
7727
7728 bool operator==( const Pair_impl& lhs ) const;
7729
7730 String_type name_;
7731 Value_type value_;
7732 };
7733
7734 template< class String >
7735 struct Config_vector
7736 {
7737 typedef String String_type;
7738 typedef Value_impl< Config_vector > Value_type;
7739 typedef Pair_impl < Config_vector > Pair_type;
7740 typedef std::vector< Value_type > Array_type;
7741 typedef std::vector< Pair_type > Object_type;
7742
7743 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
7744 {
7745 obj.push_back( Pair_type( name , value ) );
7746
7747 return obj.back().value_;
7748 }
7749
7750 static String_type get_name( const Pair_type& pair )
7751 {
7752 return pair.name_;
7753 }
7754
7755 static Value_type get_value( const Pair_type& pair )
7756 {
7757 return pair.value_;
7758 }
7759 };
7760
7761 // typedefs for ASCII
7762
7763 typedef Config_vector< std::string > Config;
7764
7765 typedef Config::Value_type Value;
7766 typedef Config::Pair_type Pair;
7767 typedef Config::Object_type Object;
7768 typedef Config::Array_type Array;
7769
7770 // typedefs for Unicode
7771
7772 #ifndef BOOST_NO_STD_WSTRING
7773
7774 typedef Config_vector< std::wstring > wConfig;
7775
7776 typedef wConfig::Value_type wValue;
7777 typedef wConfig::Pair_type wPair;
7778 typedef wConfig::Object_type wObject;
7779 typedef wConfig::Array_type wArray;
7780 #endif
7781
7782 // map objects
7783
7784 template< class String >
7785 struct Config_map
7786 {
7787 typedef String String_type;
7788 typedef Value_impl< Config_map > Value_type;
7789 typedef std::vector< Value_type > Array_type;
7790 typedef std::map< String_type, Value_type > Object_type;
7791 typedef typename Object_type::value_type Pair_type;
7792
7793 static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
7794 {
7795 return obj[ name ] = value;
7796 }
7797
7798 static String_type get_name( const Pair_type& pair )
7799 {
7800 return pair.first;
7801 }
7802
7803 static Value_type get_value( const Pair_type& pair )
7804 {
7805 return pair.second;
7806 }
7807 };
7808
7809 // typedefs for ASCII
7810
7811 typedef Config_map< std::string > mConfig;
7812
7813 typedef mConfig::Value_type mValue;
7814 typedef mConfig::Object_type mObject;
7815 typedef mConfig::Array_type mArray;
7816
7817 // typedefs for Unicode
7818
7819 #ifndef BOOST_NO_STD_WSTRING
7820
7821 typedef Config_map< std::wstring > wmConfig;
7822
7823 typedef wmConfig::Value_type wmValue;
7824 typedef wmConfig::Object_type wmObject;
7825 typedef wmConfig::Array_type wmArray;
7826
7827 #endif
7828
7829 ///////////////////////////////////////////////////////////////////////////////////////////////
7830 //
7831 // implementation
7832
7833 template< class Config >
7834 const Value_impl< Config > Value_impl< Config >::null;
7835
7836 template< class Config >
7837 Value_impl< Config >::Value_impl()
7838 : type_( null_type )
7839 , is_uint64_( false )
7840 {
7841 }
7842
7843 template< class Config >
7844 Value_impl< Config >::Value_impl( const Const_str_ptr value )
7845 : type_( str_type )
7846 , v_( String_type( value ) )
7847 , is_uint64_( false )
7848 {
7849 }
7850
7851 template< class Config >
7852 Value_impl< Config >::Value_impl( const String_type& value )
7853 : type_( str_type )
7854 , v_( value )
7855 , is_uint64_( false )
7856 {
7857 }
7858
7859 template< class Config >
7860 Value_impl< Config >::Value_impl( const Object& value )
7861 : type_( obj_type )
7862 , v_( value )
7863 , is_uint64_( false )
7864 {
7865 }
7866
7867 template< class Config >
7868 Value_impl< Config >::Value_impl( const Array& value )
7869 : type_( array_type )
7870 , v_( value )
7871 , is_uint64_( false )
7872 {
7873 }
7874
7875 template< class Config >
7876 Value_impl< Config >::Value_impl( bool value )
7877 : type_( bool_type )
7878 , v_( value )
7879 , is_uint64_( false )
7880 {
7881 }
7882
7883 template< class Config >
7884 Value_impl< Config >::Value_impl( int value )
7885 : type_( int_type )
7886 , v_( static_cast< boost::int64_t >( value ) )
7887 , is_uint64_( false )
7888 {
7889 }
7890
7891 template< class Config >
7892 Value_impl< Config >::Value_impl( boost::int64_t value )
7893 : type_( int_type )
7894 , v_( value )
7895 , is_uint64_( false )
7896 {
7897 }
7898
7899 template< class Config >
7900 Value_impl< Config >::Value_impl( boost::uint64_t value )
7901 : type_( int_type )
7902 , v_( static_cast< boost::int64_t >( value ) )
7903 , is_uint64_( true )
7904 {
7905 }
7906
7907 template< class Config >
7908 Value_impl< Config >::Value_impl( double value )
7909 : type_( real_type )
7910 , v_( value )
7911 , is_uint64_( false )
7912 {
7913 }
7914
7915 template< class Config >
7916 Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
7917 : type_( other.type() )
7918 , v_( other.v_ )
7919 , is_uint64_( other.is_uint64_ )
7920 {
7921 }
7922
7923 template< class Config >
7924 Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
7925 {
7926 Value_impl tmp( lhs );
7927
7928 std::swap( type_, tmp.type_ );
7929 std::swap( v_, tmp.v_ );
7930 std::swap( is_uint64_, tmp.is_uint64_ );
7931
7932 return *this;
7933 }
7934
7935 template< class Config >
7936 bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
7937 {
7938 if( this == &lhs ) return true;
7939
7940 if( type() != lhs.type() ) return false;
7941
7942 return v_ == lhs.v_;
7943 }
7944
7945 template< class Config >
7946 Value_type Value_impl< Config >::type() const
7947 {
7948 return type_;
7949 }
7950
7951 template< class Config >
7952 bool Value_impl< Config >::is_uint64() const
7953 {
7954 return is_uint64_;
7955 }
7956
7957 template< class Config >
7958 bool Value_impl< Config >::is_null() const
7959 {
7960 return type() == null_type;
7961 }
7962
7963 template< class Config >
7964 void Value_impl< Config >::check_type( const Value_type vtype ) const
7965 {
7966 if( type() != vtype )
7967 {
7968 std::ostringstream os;
7969
7970 ///// Bitcoin: Tell the types by name instead of by number
7971 os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
7972
7973 throw std::runtime_error( os.str() );
7974 }
7975 }
7976
7977 template< class Config >
7978 const typename Config::String_type& Value_impl< Config >::get_str() const
7979 {
7980 check_type( str_type );
7981
7982 return *boost::get< String_type >( &v_ );
7983 }
7984
7985 template< class Config >
7986 const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
7987 {
7988 check_type( obj_type );
7989
7990 return *boost::get< Object >( &v_ );
7991 }
7992
7993 template< class Config >
7994 const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
7995 {
7996 check_type( array_type );
7997
7998 return *boost::get< Array >( &v_ );
7999 }
8000
8001 template< class Config >
8002 bool Value_impl< Config >::get_bool() const
8003 {
8004 check_type( bool_type );
8005
8006 return boost::get< bool >( v_ );
8007 }
8008
8009 template< class Config >
8010 int Value_impl< Config >::get_int() const
8011 {
8012 check_type( int_type );
8013
8014 return static_cast< int >( get_int64() );
8015 }
8016
8017 template< class Config >
8018 boost::int64_t Value_impl< Config >::get_int64() const
8019 {
8020 check_type( int_type );
8021
8022 return boost::get< boost::int64_t >( v_ );
8023 }
8024
8025 template< class Config >
8026 boost::uint64_t Value_impl< Config >::get_uint64() const
8027 {
8028 check_type( int_type );
8029
8030 return static_cast< boost::uint64_t >( get_int64() );
8031 }
8032
8033 template< class Config >
8034 double Value_impl< Config >::get_real() const
8035 {
8036 if( type() == int_type )
8037 {
8038 return is_uint64() ? static_cast< double >( get_uint64() )
8039 : static_cast< double >( get_int64() );
8040 }
8041
8042 check_type( real_type );
8043
8044 return boost::get< double >( v_ );
8045 }
8046
8047 template< class Config >
8048 typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
8049 {
8050 check_type( obj_type );
8051
8052 return *boost::get< Object >( &v_ );
8053 }
8054
8055 template< class Config >
8056 typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
8057 {
8058 check_type( array_type );
8059
8060 return *boost::get< Array >( &v_ );
8061 }
8062
8063 template< class Config >
8064 Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
8065 : name_( name )
8066 , value_( value )
8067 {
8068 }
8069
8070 template< class Config >
8071 bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
8072 {
8073 if( this == &lhs ) return true;
8074
8075 return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
8076 }
8077
8078 // converts a C string, ie. 8 bit char array, to a string object
8079 //
8080 template < class String_type >
8081 String_type to_str( const char* c_str )
8082 {
8083 String_type result;
8084
8085 for( const char* p = c_str; *p != 0; ++p )
8086 {
8087 result += *p;
8088 }
8089
8090 return result;
8091 }
8092
8093 //
8094
8095 namespace internal_
8096 {
8097 template< typename T >
8098 struct Type_to_type
8099 {
8100 };
8101
8102 template< class Value >
8103 int get_value( const Value& value, Type_to_type< int > )
8104 {
8105 return value.get_int();
8106 }
8107
8108 template< class Value >
8109 boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
8110 {
8111 return value.get_int64();
8112 }
8113
8114 template< class Value >
8115 boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
8116 {
8117 return value.get_uint64();
8118 }
8119
8120 template< class Value >
8121 double get_value( const Value& value, Type_to_type< double > )
8122 {
8123 return value.get_real();
8124 }
8125
8126 template< class Value >
8127 typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
8128 {
8129 return value.get_str();
8130 }
8131
8132 template< class Value >
8133 typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
8134 {
8135 return value.get_array();
8136 }
8137
8138 template< class Value >
8139 typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
8140 {
8141 return value.get_obj();
8142 }
8143
8144 template< class Value >
8145 bool get_value( const Value& value, Type_to_type< bool > )
8146 {
8147 return value.get_bool();
8148 }
8149 }
8150
8151 template< class Config >
8152 template< typename T >
8153 T Value_impl< Config >::get_value() const
8154 {
8155 return internal_::get_value( *this, internal_::Type_to_type< T >() );
8156 }
8157 }
8158
8159 #endif