@@ -256,22 +256,63 @@ fn io_error_to_error(io: io::IoError) -> ParserError {
256256pub type EncodeResult = io:: IoResult < ( ) > ;
257257pub type DecodeResult < T > = Result < T , DecoderError > ;
258258
259- fn escape_str ( s : & str ) -> String {
260- let mut escaped = String :: from_str ( "\" " ) ;
261- for c in s. chars ( ) {
262- match c {
263- '"' => escaped. push_str ( "\\ \" " ) ,
264- '\\' => escaped. push_str ( "\\ \\ " ) ,
265- '\x08' => escaped. push_str ( "\\ b" ) ,
266- '\x0c' => escaped. push_str ( "\\ f" ) ,
267- '\n' => escaped. push_str ( "\\ n" ) ,
268- '\r' => escaped. push_str ( "\\ r" ) ,
269- '\t' => escaped. push_str ( "\\ t" ) ,
270- _ => escaped. push_char ( c) ,
259+ pub fn escape_bytes ( wr : & mut io:: Writer , bytes : & [ u8 ] ) -> Result < ( ) , io:: IoError > {
260+ try!( wr. write_str ( "\" " ) ) ;
261+
262+ let mut start = 0 ;
263+
264+ for ( i, byte) in bytes. iter ( ) . enumerate ( ) {
265+ let escaped = match * byte {
266+ b'"' => "\\ \" " ,
267+ b'\\' => "\\ \\ " ,
268+ b'\x08' => "\\ b" ,
269+ b'\x0c' => "\\ f" ,
270+ b'\n' => "\\ n" ,
271+ b'\r' => "\\ r" ,
272+ b'\t' => "\\ t" ,
273+ _ => { continue ; }
274+ } ;
275+
276+ if start < i {
277+ try!( wr. write ( bytes. slice ( start, i) ) ) ;
271278 }
272- } ;
273- escaped. push_char ( '"' ) ;
274- escaped
279+
280+ try!( wr. write_str ( escaped) ) ;
281+
282+ start = i + 1 ;
283+ }
284+
285+ if start != bytes. len ( ) {
286+ try!( wr. write ( bytes. slice_from ( start) ) ) ;
287+ }
288+
289+ wr. write_str ( "\" " )
290+ }
291+
292+ fn escape_str ( writer : & mut io:: Writer , v : & str ) -> Result < ( ) , io:: IoError > {
293+ escape_bytes ( writer, v. as_bytes ( ) )
294+ }
295+
296+ fn escape_char ( writer : & mut io:: Writer , v : char ) -> Result < ( ) , io:: IoError > {
297+ let mut buf = [ 0 , .. 4 ] ;
298+ v. encode_utf8 ( buf) ;
299+ escape_bytes ( writer, buf)
300+ }
301+
302+ fn spaces ( wr : & mut io:: Writer , mut n : uint ) -> Result < ( ) , io:: IoError > {
303+ static len: uint = 16 ;
304+ static buf: [ u8 , ..len ] = [ b' ' , ..len] ;
305+
306+ while n >= len {
307+ try!( wr. write ( buf) ) ;
308+ n -= len;
309+ }
310+
311+ if n > 0 {
312+ wr. write ( buf. slice_to ( n) )
313+ } else {
314+ Ok ( ( ) )
315+ }
275316}
276317
277318fn fmt_number_or_null ( v : f64 ) -> String {
@@ -281,10 +322,6 @@ fn fmt_number_or_null(v: f64) -> String {
281322 }
282323}
283324
284- fn spaces ( n : uint ) -> String {
285- String :: from_char ( n, ' ' )
286- }
287-
288325/// A structure for implementing serialization to JSON.
289326pub struct Encoder < ' a > {
290327 writer : & ' a mut io:: Writer ,
@@ -348,10 +385,10 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
348385 fn emit_f32 ( & mut self , v : f32 ) -> EncodeResult { self . emit_f64 ( v as f64 ) }
349386
350387 fn emit_char ( & mut self , v : char ) -> EncodeResult {
351- self . emit_str ( str :: from_char ( v ) . as_slice ( ) )
388+ escape_char ( self . writer , v )
352389 }
353390 fn emit_str ( & mut self , v : & str ) -> EncodeResult {
354- write ! ( self . writer, "{}" , escape_str ( v ) )
391+ escape_str ( self . writer , v )
355392 }
356393
357394 fn emit_enum ( & mut self , _name : & str , f: |& mut Encoder < ' a > | -> EncodeResult ) -> EncodeResult {
@@ -367,10 +404,10 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
367404 // Bunny => "Bunny"
368405 // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
369406 if cnt == 0 {
370- write ! ( self . writer, "{}" , escape_str ( name) )
407+ escape_str ( self . writer , name)
371408 } else {
372409 try!( write ! ( self . writer, "{{\" variant\" :" ) ) ;
373- try!( write ! ( self . writer, "{}" , escape_str ( name) ) ) ;
410+ try!( escape_str ( self . writer , name) ) ;
374411 try!( write ! ( self . writer, ",\" fields\" :[" ) ) ;
375412 try!( f ( self ) ) ;
376413 write ! ( self . writer, "]}}" )
@@ -415,7 +452,8 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
415452 idx : uint ,
416453 f: |& mut Encoder < ' a > | -> EncodeResult ) -> EncodeResult {
417454 if idx != 0 { try!( write ! ( self . writer, "," ) ) ; }
418- try!( write ! ( self . writer, "{}:" , escape_str( name) ) ) ;
455+ try!( escape_str ( self . writer , name) ) ;
456+ try!( write ! ( self . writer, ":" ) ) ;
419457 f ( self )
420458 }
421459
@@ -541,10 +579,10 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
541579 }
542580
543581 fn emit_char ( & mut self , v : char ) -> EncodeResult {
544- self . emit_str ( str :: from_char ( v ) . as_slice ( ) )
582+ escape_char ( self . writer , v )
545583 }
546584 fn emit_str ( & mut self , v : & str ) -> EncodeResult {
547- write ! ( self . writer, "{}" , escape_str ( v ) )
585+ escape_str ( self . writer , v )
548586 }
549587
550588 fn emit_enum ( & mut self ,
@@ -559,14 +597,18 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
559597 cnt : uint ,
560598 f: |& mut PrettyEncoder < ' a > | -> EncodeResult ) -> EncodeResult {
561599 if cnt == 0 {
562- write ! ( self . writer, "{}" , escape_str ( name) )
600+ escape_str ( self . writer, name)
563601 } else {
564602 self . indent += 2 ;
565- try!( write ! ( self . writer, "[\n {}{},\n " , spaces( self . indent) ,
566- escape_str( name) ) ) ;
603+ try!( write ! ( self . writer, "[\n " ) ) ;
604+ try!( spaces( self . writer, self . indent) ) ;
605+ try!( escape_str( self . writer, name) ) ;
606+ try!( write ! ( self . writer, ",\n " ) ) ;
567607 try!( f ( self ) ) ;
568608 self . indent -= 2 ;
569- write ! ( self . writer, "\n {}]" , spaces( self . indent) )
609+ try!( write ! ( self . writer, "\n " ) ) ;
610+ try!( spaces( self . writer, self . indent) ) ;
611+ write ! ( self . writer, "]" )
570612 }
571613 }
572614
@@ -576,7 +618,7 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
576618 if idx != 0 {
577619 try!( write ! ( self . writer, ",\n " ) ) ;
578620 }
579- try!( write ! ( self . writer, "{}" , spaces ( self . indent) ) ) ;
621+ try!( spaces ( self . writer, self . indent) ) ;
580622 f ( self )
581623 }
582624
@@ -607,7 +649,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
607649 self . indent += 2 ;
608650 try!( f ( self ) ) ;
609651 self . indent -= 2 ;
610- write ! ( self . writer, "\n {}}}" , spaces( self . indent) )
652+ try!( write ! ( self . writer, "\n " ) ) ;
653+ try!( spaces( self . writer, self . indent) ) ;
654+ write ! ( self . writer, "}}" )
611655 }
612656 }
613657
@@ -620,7 +664,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
620664 } else {
621665 try!( write ! ( self . writer, ",\n " ) ) ;
622666 }
623- try!( write ! ( self . writer, "{}{}: " , spaces( self . indent) , escape_str( name) ) ) ;
667+ try!( spaces( self . writer, self . indent) ) ;
668+ try!( escape_str( self . writer, name) ) ;
669+ try!( write ! ( self . writer, ": " ) ) ;
624670 f ( self )
625671 }
626672
@@ -665,7 +711,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
665711 self . indent += 2 ;
666712 try!( f( self ) ) ;
667713 self . indent -= 2 ;
668- write ! ( self . writer, "\n {}]" , spaces( self . indent) )
714+ try!( write ! ( self . writer, "\n " ) ) ;
715+ try!( spaces( self . writer, self . indent) ) ;
716+ write ! ( self . writer, "]" )
669717 }
670718 }
671719
@@ -677,7 +725,7 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
677725 } else {
678726 try!( write ! ( self . writer, ",\n " ) ) ;
679727 }
680- try!( write ! ( self . writer, "{}" , spaces ( self . indent) ) ) ;
728+ try!( spaces ( self . writer, self . indent) ) ;
681729 f( self )
682730 }
683731
@@ -691,7 +739,9 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
691739 self . indent += 2 ;
692740 try!( f( self ) ) ;
693741 self . indent -= 2 ;
694- write ! ( self . writer, "\n {}}}" , spaces( self . indent) )
742+ try!( write ! ( self . writer, "\n " ) ) ;
743+ try!( spaces( self . writer, self . indent) ) ;
744+ write ! ( self . writer, "}}" )
695745 }
696746 }
697747
@@ -703,7 +753,7 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
703753 } else {
704754 try!( write ! ( self . writer, ",\n " ) ) ;
705755 }
706- try!( write ! ( self . writer, "{}" , spaces ( self . indent) ) ) ;
756+ try!( spaces ( self . writer, self . indent) ) ;
707757 // ref #12967, make sure to wrap a key in double quotes,
708758 // in the event that its of a type that omits them (eg numbers)
709759 let mut buf = MemWriter :: new( ) ;
0 commit comments