11use std:: char;
22use std:: str;
33use std:: str:: Bytes ;
4- use std:: iter:: { Peekable , Iterator } ;
54use std:: collections:: BTreeMap ;
65use { JsonValue , JsonError , JsonResult } ;
76
@@ -29,26 +28,63 @@ macro_rules! expect_char {
2928 }
3029}
3130
31+ macro_rules! read_num {
32+ ( $tok: ident, $num: ident, $then: expr) => {
33+ while let Some ( ch) = $tok. next_byte( ) {
34+ match ch {
35+ b'0' ... b'9' => {
36+ let $num = ch - b'0' ;
37+ $then;
38+ } ,
39+ ch => {
40+ $tok. left_over = Some ( ch) ;
41+ break ;
42+ }
43+ }
44+ }
45+ }
46+ }
47+
3248struct Tokenizer < ' a > {
33- source : Peekable < Bytes < ' a > > ,
49+ source : Bytes < ' a > ,
3450 buffer : Vec < u8 > ,
51+ left_over : Option < u8 > ,
3552}
3653
3754impl < ' a > Tokenizer < ' a > {
3855 pub fn new ( source : & ' a str ) -> Self {
3956 Tokenizer {
40- source : source. bytes ( ) . peekable ( ) ,
41- buffer : Vec :: with_capacity ( 500 )
57+ source : source. bytes ( ) ,
58+ buffer : Vec :: with_capacity ( 512 ) ,
59+ left_over : None ,
60+ }
61+ }
62+
63+ fn peek_byte ( & mut self ) -> Option < u8 > {
64+ if self . left_over . is_none ( ) {
65+ self . left_over = self . source . next ( ) ;
66+ }
67+
68+ return self . left_over ;
69+ }
70+
71+ fn next_byte ( & mut self ) -> Option < u8 > {
72+ if self . left_over . is_some ( ) {
73+ let byte = self . left_over ;
74+ self . left_over = None ;
75+ return byte;
4276 }
77+
78+ self . source . next ( )
4379 }
4480
4581 #[ inline( always) ]
46- fn expect ( & mut self ) -> JsonResult < u8 > {
47- self . source . next ( ) . ok_or ( JsonError :: UnexpectedEndOfJson )
82+ fn expect_byte ( & mut self ) -> JsonResult < u8 > {
83+ self . next_byte ( ) . ok_or ( JsonError :: UnexpectedEndOfJson )
4884 }
4985
5086 fn read_char_as_hexnumber ( & mut self ) -> JsonResult < u32 > {
51- let ch = try!( self . expect ( ) ) ;
87+ let ch = try!( self . expect_byte ( ) ) ;
5288 Ok ( match ch {
5389 b'0' ... b'9' => ( ch - b'0' ) as u32 ,
5490 b'a' ... b'f' => ( ch + 10 - b'a' ) as u32 ,
@@ -78,11 +114,11 @@ impl<'a> Tokenizer<'a> {
78114 self . buffer . clear ( ) ;
79115
80116 loop {
81- let ch = try!( self . expect ( ) ) ;
117+ let ch = try!( self . expect_byte ( ) ) ;
82118 match ch {
83119 b'"' => break ,
84120 b'\\' => {
85- let ch = try!( self . expect ( ) ) ;
121+ let ch = try!( self . expect_byte ( ) ) ;
86122 let ch = match ch {
87123 b'b' => 0x8 ,
88124 b'f' => 0xC ,
@@ -108,79 +144,57 @@ impl<'a> Tokenizer<'a> {
108144 fn read_number ( & mut self , first : u8 ) -> JsonResult < f64 > {
109145 let mut num = if first == b'-' { 0 } else { ( first - b'0' ) as u64 } ;
110146
111- while let Some ( & ch) = self . source . peek ( ) {
112- match ch {
113- b'0' ... b'9' => {
114- num = num * 10 + ( ch - b'0' ) as u64 ;
115- } ,
116- _ => break
117- }
118- self . source . next ( ) ;
119- }
147+ read_num ! ( self , digit, num = num * 10 + digit as u64 ) ;
120148
121- match self . source . peek ( ) {
122- Some ( & b'.' ) | Some ( & b'e' ) | Some ( & b'E' ) => { } ,
123- _ => return Ok ( if first == b'-' {
124- ( num as f64 ) * -1.0
125- } else {
126- num as f64
127- } )
149+ match self . peek_byte ( ) {
150+ Some ( b'.' ) | Some ( b'e' ) | Some ( b'E' ) => { } ,
151+ _ => {
152+ return if first == b'-' {
153+ Ok ( ( num as f64 ) * -1.0 )
154+ } else {
155+ Ok ( num as f64 )
156+ } ;
157+ }
128158 }
129159
130160 let mut num = num as f64 ;
131161
132- if let Some ( & b'.' ) = self . source . peek ( ) {
133- self . source . next ( ) ;
162+ if let Some ( b'.' ) = self . peek_byte ( ) {
163+ self . next_byte ( ) ;
134164
135165 let mut precision = -1 ;
136- while let Some ( & ch) = self . source . peek ( ) {
137- match ch {
138- b'0' ... b'9' => {
139- num += ( ( ch - b'0' ) as f64 ) * 10f64 . powi ( precision) ;
140- precision -= 1 ;
141- } ,
142- _ => break
143- }
144- self . source . next ( ) ;
145- }
146- }
147166
148- match self . source . peek ( ) {
149- Some ( & b'e' ) | Some ( & b'E' ) => {
150- self . source . next ( ) ;
167+ read_num ! ( self , digit, {
168+ num += ( digit as f64 ) * 10_f64 . powi( precision) ;
169+ precision -= 1 ;
170+ } ) ;
171+ }
151172
173+ match self . next_byte ( ) {
174+ Some ( b'e' ) | Some ( b'E' ) => {
152175 let mut e = 0 ;
153- let sign = match self . source . peek ( ) {
154- Some ( & b'-' ) => {
155- self . source . next ( ) ;
156- -1
157- } ,
158- Some ( & b'+' ) => {
159- self . source . next ( ) ;
176+ let sign = match self . next_byte ( ) {
177+ Some ( b'-' ) => -1 ,
178+ Some ( b'+' ) => 1 ,
179+ byte => {
180+ self . left_over = byte;
160181 1
161182 } ,
162- _ => 1
163183 } ;
164184
165- while let Some ( & ch) = self . source . peek ( ) {
166- match ch {
167- b'0' ... b'9' => e = e * 10 + ( ch - b'0' ) as i32 ,
168- _ => break
169- }
170- self . source . next ( ) ;
171- }
185+ read_num ! ( self , digit, e = e * 10 + digit as i32 ) ;
172186
173187 num *= 10f64 . powi ( e * sign) ;
174188 } ,
175- _ => { }
189+ byte => self . left_over = byte
176190 }
177191
178192 Ok ( if first == b'-' { num * -1.0 } else { num } )
179193 }
180194
181195 fn next ( & mut self ) -> JsonResult < Token > {
182196 loop {
183- let ch = try!( self . expect ( ) ) ;
197+ let ch = try!( self . expect_byte ( ) ) ;
184198 return Ok ( match ch {
185199 b',' => Token :: Comma ,
186200 b':' => Token :: Colon ,
0 commit comments