@@ -3,6 +3,18 @@ use std::str;
33use std:: collections:: BTreeMap ;
44use { JsonValue , JsonError , JsonResult } ;
55
6+ struct Position {
7+ pub line : usize ,
8+ pub column : usize ,
9+ }
10+
11+ struct Parser < ' a > {
12+ source : & ' a str ,
13+ byte_ptr : * const u8 ,
14+ index : usize ,
15+ length : usize ,
16+ }
17+
618macro_rules! next_byte {
719 ( $parser: ident || $alt: expr) => {
820 if $parser. index < $parser. length {
@@ -66,19 +78,16 @@ macro_rules! consume_whitespace {
6678}
6779
6880macro_rules! expect {
69- ( $parser: ident, $byte: pat ) => ( {
81+ ( $parser: ident, $byte: expr ) => ( {
7082 let mut ch = next_byte!( $parser) ;
7183
7284 consume_whitespace!( $parser, ch) ;
7385
74- match ch {
75- $byte => { } ,
76- _ => return $parser. unexpected_character( ch)
86+ if ch != $byte {
87+ return $parser. unexpected_character( ch)
7788 }
78- } )
79- }
89+ } ) ;
8090
81- macro_rules! expect_one_of {
8291 { $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
8392 let mut ch = next_byte!( $parser) ;
8493
@@ -115,6 +124,50 @@ macro_rules! expect_string {
115124 } )
116125}
117126
127+ macro_rules! expect_number {
128+ ( $parser: ident, $first: ident) => ( {
129+ let mut num = ( $first - b'0' ) as u64 ;
130+ let mut digits = 0u8 ;
131+
132+ let result: f64 ;
133+
134+ // Cap on how many iterations we do while reading to u64
135+ // in order to avoid an overflow.
136+ loop {
137+ if digits == 18 {
138+ result = try!( $parser. read_big_number( num as f64 ) ) ;
139+ break ;
140+ }
141+
142+ digits += 1 ;
143+
144+ let ch = next_byte!( $parser || {
145+ result = num as f64 ;
146+ break ;
147+ } ) ;
148+
149+ match ch {
150+ b'0' ... b'9' => {
151+ // Avoid multiplication with bitshifts and addition
152+ num = ( num << 1 ) + ( num << 3 ) + ( ch - b'0' ) as u64 ;
153+ } ,
154+ b'.' | b'e' | b'E' => {
155+ $parser. index -= 1 ;
156+ result = try!( $parser. read_number_with_fraction( num as f64 ) ) ;
157+ break ;
158+ } ,
159+ _ => {
160+ $parser. index -= 1 ;
161+ result = num as f64 ;
162+ break ;
163+ }
164+ }
165+ }
166+
167+ result
168+ } )
169+ }
170+
118171macro_rules! expect_value {
119172 { $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
120173 let mut ch = next_byte!( $parser) ;
@@ -133,14 +186,14 @@ macro_rules! expect_value {
133186 JsonValue :: Number ( num)
134187 } ,
135188 b'1' ... b'9' => {
136- let num = try !( $parser. read_number ( ch ) ) ;
189+ let num = expect_number !( $parser, ch ) ;
137190 JsonValue :: Number ( num)
138191 } ,
139192 b'-' => {
140193 let ch = next_byte!( $parser) ;
141194 let num = match ch {
142195 b'0' => try!( $parser. read_number_with_fraction( 0.0 ) ) ,
143- b'1' ... b'9' => try !( $parser. read_number ( ch ) ) ,
196+ b'1' ... b'9' => expect_number !( $parser, ch ) ,
144197 _ => return $parser. unexpected_character( ch)
145198 } ;
146199 JsonValue :: Number ( -num)
@@ -162,18 +215,6 @@ macro_rules! expect_value {
162215 } )
163216}
164217
165- struct Position {
166- pub line : usize ,
167- pub column : usize ,
168- }
169-
170- struct Parser < ' a > {
171- source : & ' a str ,
172- byte_ptr : * const u8 ,
173- index : usize ,
174- length : usize ,
175- }
176-
177218impl < ' a > Parser < ' a > {
178219 pub fn new ( source : & ' a str ) -> Self {
179220 Parser {
@@ -304,41 +345,6 @@ impl<'a> Parser<'a> {
304345 Ok ( ( ) )
305346 }
306347
307- fn read_number ( & mut self , first : u8 ) -> JsonResult < f64 > {
308- let mut num = ( first - b'0' ) as u64 ;
309- let mut digits = 0u8 ;
310-
311- // Cap on how many iterations we do while reading to u64
312- // in order to avoid an overflow.
313- while digits < 18 {
314- digits += 1 ;
315-
316- let ch = next_byte ! ( self || return Ok ( num as f64 ) ) ;
317- match ch {
318- b'0' ... b'9' => {
319- // Avoid multiplication with bitshifts and addition
320- num = ( num << 1 ) + ( num << 3 ) + ( ch - b'0' ) as u64 ;
321- } ,
322- b'.' | b'e' | b'E' => {
323- self . index -= 1 ;
324- break ;
325- } ,
326- _ => {
327- self . index -= 1 ;
328- return Ok ( num as f64 ) ;
329- }
330- }
331- }
332-
333- let mut num = num as f64 ;
334-
335- // Attempt to continue reading digits that would overflow
336- // u64 into freshly converted f64
337- read_num ! ( self , digit, num = num * 10.0 + digit as f64 ) ;
338-
339- self . read_number_with_fraction ( num)
340- }
341-
342348 fn read_complex_string ( & mut self , start : usize ) -> JsonResult < String > {
343349 let mut buffer = Vec :: new ( ) ;
344350 let mut ch = b'\\' ;
@@ -378,6 +384,14 @@ impl<'a> Parser<'a> {
378384 Ok ( unsafe { String :: from_utf8_unchecked ( buffer) } )
379385 }
380386
387+ fn read_big_number ( & mut self , mut num : f64 ) -> JsonResult < f64 > {
388+ // Attempt to continue reading digits that would overflow
389+ // u64 into freshly converted f64
390+ read_num ! ( self , digit, num = num * 10.0 + digit as f64 ) ;
391+
392+ self . read_number_with_fraction ( num)
393+ }
394+
381395 fn read_number_with_fraction ( & mut self , mut num : f64 ) -> JsonResult < f64 > {
382396 if next_byte ! ( self || return Ok ( num) ) == b'.' {
383397 let mut precision = -1 ;
@@ -420,7 +434,7 @@ impl<'a> Parser<'a> {
420434 fn read_object ( & mut self ) -> JsonResult < BTreeMap < String , JsonValue > > {
421435 let mut object = BTreeMap :: new ( ) ;
422436
423- let key = expect_one_of ! { self ,
437+ let key = expect ! { self ,
424438 b'}' => return Ok ( object) ,
425439 b'\"' => expect_string!( self )
426440 } ;
@@ -430,7 +444,7 @@ impl<'a> Parser<'a> {
430444 object. insert ( key, expect_value ! ( self ) ) ;
431445
432446 loop {
433- let key = expect_one_of ! { self ,
447+ let key = expect ! { self ,
434448 b'}' => break ,
435449 b',' => {
436450 expect!( self , b'"' ) ;
@@ -453,7 +467,7 @@ impl<'a> Parser<'a> {
453467 array. push ( first) ;
454468
455469 loop {
456- expect_one_of ! { self ,
470+ expect ! { self ,
457471 b']' => break ,
458472 b',' => {
459473 let value = expect_value!( self ) ;
0 commit comments