@@ -81,10 +81,54 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
8181 }
8282}
8383
84+ pub fn unrolled_find_u16s ( needle : u16 , haystack : & [ u16 ] ) -> Option < usize > {
85+ let ptr = haystack. as_ptr ( ) ;
86+ let mut len = haystack. len ( ) ;
87+ let mut start = & haystack[ ..] ;
88+
89+ // For performance reasons unfold the loop eight times.
90+ while len >= 8 {
91+ if start[ 0 ] == needle {
92+ return Some ( ( start. as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
93+ }
94+ if start[ 1 ] == needle {
95+ return Some ( ( start[ 1 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
96+ }
97+ if start[ 2 ] == needle {
98+ return Some ( ( start[ 2 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
99+ }
100+ if start[ 3 ] == needle {
101+ return Some ( ( start[ 3 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
102+ }
103+ if start[ 4 ] == needle {
104+ return Some ( ( start[ 4 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
105+ }
106+ if start[ 5 ] == needle {
107+ return Some ( ( start[ 5 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
108+ }
109+ if start[ 6 ] == needle {
110+ return Some ( ( start[ 6 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
111+ }
112+ if start[ 7 ] == needle {
113+ return Some ( ( start[ 7 ..] . as_ptr ( ) as usize - ptr as usize ) / 2 ) ;
114+ }
115+
116+ start = & start[ 8 ..] ;
117+ len -= 8 ;
118+ }
119+
120+ for ( i, c) in start. iter ( ) . enumerate ( ) {
121+ if * c == needle {
122+ return Some ( ( start. as_ptr ( ) as usize - ptr as usize ) / 2 + i) ;
123+ }
124+ }
125+ None
126+ }
127+
84128pub fn to_u16s < S : AsRef < OsStr > > ( s : S ) -> crate :: io:: Result < Vec < u16 > > {
85129 fn inner ( s : & OsStr ) -> crate :: io:: Result < Vec < u16 > > {
86130 let mut maybe_result: Vec < u16 > = s. encode_wide ( ) . collect ( ) ;
87- if maybe_result . iter ( ) . any ( | & u| u == 0 ) {
131+ if unrolled_find_u16s ( 0 , & maybe_result ) . is_some ( ) {
88132 return Err ( crate :: io:: Error :: new (
89133 ErrorKind :: InvalidInput ,
90134 "strings passed to WinAPI cannot contain NULs" ,
@@ -214,7 +258,7 @@ fn wide_char_to_multi_byte(
214258}
215259
216260pub fn truncate_utf16_at_nul ( v : & [ u16 ] ) -> & [ u16 ] {
217- match v . iter ( ) . position ( |c| * c == 0 ) {
261+ match unrolled_find_u16s ( 0 , v ) {
218262 // don't include the 0
219263 Some ( i) => & v[ ..i] ,
220264 None => v,
0 commit comments