@@ -66,9 +66,8 @@ pub fn is_ipv4(input: &str) -> bool {
6666 let last_char = b[ b. len ( ) - 1 ] ;
6767
6868 // Quick filter: the last character must be a decimal digit, a-f, or 'x'
69- let possible = last_char. is_ascii_digit ( )
70- || matches ! ( last_char, b'a' ..=b'f' )
71- || last_char == b'x' ;
69+ let possible =
70+ last_char. is_ascii_digit ( ) || matches ! ( last_char, b'a' ..=b'f' ) || last_char == b'x' ;
7271 if !possible {
7372 return false ;
7473 }
@@ -119,34 +118,54 @@ pub fn is_ipv4(input: &str) -> bool {
119118const PATH_SIG_TABLE : [ u8 ; 256 ] = {
120119 let mut t = [ 0u8 ; 256 ] ;
121120 // Needs encoding: C0 controls (0x00-0x1F), DEL (0x7F), high bytes (0x80-0xFF)
122- let mut i = 0usize ; while i <= 0x1F { t[ i] |= 0x01 ; i += 1 ; }
123- let mut i = 0x7Fusize ; while i < 256 { t[ i] |= 0x01 ; i += 1 ; }
121+ let mut i = 0usize ;
122+ while i <= 0x1F {
123+ t[ i] |= 0x01 ;
124+ i += 1 ;
125+ }
126+ let mut i = 0x7Fusize ;
127+ while i < 256 {
128+ t[ i] |= 0x01 ;
129+ i += 1 ;
130+ }
124131 // Needs encoding: specific printable ASCII chars
125132 let enc: & [ u8 ] = b" \" #<>?^`{|}" ;
126133
127- let mut i = 0 ; while i < enc. len ( ) { t[ enc[ i] as usize ] |= 0x01 ; i += 1 ; }
134+ let mut i = 0 ;
135+ while i < enc. len ( ) {
136+ t[ enc[ i] as usize ] |= 0x01 ;
137+ i += 1 ;
138+ }
128139 // Special flags
129140 t[ b'\\' as usize ] |= 0x02 ; // backslash
130- t[ b'.' as usize ] |= 0x04 ; // dot
131- t[ b'%' as usize ] |= 0x08 ; // percent
141+ t[ b'.' as usize ] |= 0x04 ; // dot
142+ t[ b'%' as usize ] |= 0x08 ; // percent
132143 t
133144} ;
134145
135- /// Compute a path-signature byte via an unrolled table lookup — branch-free.
136- /// Returns a bitmask of the flags above.
146+ /// Compute a path-signature byte via Ada's exact 8-at-a-time unrolled lookup.
147+ ///
148+ /// Ada C++ uses `for (; i + 7 < size; i += 8)` — we match that exactly.
137149pub fn path_signature ( input : & str ) -> u8 {
138150 let b = input. as_bytes ( ) ;
139151 let mut acc = 0u8 ;
140152 let mut i = 0 ;
141- // Unrolled 4-at-a-time — same as Ada C++ style
142- while i + 4 <= b. len ( ) {
143- acc |= PATH_SIG_TABLE [ b[ i] as usize ]
144- | PATH_SIG_TABLE [ b[ i+1 ] as usize ]
145- | PATH_SIG_TABLE [ b[ i+2 ] as usize ]
146- | PATH_SIG_TABLE [ b[ i+3 ] as usize ] ;
147- i += 4 ;
148- }
149- while i < b. len ( ) { acc |= PATH_SIG_TABLE [ b[ i] as usize ] ; i += 1 ; }
153+ // 8-at-a-time — Ada C++ uses this exact unroll factor
154+ while i + 8 <= b. len ( ) {
155+ acc |= PATH_SIG_TABLE [ b[ i] as usize ]
156+ | PATH_SIG_TABLE [ b[ i + 1 ] as usize ]
157+ | PATH_SIG_TABLE [ b[ i + 2 ] as usize ]
158+ | PATH_SIG_TABLE [ b[ i + 3 ] as usize ]
159+ | PATH_SIG_TABLE [ b[ i + 4 ] as usize ]
160+ | PATH_SIG_TABLE [ b[ i + 5 ] as usize ]
161+ | PATH_SIG_TABLE [ b[ i + 6 ] as usize ]
162+ | PATH_SIG_TABLE [ b[ i + 7 ] as usize ] ;
163+ i += 8 ;
164+ }
165+ while i < b. len ( ) {
166+ acc |= PATH_SIG_TABLE [ b[ i] as usize ] ;
167+ i += 1 ;
168+ }
150169 acc
151170}
152171
0 commit comments