Rollup merge of #67705 - lzutao:wmemchr, r=wesleywiser
Use unrolled loop for searching NULL in [u16] on Windows
This commit is contained in:
commit
e89cb0733a
1 changed files with 46 additions and 2 deletions
|
@ -81,10 +81,54 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option<usize> {
|
||||
let ptr = haystack.as_ptr();
|
||||
let mut len = haystack.len();
|
||||
let mut start = &haystack[..];
|
||||
|
||||
// For performance reasons unfold the loop eight times.
|
||||
while len >= 8 {
|
||||
if start[0] == needle {
|
||||
return Some((start.as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[1] == needle {
|
||||
return Some((start[1..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[2] == needle {
|
||||
return Some((start[2..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[3] == needle {
|
||||
return Some((start[3..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[4] == needle {
|
||||
return Some((start[4..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[5] == needle {
|
||||
return Some((start[5..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[6] == needle {
|
||||
return Some((start[6..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
if start[7] == needle {
|
||||
return Some((start[7..].as_ptr() as usize - ptr as usize) / 2);
|
||||
}
|
||||
|
||||
start = &start[8..];
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
for (i, c) in start.iter().enumerate() {
|
||||
if *c == needle {
|
||||
return Some((start.as_ptr() as usize - ptr as usize) / 2 + i);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
|
||||
fn inner(s: &OsStr) -> crate::io::Result<Vec<u16>> {
|
||||
let mut maybe_result: Vec<u16> = s.encode_wide().collect();
|
||||
if maybe_result.iter().any(|&u| u == 0) {
|
||||
if unrolled_find_u16s(0, &maybe_result).is_some() {
|
||||
return Err(crate::io::Error::new(
|
||||
ErrorKind::InvalidInput,
|
||||
"strings passed to WinAPI cannot contain NULs",
|
||||
|
@ -214,7 +258,7 @@ fn wide_char_to_multi_byte(
|
|||
}
|
||||
|
||||
pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
|
||||
match v.iter().position(|c| *c == 0) {
|
||||
match unrolled_find_u16s(0, v) {
|
||||
// don't include the 0
|
||||
Some(i) => &v[..i],
|
||||
None => v,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue