@@ -26,19 +26,19 @@ pub enum EscapeState {
2626}
2727
2828/// Bytes we need to present as escaped octal, in the form of `\nnn` per byte.
29- /// Only supports characters up to 2 bytes long in UTF-8.
29+ /// Supports characters up to 4 bytes long in UTF-8.
3030pub struct EscapeOctal {
31- c : [ u8 ; 2 ] ,
31+ bytes : [ u8 ; 4 ] ,
32+ num_bytes : usize ,
33+ byte_idx : usize ,
34+ digit_idx : u8 ,
3235 state : EscapeOctalState ,
33- idx : u8 ,
3436}
3537
3638enum EscapeOctalState {
3739 Done ,
38- FirstBackslash ,
39- FirstValue ,
40- LastBackslash ,
41- LastValue ,
40+ Backslash ,
41+ Value ,
4242}
4343
4444fn byte_to_octal_digit ( byte : u8 , idx : u8 ) -> u8 {
@@ -51,30 +51,23 @@ impl Iterator for EscapeOctal {
5151 fn next ( & mut self ) -> Option < char > {
5252 match self . state {
5353 EscapeOctalState :: Done => None ,
54- EscapeOctalState :: FirstBackslash => {
55- self . state = EscapeOctalState :: FirstValue ;
54+ EscapeOctalState :: Backslash => {
55+ self . state = EscapeOctalState :: Value ;
5656 Some ( '\\' )
5757 }
58- EscapeOctalState :: LastBackslash => {
59- self . state = EscapeOctalState :: LastValue ;
60- Some ( '\\' )
61- }
62- EscapeOctalState :: FirstValue => {
63- let octal_digit = byte_to_octal_digit ( self . c [ 0 ] , self . idx ) ;
64- if self . idx == 0 {
65- self . state = EscapeOctalState :: LastBackslash ;
66- self . idx = 2 ;
67- } else {
68- self . idx -= 1 ;
69- }
70- Some ( from_digit ( octal_digit. into ( ) , 8 ) . unwrap ( ) )
71- }
72- EscapeOctalState :: LastValue => {
73- let octal_digit = byte_to_octal_digit ( self . c [ 1 ] , self . idx ) ;
74- if self . idx == 0 {
75- self . state = EscapeOctalState :: Done ;
58+ EscapeOctalState :: Value => {
59+ let octal_digit = byte_to_octal_digit ( self . bytes [ self . byte_idx ] , self . digit_idx ) ;
60+ if self . digit_idx == 0 {
61+ // Move to next byte
62+ self . byte_idx += 1 ;
63+ if self . byte_idx >= self . num_bytes {
64+ self . state = EscapeOctalState :: Done ;
65+ } else {
66+ self . state = EscapeOctalState :: Backslash ;
67+ self . digit_idx = 2 ;
68+ }
7669 } else {
77- self . idx -= 1 ;
70+ self . digit_idx -= 1 ;
7871 }
7972 Some ( from_digit ( octal_digit. into ( ) , 8 ) . unwrap ( ) )
8073 }
@@ -88,20 +81,24 @@ impl EscapeOctal {
8881 return Self :: from_byte ( c as u8 ) ;
8982 }
9083
91- let mut buf = [ 0 ; 2 ] ;
92- let _s = c. encode_utf8 ( & mut buf ) ;
84+ let mut bytes = [ 0 ; 4 ] ;
85+ let len = c. encode_utf8 ( & mut bytes ) . len ( ) ;
9386 Self {
94- c : buf,
95- idx : 2 ,
96- state : EscapeOctalState :: FirstBackslash ,
87+ bytes,
88+ num_bytes : len,
89+ byte_idx : 0 ,
90+ digit_idx : 2 ,
91+ state : EscapeOctalState :: Backslash ,
9792 }
9893 }
9994
10095 fn from_byte ( b : u8 ) -> Self {
10196 Self {
102- c : [ 0 , b] ,
103- idx : 2 ,
104- state : EscapeOctalState :: LastBackslash ,
97+ bytes : [ b, 0 , 0 , 0 ] ,
98+ num_bytes : 1 ,
99+ byte_idx : 0 ,
100+ digit_idx : 2 ,
101+ state : EscapeOctalState :: Backslash ,
105102 }
106103 }
107104}
0 commit comments