@@ -4,41 +4,48 @@ use JsonValue;
44
55extern crate itoa;
66
7+ const _Q: u8 = b'"' ;
8+ const _S: u8 = b'\\' ;
9+ const B : u8 = b'b' ;
10+ const T : u8 = b't' ;
11+ const N : u8 = b'n' ;
12+ const F : u8 = b'f' ;
13+ const R : u8 = b'r' ;
14+ const U : u8 = b'u' ;
15+
716static ESCAPED : [ u8 ; 256 ] = [
817// 0 1 2 3 4 5 6 7 8 9 A B C D E F
9- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , b'b' , b't' , b'n' , 0 , b'f' , b'r' , 0 , 0 , // 0
10- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 1
11- 0 , 0 , b'"' , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 2
12- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 3
13- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 4
14- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , b'\\' , 0 , 0 , 0 , // 5
15- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 6
16- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 7
17- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 8
18- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 9
19- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // A
20- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // B
21- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // C
22- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // D
23- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // E
24- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // F
18+ U , U , U , U , U , U , U , U , B , T , N , U , F , R , U , U , // 0
19+ U , U , U , U , U , U , U , U , U , U , U , U , U , U , U , U , // 1
20+ 0 , 0 , _Q , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 2
21+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 3
22+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 4
23+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , _S , 0 , 0 , 0 , // 5
24+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 6
25+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , U , // 7
26+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 8
27+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 9
28+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // A
29+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // B
30+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // C
31+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // D
32+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // E
33+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // F
2534] ;
2635
2736pub trait Generator {
28- fn get_buffer ( & mut self ) -> & mut Vec < u8 > ;
37+ type T : Write ;
2938
30- fn current_index ( & mut self ) -> usize {
31- self . get_buffer ( ) . len ( )
32- }
39+ fn get_writer ( & mut self ) -> & mut Self :: T ;
3340
3441 #[ inline( always) ]
3542 fn write ( & mut self , slice : & [ u8 ] ) {
36- self . get_buffer ( ) . extend_from_slice ( slice)
43+ self . get_writer ( ) . write_all ( slice) . unwrap ( ) ;
3744 }
3845
3946 #[ inline( always) ]
4047 fn write_char ( & mut self , ch : u8 ) {
41- self . get_buffer ( ) . push ( ch )
48+ self . get_writer ( ) . write ( & [ ch ] ) . unwrap ( ) ;
4249 }
4350
4451 fn write_min ( & mut self , slice : & [ u8 ] , min : u8 ) ;
@@ -49,6 +56,7 @@ pub trait Generator {
4956
5057 fn dedent ( & mut self ) { }
5158
59+ #[ inline( never) ]
5260 fn write_string_complex ( & mut self , string : & str , mut start : usize ) {
5361 for ( index, ch) in string. bytes ( ) . enumerate ( ) . skip ( start) {
5462 let escape = ESCAPED [ ch as usize ] ;
@@ -82,13 +90,13 @@ pub trait Generator {
8290 FpCategory :: Normal |
8391 FpCategory :: Subnormal => {
8492 if num. fract ( ) == 0.0 && num. abs ( ) < 1e19 {
85- itoa:: write ( self . get_buffer ( ) , num as i64 ) . unwrap ( ) ;
93+ itoa:: write ( self . get_writer ( ) , num as i64 ) . unwrap ( ) ;
8694 } else {
8795 let abs = num. abs ( ) ;
8896 if abs < 1e-15 || abs > 1e19 {
89- write ! ( self . get_buffer ( ) , "{:e}" , num) . unwrap ( ) ;
97+ write ! ( self . get_writer ( ) , "{:e}" , num) . unwrap ( ) ;
9098 } else {
91- write ! ( self . get_buffer ( ) , "{}" , num) . unwrap ( ) ;
99+ write ! ( self . get_writer ( ) , "{}" , num) . unwrap ( ) ;
92100 }
93101 }
94102 } ,
@@ -153,8 +161,6 @@ pub trait Generator {
153161 }
154162 }
155163 }
156-
157- fn consume ( self ) -> String ;
158164}
159165
160166pub struct DumpGenerator {
@@ -167,22 +173,34 @@ impl DumpGenerator {
167173 code : Vec :: with_capacity ( 1024 ) ,
168174 }
169175 }
176+
177+ pub fn consume ( self ) -> String {
178+ String :: from_utf8 ( self . code ) . unwrap ( )
179+ }
170180}
171181
172182impl Generator for DumpGenerator {
183+ type T = Vec < u8 > ;
184+
185+ #[ inline( always) ]
186+ fn write ( & mut self , slice : & [ u8 ] ) {
187+ self . code . extend_from_slice ( slice)
188+ }
189+
173190 #[ inline( always) ]
174- fn get_buffer ( & mut self ) -> & mut Vec < u8 > {
191+ fn write_char ( & mut self , ch : u8 ) {
192+ self . code . push ( ch)
193+ }
194+
195+ #[ inline( always) ]
196+ fn get_writer ( & mut self ) -> & mut Vec < u8 > {
175197 & mut self . code
176198 }
177199
178200 #[ inline( always) ]
179201 fn write_min ( & mut self , _: & [ u8 ] , min : u8 ) {
180202 self . code . push ( min) ;
181203 }
182-
183- fn consume ( self ) -> String {
184- String :: from_utf8 ( self . code ) . unwrap ( )
185- }
186204}
187205
188206pub struct PrettyGenerator {
@@ -199,11 +217,27 @@ impl PrettyGenerator {
199217 spaces_per_indent : spaces
200218 }
201219 }
220+
221+ pub fn consume ( self ) -> String {
222+ String :: from_utf8 ( self . code ) . unwrap ( )
223+ }
202224}
203225
204226impl Generator for PrettyGenerator {
227+ type T = Vec < u8 > ;
228+
205229 #[ inline( always) ]
206- fn get_buffer ( & mut self ) -> & mut Vec < u8 > {
230+ fn write ( & mut self , slice : & [ u8 ] ) {
231+ self . code . extend_from_slice ( slice)
232+ }
233+
234+ #[ inline( always) ]
235+ fn write_char ( & mut self , ch : u8 ) {
236+ self . code . push ( ch)
237+ }
238+
239+ #[ inline( always) ]
240+ fn get_writer ( & mut self ) -> & mut Vec < u8 > {
207241 & mut self . code
208242 }
209243
@@ -226,8 +260,30 @@ impl Generator for PrettyGenerator {
226260 fn dedent ( & mut self ) {
227261 self . dent -= 1 ;
228262 }
263+ }
229264
230- fn consume ( self ) -> String {
231- String :: from_utf8 ( self . code ) . unwrap ( )
265+ pub struct WriterGenerator < ' a , W : ' a + Write > {
266+ writer : & ' a mut W
267+ }
268+
269+ impl < ' a , W > WriterGenerator < ' a , W > where W : ' a + Write {
270+ pub fn new ( writer : & ' a mut W ) -> Self {
271+ WriterGenerator {
272+ writer : writer
273+ }
274+ }
275+ }
276+
277+ impl < ' a , W > Generator for WriterGenerator < ' a , W > where W : Write {
278+ type T = W ;
279+
280+ #[ inline( always) ]
281+ fn get_writer ( & mut self ) -> & mut W {
282+ & mut self . writer
283+ }
284+
285+ #[ inline( always) ]
286+ fn write_min ( & mut self , _: & [ u8 ] , min : u8 ) {
287+ self . writer . write ( & [ min] ) . unwrap ( ) ;
232288 }
233289}
0 commit comments