Better wording for transaction fee notification messages
[novacoin.git] / src / json / json_spirit_reader_template.h
1 #ifndef JSON_SPIRIT_READER_TEMPLATE
2 #define JSON_SPIRIT_READER_TEMPLATE
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 #include "json_spirit_value.h"
10 #include "json_spirit_error_position.h"
11
12 //#define BOOST_SPIRIT_THREADSAFE  // uncomment for multithreaded use, requires linking to boost.thread
13
14 #include <boost/bind.hpp>
15 #include <boost/function.hpp>
16 #include <boost/version.hpp>
17
18 #if BOOST_VERSION >= 103800
19     #include <boost/spirit/include/classic_core.hpp>
20     #include <boost/spirit/include/classic_confix.hpp>
21     #include <boost/spirit/include/classic_escape_char.hpp>
22     #include <boost/spirit/include/classic_multi_pass.hpp>
23     #include <boost/spirit/include/classic_position_iterator.hpp>
24     #define spirit_namespace boost::spirit::classic
25 #else
26     #include <boost/spirit/core.hpp>
27     #include <boost/spirit/utility/confix.hpp>
28     #include <boost/spirit/utility/escape_char.hpp>
29     #include <boost/spirit/iterator/multi_pass.hpp>
30     #include <boost/spirit/iterator/position_iterator.hpp>
31     #define spirit_namespace boost::spirit
32 #endif
33
34 namespace json_spirit
35 {
36     const spirit_namespace::int_parser < boost::int64_t >  int64_p  = spirit_namespace::int_parser < boost::int64_t  >();
37     const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
38
39     template< class Iter_type >
40     bool is_eq( Iter_type first, Iter_type last, const char* c_str )
41     {
42         for( Iter_type i = first; i != last; ++i, ++c_str )
43         {
44             if( *c_str == 0 ) return false;
45
46             if( *i != *c_str ) return false;
47         }
48
49         return true;
50     }
51
52     template< class Char_type >
53     Char_type hex_to_num( const Char_type c )
54     {
55         if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
56         if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
57         if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
58         return 0;
59     }
60
61     template< class Char_type, class Iter_type >
62     Char_type hex_str_to_char( Iter_type& begin )
63     {
64         const Char_type c1( *( ++begin ) );
65         const Char_type c2( *( ++begin ) );
66
67         return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
68     }       
69
70     template< class Char_type, class Iter_type >
71     Char_type unicode_str_to_char( Iter_type& begin )
72     {
73         const Char_type c1( *( ++begin ) );
74         const Char_type c2( *( ++begin ) );
75         const Char_type c3( *( ++begin ) );
76         const Char_type c4( *( ++begin ) );
77
78         return ( hex_to_num( c1 ) << 12 ) + 
79                ( hex_to_num( c2 ) <<  8 ) + 
80                ( hex_to_num( c3 ) <<  4 ) + 
81                hex_to_num( c4 );
82     }
83
84     template< class String_type >
85     void append_esc_char_and_incr_iter( String_type& s, 
86                                         typename String_type::const_iterator& begin, 
87                                         typename String_type::const_iterator end )
88     {
89         typedef typename String_type::value_type Char_type;
90              
91         const Char_type c2( *begin );
92
93         switch( c2 )
94         {
95             case 't':  s += '\t'; break;
96             case 'b':  s += '\b'; break;
97             case 'f':  s += '\f'; break;
98             case 'n':  s += '\n'; break;
99             case 'r':  s += '\r'; break;
100             case '\\': s += '\\'; break;
101             case '/':  s += '/';  break;
102             case '"':  s += '"';  break;
103             case 'x':  
104             {
105                 if( end - begin >= 3 )  //  expecting "xHH..."
106                 {
107                     s += hex_str_to_char< Char_type >( begin );  
108                 }
109                 break;
110             }
111             case 'u':  
112             {
113                 if( end - begin >= 5 )  //  expecting "uHHHH..."
114                 {
115                     s += unicode_str_to_char< Char_type >( begin );  
116                 }
117                 break;
118             }
119         }
120     }
121
122     template< class String_type >
123     String_type substitute_esc_chars( typename String_type::const_iterator begin, 
124                                    typename String_type::const_iterator end )
125     {
126         typedef typename String_type::const_iterator Iter_type;
127
128         if( end - begin < 2 ) return String_type( begin, end );
129
130         String_type result;
131         
132         result.reserve( end - begin );
133
134         const Iter_type end_minus_1( end - 1 );
135
136         Iter_type substr_start = begin;
137         Iter_type i = begin;
138
139         for( ; i < end_minus_1; ++i )
140         {
141             if( *i == '\\' )
142             {
143                 result.append( substr_start, i );
144
145                 ++i;  // skip the '\'
146              
147                 append_esc_char_and_incr_iter( result, i, end );
148
149                 substr_start = i + 1;
150             }
151         }
152
153         result.append( substr_start, end );
154
155         return result;
156     }
157
158     template< class String_type >
159     String_type get_str_( typename String_type::const_iterator begin, 
160                        typename String_type::const_iterator end )
161     {
162         assert( end - begin >= 2 );
163
164         typedef typename String_type::const_iterator Iter_type;
165
166         Iter_type str_without_quotes( ++begin );
167         Iter_type end_without_quotes( --end );
168
169         return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
170     }
171
172     inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
173     {
174         return get_str_< std::string >( begin, end );
175     }
176
177     inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
178     {
179         return get_str_< std::wstring >( begin, end );
180     }
181     
182     template< class String_type, class Iter_type >
183     String_type get_str( Iter_type begin, Iter_type end )
184     {
185         const String_type tmp( begin, end );  // convert multipass iterators to string iterators
186
187         return get_str( tmp.begin(), tmp.end() );
188     }
189
190     // this class's methods get called by the spirit parse resulting
191     // in the creation of a JSON object or array
192     //
193     // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
194     //
195     template< class Value_type, class Iter_type >
196     class Semantic_actions 
197     {
198     public:
199
200         typedef typename Value_type::Config_type Config_type;
201         typedef typename Config_type::String_type String_type;
202         typedef typename Config_type::Object_type Object_type;
203         typedef typename Config_type::Array_type Array_type;
204         typedef typename String_type::value_type Char_type;
205
206         Semantic_actions( Value_type& value )
207         :   value_( value )
208         ,   current_p_( 0 )
209         {
210         }
211
212         void begin_obj( Char_type c )
213         {
214             assert( c == '{' );
215
216             begin_compound< Object_type >();
217         }
218
219         void end_obj( Char_type c )
220         {
221             assert( c == '}' );
222
223             end_compound();
224         }
225
226         void begin_array( Char_type c )
227         {
228             assert( c == '[' );
229      
230             begin_compound< Array_type >();
231         }
232
233         void end_array( Char_type c )
234         {
235             assert( c == ']' );
236
237             end_compound();
238         }
239
240         void new_name( Iter_type begin, Iter_type end )
241         {
242             assert( current_p_->type() == obj_type );
243
244             name_ = get_str< String_type >( begin, end );
245         }
246
247         void new_str( Iter_type begin, Iter_type end )
248         {
249             add_to_current( get_str< String_type >( begin, end ) );
250         }
251
252         void new_true( Iter_type begin, Iter_type end )
253         {
254             assert( is_eq( begin, end, "true" ) );
255
256             add_to_current( true );
257         }
258
259         void new_false( Iter_type begin, Iter_type end )
260         {
261             assert( is_eq( begin, end, "false" ) );
262
263             add_to_current( false );
264         }
265
266         void new_null( Iter_type begin, Iter_type end )
267         {
268             assert( is_eq( begin, end, "null" ) );
269
270             add_to_current( Value_type() );
271         }
272
273         void new_int( boost::int64_t i )
274         {
275             add_to_current( i );
276         }
277
278         void new_uint64( boost::uint64_t ui )
279         {
280             add_to_current( ui );
281         }
282
283         void new_real( double d )
284         {
285             add_to_current( d );
286         }
287
288     private:
289
290         Semantic_actions& operator=( const Semantic_actions& ); 
291                                     // to prevent "assignment operator could not be generated" warning
292
293         Value_type* add_first( const Value_type& value )
294         {
295             assert( current_p_ == 0 );
296
297             value_ = value;
298             current_p_ = &value_;
299             return current_p_;
300         }
301
302         template< class Array_or_obj >
303         void begin_compound()
304         {
305             if( current_p_ == 0 )
306             {
307                 add_first( Array_or_obj() );
308             }
309             else
310             {
311                 stack_.push_back( current_p_ );
312
313                 Array_or_obj new_array_or_obj;   // avoid copy by building new array or object in place
314
315                 current_p_ = add_to_current( new_array_or_obj );
316             }
317         }
318
319         void end_compound()
320         {
321             if( current_p_ != &value_ )
322             {
323                 current_p_ = stack_.back();
324                 
325                 stack_.pop_back();
326             }    
327         }
328
329         Value_type* add_to_current( const Value_type& value )
330         {
331             if( current_p_ == 0 )
332             {
333                 return add_first( value );
334             }
335             else if( current_p_->type() == array_type )
336             {
337                 current_p_->get_array().push_back( value );
338
339                 return &current_p_->get_array().back(); 
340             }
341             
342             assert( current_p_->type() == obj_type );
343
344             return &Config_type::add( current_p_->get_obj(), name_, value );
345         }
346
347         Value_type& value_;             // this is the object or array that is being created
348         Value_type* current_p_;         // the child object or array that is currently being constructed
349
350         std::vector< Value_type* > stack_;   // previous child objects and arrays
351
352         String_type name_;              // of current name/value pair
353     };
354
355     template< typename Iter_type >
356     void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
357     {
358         throw Error_position( i.get_position().line, i.get_position().column, reason );
359     }
360
361     template< typename Iter_type >
362     void throw_error( Iter_type i, const std::string& reason )
363     {
364        throw reason;
365     }
366
367     // the spirit grammer 
368     //
369     template< class Value_type, class Iter_type >
370     class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
371     {
372     public:
373
374         typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
375
376         Json_grammer( Semantic_actions_t& semantic_actions )
377         :   actions_( semantic_actions )
378         {
379         }
380
381         static void throw_not_value( Iter_type begin, Iter_type end )
382         {
383             throw_error( begin, "not a value" );
384         }
385
386         static void throw_not_array( Iter_type begin, Iter_type end )
387         {
388             throw_error( begin, "not an array" );
389         }
390
391         static void throw_not_object( Iter_type begin, Iter_type end )
392         {
393             throw_error( begin, "not an object" );
394         }
395
396         static void throw_not_pair( Iter_type begin, Iter_type end )
397         {
398             throw_error( begin, "not a pair" );
399         }
400
401         static void throw_not_colon( Iter_type begin, Iter_type end )
402         {
403             throw_error( begin, "no colon in pair" );
404         }
405
406         static void throw_not_string( Iter_type begin, Iter_type end )
407         {
408             throw_error( begin, "not a string" );
409         }
410
411         template< typename ScannerT >
412         class definition
413         {
414         public:
415
416             definition( const Json_grammer& self )
417             {
418                 using namespace spirit_namespace;
419
420                 typedef typename Value_type::String_type::value_type Char_type;
421
422                 // first we convert the semantic action class methods to functors with the 
423                 // parameter signature expected by spirit
424
425                 typedef boost::function< void( Char_type )            > Char_action;
426                 typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
427                 typedef boost::function< void( double )               > Real_action;
428                 typedef boost::function< void( boost::int64_t )       > Int_action;
429                 typedef boost::function< void( boost::uint64_t )      > Uint64_action;
430
431                 Char_action   begin_obj  ( boost::bind( &Semantic_actions_t::begin_obj,   &self.actions_, _1 ) );
432                 Char_action   end_obj    ( boost::bind( &Semantic_actions_t::end_obj,     &self.actions_, _1 ) );
433                 Char_action   begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
434                 Char_action   end_array  ( boost::bind( &Semantic_actions_t::end_array,   &self.actions_, _1 ) );
435                 Str_action    new_name   ( boost::bind( &Semantic_actions_t::new_name,    &self.actions_, _1, _2 ) );
436                 Str_action    new_str    ( boost::bind( &Semantic_actions_t::new_str,     &self.actions_, _1, _2 ) );
437                 Str_action    new_true   ( boost::bind( &Semantic_actions_t::new_true,    &self.actions_, _1, _2 ) );
438                 Str_action    new_false  ( boost::bind( &Semantic_actions_t::new_false,   &self.actions_, _1, _2 ) );
439                 Str_action    new_null   ( boost::bind( &Semantic_actions_t::new_null,    &self.actions_, _1, _2 ) );
440                 Real_action   new_real   ( boost::bind( &Semantic_actions_t::new_real,    &self.actions_, _1 ) );
441                 Int_action    new_int    ( boost::bind( &Semantic_actions_t::new_int,     &self.actions_, _1 ) );
442                 Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64,  &self.actions_, _1 ) );
443
444                 // actual grammer
445
446                 json_
447                     = value_ | eps_p[ &throw_not_value ]
448                     ;
449
450                 value_
451                     = string_[ new_str ] 
452                     | number_ 
453                     | object_ 
454                     | array_ 
455                     | str_p( "true" ) [ new_true  ] 
456                     | str_p( "false" )[ new_false ] 
457                     | str_p( "null" ) [ new_null  ]
458                     ;
459
460                 object_ 
461                     = ch_p('{')[ begin_obj ]
462                     >> !members_
463                     >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
464                     ;
465
466                 members_
467                     = pair_ >> *( ',' >> pair_ )
468                     ;
469
470                 pair_
471                     = string_[ new_name ]
472                     >> ( ':' | eps_p[ &throw_not_colon ] )
473                     >> ( value_ | eps_p[ &throw_not_value ] )
474                     ;
475
476                 array_
477                     = ch_p('[')[ begin_array ]
478                     >> !elements_
479                     >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
480                     ;
481
482                 elements_
483                     = value_ >> *( ',' >> value_ )
484                     ;
485
486                 string_ 
487                     = lexeme_d // this causes white space inside a string to be retained
488                       [
489                           confix_p
490                           ( 
491                               '"', 
492                               *lex_escape_ch_p,
493                               '"'
494                           ) 
495                       ]
496                     ;
497
498                 number_
499                     = strict_real_p[ new_real   ] 
500                     | int64_p      [ new_int    ]
501                     | uint64_p     [ new_uint64 ]
502                     ;
503             }
504
505             spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
506
507             const spirit_namespace::rule< ScannerT >& start() const { return json_; }
508         };
509
510     private:
511
512         Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
513
514         Semantic_actions_t& actions_;
515     };
516
517     template< class Iter_type, class Value_type >
518     Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
519     {
520         Semantic_actions< Value_type, Iter_type > semantic_actions( value );
521      
522         const spirit_namespace::parse_info< Iter_type > info = 
523                             spirit_namespace::parse( begin, end, 
524                                                     Json_grammer< Value_type, Iter_type >( semantic_actions ), 
525                                                     spirit_namespace::space_p );
526
527         if( !info.hit )
528         {
529             assert( false ); // in theory exception should already have been thrown
530             throw_error( info.stop, "error" );
531         }
532
533         return info.stop;
534     }
535
536     template< class Iter_type, class Value_type >
537     void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
538     {
539         typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
540
541         const Posn_iter_t posn_begin( begin, end );
542         const Posn_iter_t posn_end( end, end );
543      
544         read_range_or_throw( posn_begin, posn_end, value );
545     }
546
547     template< class Iter_type, class Value_type >
548     bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
549     {
550         try
551         {
552             begin = read_range_or_throw( begin, end, value );
553
554             return true;
555         }
556         catch( ... )
557         {
558             return false;
559         }
560     }
561
562     template< class String_type, class Value_type >
563     void read_string_or_throw( const String_type& s, Value_type& value )
564     {
565         add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
566     }
567
568     template< class String_type, class Value_type >
569     bool read_string( const String_type& s, Value_type& value )
570     {
571         typename String_type::const_iterator begin = s.begin();
572
573         return read_range( begin, s.end(), value );
574     }
575
576     template< class Istream_type >
577     struct Multi_pass_iters
578     {
579         typedef typename Istream_type::char_type Char_type;
580         typedef std::istream_iterator< Char_type, Char_type > istream_iter;
581         typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
582
583         Multi_pass_iters( Istream_type& is )
584         {
585             is.unsetf( std::ios::skipws );
586
587             begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
588             end_   = spirit_namespace::make_multi_pass( istream_iter() );
589         }
590
591         Mp_iter begin_;
592         Mp_iter end_;
593     };
594
595     template< class Istream_type, class Value_type >
596     bool read_stream( Istream_type& is, Value_type& value )
597     {
598         Multi_pass_iters< Istream_type > mp_iters( is );
599
600         return read_range( mp_iters.begin_, mp_iters.end_, value );
601     }
602
603     template< class Istream_type, class Value_type >
604     void read_stream_or_throw( Istream_type& is, Value_type& value )
605     {
606         const Multi_pass_iters< Istream_type > mp_iters( is );
607
608         add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
609     }
610 }
611
612 #endif