Back to home page

Bitcoin sources

 
 

    


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

0001 #ifndef JSON_SPIRIT_READER_TEMPLATE
0002 #define JSON_SPIRIT_READER_TEMPLATE
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 #include "json_spirit_value.h"
0010 #include "json_spirit_error_position.h"
0011 
0012 //#define BOOST_SPIRIT_THREADSAFE  // uncomment for multithreaded use, requires linking to boost.thread
0013 
0014 #include <boost/bind.hpp>
0015 #include <boost/function.hpp>
0016 #include <boost/version.hpp>
0017 
0018 #if BOOST_VERSION >= 103800
0019     #include <boost/spirit/include/classic_core.hpp>
0020     #include <boost/spirit/include/classic_confix.hpp>
0021     #include <boost/spirit/include/classic_escape_char.hpp>
0022     #include <boost/spirit/include/classic_multi_pass.hpp>
0023     #include <boost/spirit/include/classic_position_iterator.hpp>
0024     #define spirit_namespace boost::spirit::classic
0025 #else
0026     #include <boost/spirit/core.hpp>
0027     #include <boost/spirit/utility/confix.hpp>
0028     #include <boost/spirit/utility/escape_char.hpp>
0029     #include <boost/spirit/iterator/multi_pass.hpp>
0030     #include <boost/spirit/iterator/position_iterator.hpp>
0031     #define spirit_namespace boost::spirit
0032 #endif
0033 
0034 namespace json_spirit
0035 {
0036     const spirit_namespace::int_parser < boost::int64_t >  int64_p  = spirit_namespace::int_parser < boost::int64_t  >();
0037     const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
0038 
0039     template< class Iter_type >
0040     bool is_eq( Iter_type first, Iter_type last, const char* c_str )
0041     {
0042         for( Iter_type i = first; i != last; ++i, ++c_str )
0043         {
0044             if( *c_str == 0 ) return false;
0045 
0046             if( *i != *c_str ) return false;
0047         }
0048 
0049         return true;
0050     }
0051 
0052     template< class Char_type >
0053     Char_type hex_to_num( const Char_type c )
0054     {
0055         if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
0056         if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
0057         if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
0058         return 0;
0059     }
0060 
0061     template< class Char_type, class Iter_type >
0062     Char_type hex_str_to_char( Iter_type& begin )
0063     {
0064         const Char_type c1( *( ++begin ) );
0065         const Char_type c2( *( ++begin ) );
0066 
0067         return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
0068     }       
0069 
0070     template< class Char_type, class Iter_type >
0071     Char_type unicode_str_to_char( Iter_type& begin )
0072     {
0073         const Char_type c1( *( ++begin ) );
0074         const Char_type c2( *( ++begin ) );
0075         const Char_type c3( *( ++begin ) );
0076         const Char_type c4( *( ++begin ) );
0077 
0078         return ( hex_to_num( c1 ) << 12 ) + 
0079                ( hex_to_num( c2 ) <<  8 ) + 
0080                ( hex_to_num( c3 ) <<  4 ) + 
0081                hex_to_num( c4 );
0082     }
0083 
0084     template< class String_type >
0085     void append_esc_char_and_incr_iter( String_type& s, 
0086                                         typename String_type::const_iterator& begin, 
0087                                         typename String_type::const_iterator end )
0088     {
0089         typedef typename String_type::value_type Char_type;
0090              
0091         const Char_type c2( *begin );
0092 
0093         switch( c2 )
0094         {
0095             case 't':  s += '\t'; break;
0096             case 'b':  s += '\b'; break;
0097             case 'f':  s += '\f'; break;
0098             case 'n':  s += '\n'; break;
0099             case 'r':  s += '\r'; break;
0100             case '\\': s += '\\'; break;
0101             case '/':  s += '/';  break;
0102             case '"':  s += '"';  break;
0103             case 'x':  
0104             {
0105                 if( end - begin >= 3 )  //  expecting "xHH..."
0106                 {
0107                     s += hex_str_to_char< Char_type >( begin );  
0108                 }
0109                 break;
0110             }
0111             case 'u':  
0112             {
0113                 if( end - begin >= 5 )  //  expecting "uHHHH..."
0114                 {
0115                     s += unicode_str_to_char< Char_type >( begin );  
0116                 }
0117                 break;
0118             }
0119         }
0120     }
0121 
0122     template< class String_type >
0123     String_type substitute_esc_chars( typename String_type::const_iterator begin, 
0124                                    typename String_type::const_iterator end )
0125     {
0126         typedef typename String_type::const_iterator Iter_type;
0127 
0128         if( end - begin < 2 ) return String_type( begin, end );
0129 
0130         String_type result;
0131         
0132         result.reserve( end - begin );
0133 
0134         const Iter_type end_minus_1( end - 1 );
0135 
0136         Iter_type substr_start = begin;
0137         Iter_type i = begin;
0138 
0139         for( ; i < end_minus_1; ++i )
0140         {
0141             if( *i == '\\' )
0142             {
0143                 result.append( substr_start, i );
0144 
0145                 ++i;  // skip the '\'
0146              
0147                 append_esc_char_and_incr_iter( result, i, end );
0148 
0149                 substr_start = i + 1;
0150             }
0151         }
0152 
0153         result.append( substr_start, end );
0154 
0155         return result;
0156     }
0157 
0158     template< class String_type >
0159     String_type get_str_( typename String_type::const_iterator begin, 
0160                        typename String_type::const_iterator end )
0161     {
0162         assert( end - begin >= 2 );
0163 
0164         typedef typename String_type::const_iterator Iter_type;
0165 
0166         Iter_type str_without_quotes( ++begin );
0167         Iter_type end_without_quotes( --end );
0168 
0169         return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
0170     }
0171 
0172     inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
0173     {
0174         return get_str_< std::string >( begin, end );
0175     }
0176 
0177     inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
0178     {
0179         return get_str_< std::wstring >( begin, end );
0180     }
0181     
0182     template< class String_type, class Iter_type >
0183     String_type get_str( Iter_type begin, Iter_type end )
0184     {
0185         const String_type tmp( begin, end );  // convert multipass iterators to string iterators
0186 
0187         return get_str( tmp.begin(), tmp.end() );
0188     }
0189 
0190     // this class's methods get called by the spirit parse resulting
0191     // in the creation of a JSON object or array
0192     //
0193     // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
0194     //
0195     template< class Value_type, class Iter_type >
0196     class Semantic_actions 
0197     {
0198     public:
0199 
0200         typedef typename Value_type::Config_type Config_type;
0201         typedef typename Config_type::String_type String_type;
0202         typedef typename Config_type::Object_type Object_type;
0203         typedef typename Config_type::Array_type Array_type;
0204         typedef typename String_type::value_type Char_type;
0205 
0206         Semantic_actions( Value_type& value )
0207         :   value_( value )
0208         ,   current_p_( 0 )
0209         {
0210         }
0211 
0212         void begin_obj( Char_type c )
0213         {
0214             assert( c == '{' );
0215 
0216             begin_compound< Object_type >();
0217         }
0218 
0219         void end_obj( Char_type c )
0220         {
0221             assert( c == '}' );
0222 
0223             end_compound();
0224         }
0225 
0226         void begin_array( Char_type c )
0227         {
0228             assert( c == '[' );
0229      
0230             begin_compound< Array_type >();
0231         }
0232 
0233         void end_array( Char_type c )
0234         {
0235             assert( c == ']' );
0236 
0237             end_compound();
0238         }
0239 
0240         void new_name( Iter_type begin, Iter_type end )
0241         {
0242             assert( current_p_->type() == obj_type );
0243 
0244             name_ = get_str< String_type >( begin, end );
0245         }
0246 
0247         void new_str( Iter_type begin, Iter_type end )
0248         {
0249             add_to_current( get_str< String_type >( begin, end ) );
0250         }
0251 
0252         void new_true( Iter_type begin, Iter_type end )
0253         {
0254             assert( is_eq( begin, end, "true" ) );
0255 
0256             add_to_current( true );
0257         }
0258 
0259         void new_false( Iter_type begin, Iter_type end )
0260         {
0261             assert( is_eq( begin, end, "false" ) );
0262 
0263             add_to_current( false );
0264         }
0265 
0266         void new_null( Iter_type begin, Iter_type end )
0267         {
0268             assert( is_eq( begin, end, "null" ) );
0269 
0270             add_to_current( Value_type() );
0271         }
0272 
0273         void new_int( boost::int64_t i )
0274         {
0275             add_to_current( i );
0276         }
0277 
0278         void new_uint64( boost::uint64_t ui )
0279         {
0280             add_to_current( ui );
0281         }
0282 
0283         void new_real( double d )
0284         {
0285             add_to_current( d );
0286         }
0287 
0288     private:
0289 
0290         Semantic_actions& operator=( const Semantic_actions& ); 
0291                                     // to prevent "assignment operator could not be generated" warning
0292 
0293         Value_type* add_first( const Value_type& value )
0294         {
0295             assert( current_p_ == 0 );
0296 
0297             value_ = value;
0298             current_p_ = &value_;
0299             return current_p_;
0300         }
0301 
0302         template< class Array_or_obj >
0303         void begin_compound()
0304         {
0305             if( current_p_ == 0 )
0306             {
0307                 add_first( Array_or_obj() );
0308             }
0309             else
0310             {
0311                 stack_.push_back( current_p_ );
0312 
0313                 Array_or_obj new_array_or_obj;   // avoid copy by building new array or object in place
0314 
0315                 current_p_ = add_to_current( new_array_or_obj );
0316             }
0317         }
0318 
0319         void end_compound()
0320         {
0321             if( current_p_ != &value_ )
0322             {
0323                 current_p_ = stack_.back();
0324                 
0325                 stack_.pop_back();
0326             }    
0327         }
0328 
0329         Value_type* add_to_current( const Value_type& value )
0330         {
0331             if( current_p_ == 0 )
0332             {
0333                 return add_first( value );
0334             }
0335             else if( current_p_->type() == array_type )
0336             {
0337                 current_p_->get_array().push_back( value );
0338 
0339                 return &current_p_->get_array().back(); 
0340             }
0341             
0342             assert( current_p_->type() == obj_type );
0343 
0344             return &Config_type::add( current_p_->get_obj(), name_, value );
0345         }
0346 
0347         Value_type& value_;             // this is the object or array that is being created
0348         Value_type* current_p_;         // the child object or array that is currently being constructed
0349 
0350         std::vector< Value_type* > stack_;   // previous child objects and arrays
0351 
0352         String_type name_;              // of current name/value pair
0353     };
0354 
0355     template< typename Iter_type >
0356     void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
0357     {
0358         throw Error_position( i.get_position().line, i.get_position().column, reason );
0359     }
0360 
0361     template< typename Iter_type >
0362     void throw_error( Iter_type i, const std::string& reason )
0363     {
0364        throw reason;
0365     }
0366 
0367     // the spirit grammer 
0368     //
0369     template< class Value_type, class Iter_type >
0370     class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
0371     {
0372     public:
0373 
0374         typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
0375 
0376         Json_grammer( Semantic_actions_t& semantic_actions )
0377         :   actions_( semantic_actions )
0378         {
0379         }
0380 
0381         static void throw_not_value( Iter_type begin, Iter_type end )
0382         {
0383             throw_error( begin, "not a value" );
0384         }
0385 
0386         static void throw_not_array( Iter_type begin, Iter_type end )
0387         {
0388             throw_error( begin, "not an array" );
0389         }
0390 
0391         static void throw_not_object( Iter_type begin, Iter_type end )
0392         {
0393             throw_error( begin, "not an object" );
0394         }
0395 
0396         static void throw_not_pair( Iter_type begin, Iter_type end )
0397         {
0398             throw_error( begin, "not a pair" );
0399         }
0400 
0401         static void throw_not_colon( Iter_type begin, Iter_type end )
0402         {
0403             throw_error( begin, "no colon in pair" );
0404         }
0405 
0406         static void throw_not_string( Iter_type begin, Iter_type end )
0407         {
0408             throw_error( begin, "not a string" );
0409         }
0410 
0411         template< typename ScannerT >
0412         class definition
0413         {
0414         public:
0415 
0416             definition( const Json_grammer& self )
0417             {
0418                 using namespace spirit_namespace;
0419 
0420                 typedef typename Value_type::String_type::value_type Char_type;
0421 
0422                 // first we convert the semantic action class methods to functors with the 
0423                 // parameter signature expected by spirit
0424 
0425                 typedef boost::function< void( Char_type )            > Char_action;
0426                 typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
0427                 typedef boost::function< void( double )               > Real_action;
0428                 typedef boost::function< void( boost::int64_t )       > Int_action;
0429                 typedef boost::function< void( boost::uint64_t )      > Uint64_action;
0430 
0431                 Char_action   begin_obj  ( boost::bind( &Semantic_actions_t::begin_obj,   &self.actions_, _1 ) );
0432                 Char_action   end_obj    ( boost::bind( &Semantic_actions_t::end_obj,     &self.actions_, _1 ) );
0433                 Char_action   begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
0434                 Char_action   end_array  ( boost::bind( &Semantic_actions_t::end_array,   &self.actions_, _1 ) );
0435                 Str_action    new_name   ( boost::bind( &Semantic_actions_t::new_name,    &self.actions_, _1, _2 ) );
0436                 Str_action    new_str    ( boost::bind( &Semantic_actions_t::new_str,     &self.actions_, _1, _2 ) );
0437                 Str_action    new_true   ( boost::bind( &Semantic_actions_t::new_true,    &self.actions_, _1, _2 ) );
0438                 Str_action    new_false  ( boost::bind( &Semantic_actions_t::new_false,   &self.actions_, _1, _2 ) );
0439                 Str_action    new_null   ( boost::bind( &Semantic_actions_t::new_null,    &self.actions_, _1, _2 ) );
0440                 Real_action   new_real   ( boost::bind( &Semantic_actions_t::new_real,    &self.actions_, _1 ) );
0441                 Int_action    new_int    ( boost::bind( &Semantic_actions_t::new_int,     &self.actions_, _1 ) );
0442                 Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64,  &self.actions_, _1 ) );
0443 
0444                 // actual grammer
0445 
0446                 json_
0447                     = value_ | eps_p[ &throw_not_value ]
0448                     ;
0449 
0450                 value_
0451                     = string_[ new_str ] 
0452                     | number_ 
0453                     | object_ 
0454                     | array_ 
0455                     | str_p( "true" ) [ new_true  ] 
0456                     | str_p( "false" )[ new_false ] 
0457                     | str_p( "null" ) [ new_null  ]
0458                     ;
0459 
0460                 object_ 
0461                     = ch_p('{')[ begin_obj ]
0462                     >> !members_
0463                     >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
0464                     ;
0465 
0466                 members_
0467                     = pair_ >> *( ',' >> pair_ )
0468                     ;
0469 
0470                 pair_
0471                     = string_[ new_name ]
0472                     >> ( ':' | eps_p[ &throw_not_colon ] )
0473                     >> ( value_ | eps_p[ &throw_not_value ] )
0474                     ;
0475 
0476                 array_
0477                     = ch_p('[')[ begin_array ]
0478                     >> !elements_
0479                     >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
0480                     ;
0481 
0482                 elements_
0483                     = value_ >> *( ',' >> value_ )
0484                     ;
0485 
0486                 string_ 
0487                     = lexeme_d // this causes white space inside a string to be retained
0488                       [
0489                           confix_p
0490                           ( 
0491                               '"', 
0492                               *lex_escape_ch_p,
0493                               '"'
0494                           ) 
0495                       ]
0496                     ;
0497 
0498                 number_
0499                     = strict_real_p[ new_real   ] 
0500                     | int64_p      [ new_int    ]
0501                     | uint64_p     [ new_uint64 ]
0502                     ;
0503             }
0504 
0505             spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
0506 
0507             const spirit_namespace::rule< ScannerT >& start() const { return json_; }
0508         };
0509 
0510     private:
0511 
0512         Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
0513 
0514         Semantic_actions_t& actions_;
0515     };
0516 
0517     template< class Iter_type, class Value_type >
0518     Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
0519     {
0520         Semantic_actions< Value_type, Iter_type > semantic_actions( value );
0521      
0522         const spirit_namespace::parse_info< Iter_type > info = 
0523                             spirit_namespace::parse( begin, end, 
0524                                                     Json_grammer< Value_type, Iter_type >( semantic_actions ), 
0525                                                     spirit_namespace::space_p );
0526 
0527         if( !info.hit )
0528         {
0529             assert( false ); // in theory exception should already have been thrown
0530             throw_error( info.stop, "error" );
0531         }
0532 
0533         return info.stop;
0534     }
0535 
0536     template< class Iter_type, class Value_type >
0537     void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
0538     {
0539         typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
0540 
0541         const Posn_iter_t posn_begin( begin, end );
0542         const Posn_iter_t posn_end( end, end );
0543      
0544         read_range_or_throw( posn_begin, posn_end, value );
0545     }
0546 
0547     template< class Iter_type, class Value_type >
0548     bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
0549     {
0550         try
0551         {
0552             begin = read_range_or_throw( begin, end, value );
0553 
0554             return true;
0555         }
0556         catch( ... )
0557         {
0558             return false;
0559         }
0560     }
0561 
0562     template< class String_type, class Value_type >
0563     void read_string_or_throw( const String_type& s, Value_type& value )
0564     {
0565         add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
0566     }
0567 
0568     template< class String_type, class Value_type >
0569     bool read_string( const String_type& s, Value_type& value )
0570     {
0571         typename String_type::const_iterator begin = s.begin();
0572 
0573         return read_range( begin, s.end(), value );
0574     }
0575 
0576     template< class Istream_type >
0577     struct Multi_pass_iters
0578     {
0579         typedef typename Istream_type::char_type Char_type;
0580         typedef std::istream_iterator< Char_type, Char_type > istream_iter;
0581         typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
0582 
0583         Multi_pass_iters( Istream_type& is )
0584         {
0585             is.unsetf( std::ios::skipws );
0586 
0587             begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
0588             end_   = spirit_namespace::make_multi_pass( istream_iter() );
0589         }
0590 
0591         Mp_iter begin_;
0592         Mp_iter end_;
0593     };
0594 
0595     template< class Istream_type, class Value_type >
0596     bool read_stream( Istream_type& is, Value_type& value )
0597     {
0598         Multi_pass_iters< Istream_type > mp_iters( is );
0599 
0600         return read_range( mp_iters.begin_, mp_iters.end_, value );
0601     }
0602 
0603     template< class Istream_type, class Value_type >
0604     void read_stream_or_throw( Istream_type& is, Value_type& value )
0605     {
0606         const Multi_pass_iters< Istream_type > mp_iters( is );
0607 
0608         add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
0609     }
0610 }
0611 
0612 #endif