@@ -18,26 +18,22 @@ struct Parser<'a> {
18
18
length : usize ,
19
19
}
20
20
21
- macro_rules! next_byte {
22
- ( $parser: ident || $alt: expr) => {
23
- if $parser. index < $parser. length {
24
- let ch = unsafe { * $parser. byte_ptr. offset( $parser. index as isize ) } ;
25
- $parser. index += 1 ;
26
- ch
27
- } else {
28
- $alt
21
+ macro_rules! expect_byte {
22
+ ( $parser: ident) => ( {
23
+ if $parser. is_eof( ) {
24
+ return Err ( JsonError :: UnexpectedEndOfJson ) ;
29
25
}
30
- } ;
31
26
32
- ( $parser: ident) => {
33
- next_byte!( $parser || return Err ( JsonError :: UnexpectedEndOfJson ) )
34
- }
27
+ let ch = $parser. read_byte( ) ;
28
+ $parser. bump( ) ;
29
+ ch
30
+ } )
35
31
}
36
32
37
33
macro_rules! sequence {
38
34
( $parser: ident, $( $ch: pat ) ,* ) => {
39
35
$(
40
- match next_byte !( $parser) {
36
+ match expect_byte !( $parser) {
41
37
$ch => { } ,
42
38
ch => return $parser. unexpected_character( ch) ,
43
39
}
@@ -48,16 +44,15 @@ macro_rules! sequence {
48
44
macro_rules! read_num {
49
45
( $parser: ident, $num: ident, $then: expr) => {
50
46
loop {
51
- let ch = next_byte!( $parser || break ) ;
47
+ if $parser. is_eof( ) { break ; }
48
+ let ch = $parser. read_byte( ) ;
52
49
match ch {
53
50
b'0' ... b'9' => {
51
+ $parser. bump( ) ;
54
52
let $num = ch - b'0' ;
55
53
$then;
56
54
} ,
57
- _ => {
58
- $parser. index -= 1 ;
59
- break ;
60
- }
55
+ _ => break
61
56
}
62
57
}
63
58
}
@@ -69,7 +64,7 @@ macro_rules! consume_whitespace {
69
64
// whitespace
70
65
9 ... 13 | 32 => {
71
66
loop {
72
- match next_byte !( $parser) {
67
+ match expect_byte !( $parser) {
73
68
9 ... 13 | 32 => { } ,
74
69
ch => { $ch = ch; break }
75
70
}
@@ -82,7 +77,7 @@ macro_rules! consume_whitespace {
82
77
83
78
macro_rules! expect {
84
79
( $parser: ident, $byte: expr) => ( {
85
- let mut ch = next_byte !( $parser) ;
80
+ let mut ch = expect_byte !( $parser) ;
86
81
87
82
consume_whitespace!( $parser, ch) ;
88
83
@@ -92,7 +87,7 @@ macro_rules! expect {
92
87
} ) ;
93
88
94
89
{ $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
95
- let mut ch = next_byte !( $parser) ;
90
+ let mut ch = expect_byte !( $parser) ;
96
91
97
92
consume_whitespace!( $parser, ch) ;
98
93
@@ -136,7 +131,7 @@ macro_rules! expect_string {
136
131
let start = $parser. index;
137
132
138
133
loop {
139
- let ch = next_byte !( $parser) ;
134
+ let ch = expect_byte !( $parser) ;
140
135
if CHARCODES [ ch as usize ] == 0 {
141
136
continue ;
142
137
}
@@ -192,37 +187,35 @@ fn make_float(num: u64, e: i32) -> f64 {
192
187
macro_rules! expect_number {
193
188
( $parser: ident, $first: ident) => ( {
194
189
let mut num = ( $first - b'0' ) as u64 ;
195
- let mut digits = 0u8 ;
196
190
197
191
let result: f64 ;
198
192
199
193
// Cap on how many iterations we do while reading to u64
200
194
// in order to avoid an overflow.
201
195
loop {
202
- if digits == 18 {
196
+ if num >= 576460752303423500 {
203
197
result = try!( $parser. read_big_number( num) ) ;
204
198
break ;
205
199
}
206
200
207
- digits += 1 ;
208
-
209
- let ch = next_byte!( $parser || {
201
+ if $parser. is_eof( ) {
210
202
result = num as f64 ;
211
203
break ;
212
- } ) ;
204
+ }
205
+
206
+ let ch = $parser. read_byte( ) ;
213
207
214
208
match ch {
215
209
b'0' ... b'9' => {
210
+ $parser. bump( ) ;
216
211
// Avoid multiplication with bitshifts and addition
217
212
num = ( num << 1 ) + ( num << 3 ) + ( ch - b'0' ) as u64 ;
218
213
} ,
219
214
b'.' | b'e' | b'E' => {
220
- $parser. index -= 1 ;
221
215
result = try!( $parser. read_number_with_fraction( num, 0 ) ) ;
222
216
break ;
223
217
} ,
224
218
_ => {
225
- $parser. index -= 1 ;
226
219
result = num as f64 ;
227
220
break ;
228
221
}
@@ -235,7 +228,7 @@ macro_rules! expect_number {
235
228
236
229
macro_rules! expect_value {
237
230
{ $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
238
- let mut ch = next_byte !( $parser) ;
231
+ let mut ch = expect_byte !( $parser) ;
239
232
240
233
consume_whitespace!( $parser, ch) ;
241
234
@@ -255,7 +248,7 @@ macro_rules! expect_value {
255
248
JsonValue :: Number ( num)
256
249
} ,
257
250
b'-' => {
258
- let ch = next_byte !( $parser) ;
251
+ let ch = expect_byte !( $parser) ;
259
252
let num = match ch {
260
253
b'0' => try!( $parser. read_number_with_fraction( 0 , 0 ) ) ,
261
254
b'1' ... b'9' => expect_number!( $parser, ch) ,
@@ -290,7 +283,22 @@ impl<'a> Parser<'a> {
290
283
}
291
284
}
292
285
293
- pub fn source_position_from_index ( & self , index : usize ) -> Position {
286
+ #[ inline( always) ]
287
+ fn is_eof ( & mut self ) -> bool {
288
+ self . index == self . length
289
+ }
290
+
291
+ #[ inline( always) ]
292
+ fn read_byte ( & mut self ) -> u8 {
293
+ unsafe { * self . byte_ptr . offset ( self . index as isize ) }
294
+ }
295
+
296
+ #[ inline( always) ]
297
+ fn bump ( & mut self ) {
298
+ self . index += 1 ;
299
+ }
300
+
301
+ fn source_position_from_index ( & self , index : usize ) -> Position {
294
302
let ( bytes, _) = self . source . split_at ( index-1 ) ;
295
303
296
304
Position {
@@ -311,18 +319,18 @@ impl<'a> Parser<'a> {
311
319
if byte & 0xE0 == 0xCE {
312
320
// 2 bytes, 11 bits
313
321
len = 2 ;
314
- buf[ 1 ] = next_byte ! ( self ) ;
322
+ buf[ 1 ] = expect_byte ! ( self ) ;
315
323
} else if byte & 0xF0 == 0xE0 {
316
324
// 3 bytes, 16 bits
317
325
len = 3 ;
318
- buf[ 1 ] = next_byte ! ( self ) ;
319
- buf[ 2 ] = next_byte ! ( self ) ;
326
+ buf[ 1 ] = expect_byte ! ( self ) ;
327
+ buf[ 2 ] = expect_byte ! ( self ) ;
320
328
} else if byte & 0xF8 == 0xF0 {
321
329
// 4 bytes, 21 bits
322
330
len = 4 ;
323
- buf[ 1 ] = next_byte ! ( self ) ;
324
- buf[ 2 ] = next_byte ! ( self ) ;
325
- buf[ 3 ] = next_byte ! ( self ) ;
331
+ buf[ 1 ] = expect_byte ! ( self ) ;
332
+ buf[ 2 ] = expect_byte ! ( self ) ;
333
+ buf[ 3 ] = expect_byte ! ( self ) ;
326
334
}
327
335
328
336
let slice = try!(
@@ -345,7 +353,7 @@ impl<'a> Parser<'a> {
345
353
}
346
354
347
355
fn read_hexdec_digit ( & mut self ) -> JsonResult < u32 > {
348
- let ch = next_byte ! ( self ) ;
356
+ let ch = expect_byte ! ( self ) ;
349
357
Ok ( match ch {
350
358
b'0' ... b'9' => ( ch - b'0' ) ,
351
359
b'a' ... b'f' => ( ch + 10 - b'a' ) ,
@@ -418,17 +426,17 @@ impl<'a> Parser<'a> {
418
426
loop {
419
427
if CHARCODES [ ch as usize ] == 0 {
420
428
buffer. push ( ch) ;
421
- ch = next_byte ! ( self ) ;
429
+ ch = expect_byte ! ( self ) ;
422
430
continue ;
423
431
}
424
432
match ch {
425
433
b'"' => break ,
426
434
b'\\' => {
427
- let escaped = next_byte ! ( self ) ;
435
+ let escaped = expect_byte ! ( self ) ;
428
436
let escaped = match escaped {
429
437
b'u' => {
430
438
try!( self . read_codepoint ( & mut buffer) ) ;
431
- ch = next_byte ! ( self ) ;
439
+ ch = expect_byte ! ( self ) ;
432
440
continue ;
433
441
} ,
434
442
b'"' |
@@ -445,7 +453,7 @@ impl<'a> Parser<'a> {
445
453
} ,
446
454
_ => return self . unexpected_character ( ch)
447
455
}
448
- ch = next_byte ! ( self ) ;
456
+ ch = expect_byte ! ( self ) ;
449
457
}
450
458
451
459
// Since the original source is already valid UTF-8, and `\`
@@ -459,64 +467,75 @@ impl<'a> Parser<'a> {
459
467
460
468
let mut e = 0i32 ;
461
469
loop {
462
- match next_byte ! ( self || break ) {
463
- b'0' ... b'9' => e += 1 ,
464
- _ => {
465
- self . index -= 1 ;
466
- break ;
467
- }
470
+ if self . is_eof ( ) {
471
+ return Ok ( make_float ( num, e) ) ;
472
+ }
473
+ match self . read_byte ( ) {
474
+ b'0' ... b'9' => {
475
+ self . bump ( ) ;
476
+ e += 1 ;
477
+ } ,
478
+ _ => break
468
479
}
469
480
}
470
481
471
482
self . read_number_with_fraction ( num, e)
472
483
}
473
484
474
485
fn read_number_with_fraction ( & mut self , mut num : u64 , mut e : i32 ) -> JsonResult < f64 > {
475
- if next_byte ! ( self || return Ok ( make_float( num, e) ) ) == b'.' {
486
+ if self . is_eof ( ) {
487
+ return Ok ( make_float ( num, e) ) ;
488
+ }
489
+
490
+ let mut ch = self . read_byte ( ) ;
491
+
492
+ if ch == b'.' {
493
+ self . bump ( ) ;
494
+
476
495
loop {
477
- let ch = next_byte ! ( self || break ) ;
496
+ if self . is_eof ( ) {
497
+ return Ok ( make_float ( num, e) ) ;
498
+ }
499
+ ch = self . read_byte ( ) ;
478
500
479
501
match ch {
480
502
b'0' ... b'9' => {
503
+ self . bump ( ) ;
481
504
if num < MAX_FLOAT_PRECISION {
482
- num = num * 10 + ( ch - b'0' ) as u64 ;
505
+ num = ( num << 3 ) + ( num << 1 ) + ( ch - b'0' ) as u64 ;
483
506
e -= 1 ;
484
507
}
485
508
} ,
486
- _ => {
487
- self . index -= 1 ;
488
- break ;
489
- }
509
+ _ => break
490
510
}
491
511
}
492
- } else {
493
- self . index -= 1 ;
494
512
}
495
513
496
- match next_byte ! ( self || return Ok ( make_float( num, e) ) ) {
497
- b'e' | b'E' => {
498
- let sign = match next_byte ! ( self ) {
499
- b'-' => -1 ,
500
- b'+' => 1 ,
501
- _ => {
502
- self . index -= 1 ;
503
- 1
504
- } ,
505
- } ;
514
+ if ch == b'e' || ch == b'E' {
515
+ self . bump ( ) ;
516
+ ch = expect_byte ! ( self ) ;
517
+ let sign = match ch {
518
+ b'-' => {
519
+ ch = expect_byte ! ( self ) ;
520
+ -1
521
+ } ,
522
+ b'+' => {
523
+ ch = expect_byte ! ( self ) ;
524
+ 1
525
+ } ,
526
+ _ => 1
527
+ } ;
506
528
507
- let num = make_float ( num, e) ;
529
+ let num = make_float ( num, e) ;
508
530
509
- let ch = next_byte ! ( self ) ;
510
- let mut e = match ch {
511
- b'0' ... b'9' => ( ch - b'0' ) as i32 ,
512
- _ => return self . unexpected_character ( ch) ,
513
- } ;
531
+ let mut e = match ch {
532
+ b'0' ... b'9' => ( ch - b'0' ) as i32 ,
533
+ _ => return self . unexpected_character ( ch) ,
534
+ } ;
514
535
515
- read_num ! ( self , digit, e = ( e << 3 ) + ( e << 1 ) + digit as i32 ) ;
536
+ read_num ! ( self , digit, e = ( e << 3 ) + ( e << 1 ) + digit as i32 ) ;
516
537
517
- return Ok ( num * exponent_to_power ( e * sign) ) ;
518
- } ,
519
- _ => self . index -= 1
538
+ return Ok ( num * exponent_to_power ( e * sign) ) ;
520
539
}
521
540
522
541
Ok ( make_float ( num, e) )
@@ -571,15 +590,17 @@ impl<'a> Parser<'a> {
571
590
}
572
591
573
592
fn ensure_end ( & mut self ) -> JsonResult < ( ) > {
574
- let mut ch = next_byte ! ( self || return Ok ( ( ) ) ) ;
575
- loop {
576
- match ch {
577
- // whitespace
578
- 9 ... 13 | 32 => { } ,
579
- _ => return self . unexpected_character ( ch)
593
+ while !self . is_eof ( ) {
594
+ match self . read_byte ( ) {
595
+ 9 ... 13 | 32 => self . bump ( ) ,
596
+ ch => {
597
+ self . bump ( ) ;
598
+ return self . unexpected_character ( ch) ;
599
+ }
580
600
}
581
- ch = next_byte ! ( self || return Ok ( ( ) ) ) ;
582
601
}
602
+
603
+ Ok ( ( ) )
583
604
}
584
605
585
606
fn value ( & mut self ) -> JsonResult < JsonValue > {
0 commit comments