提交 c9b4538b 编写于 作者: H Huon Wilson

str: add a function for truncating a vector of u16 at NUL.

Many of the functions interacting with Windows APIs allocate a vector of
0's and do not retrieve a length directly from the API call, and so need
to be sure to remove the unmodified junk at the end of the vector.
上级 4f841ee1
......@@ -571,7 +571,8 @@ unsafe fn get_list(p: &CString) -> IoResult<~[Path]> {
else {
let fp_vec = vec::from_buf(
fp_buf, wcslen(fp_buf) as uint);
let fp_str = str::from_utf16(fp_vec)
let fp_trimmed = str::truncate_utf16_at_nul(fp_vec);
let fp_str = str::from_utf16(fp_trimmed)
.expect("rust_list_dir_wfd_fp_buf returned invalid UTF-16");
paths.push(Path::new(fp_str));
}
......
......@@ -88,7 +88,8 @@ pub fn getcwd() -> Path {
fail!();
}
}
Path::new(str::from_utf16(buf).expect("GetCurrentDirectoryW returned invalid UTF-16"))
Path::new(str::from_utf16(str::truncate_utf16_at_nul(buf))
.expect("GetCurrentDirectoryW returned invalid UTF-16"))
}
#[cfg(windows)]
......@@ -744,7 +745,8 @@ fn FormatMessageW(flags: DWORD,
fail!("[{}] FormatMessage failure", errno());
}
str::from_utf16(buf).expect("FormatMessageW returned invalid UTF-16")
str::from_utf16(str::truncate_utf16_at_nul(buf))
.expect("FormatMessageW returned invalid UTF-16")
}
}
......@@ -833,7 +835,9 @@ fn real_args() -> ~[~str] {
while *ptr.offset(len as int) != 0 { len += 1; }
// Push it onto the list.
let opt_s = vec::raw::buf_as_slice(ptr, len, str::from_utf16);
let opt_s = vec::raw::buf_as_slice(ptr, len, |buf| {
str::from_utf16(str::truncate_utf16_at_nul(buf))
});
args.push(opt_s.expect("CommandLineToArgvW returned invalid UTF-16"));
}
}
......
......@@ -920,6 +920,32 @@ pub fn utf16_items<'a>(v: &'a [u16]) -> UTF16Items<'a> {
UTF16Items { iter : v.iter() }
}
/// Return a slice of `v` ending at (and not including) the first NUL
/// (0).
///
/// # Example
///
/// ```rust
/// use std::str;
///
/// // "abcd"
/// let mut v = ['a' as u16, 'b' as u16, 'c' as u16, 'd' as u16];
/// // no NULs so no change
/// assert_eq!(str::truncate_utf16_at_nul(v), v.as_slice());
///
/// // "ab\0d"
/// v[2] = 0;
/// assert_eq!(str::truncate_utf16_at_nul(v),
/// &['a' as u16, 'b' as u16]);
/// ```
pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
match v.iter().position(|c| *c == 0) {
// don't include the 0
Some(i) => v.slice_to(i),
None => v
}
}
/// Decode a UTF-16 encoded vector `v` into a string, returning `None`
/// if `v` contains any invalid data.
///
......@@ -3875,6 +3901,24 @@ fn test_utf16_lossy() {
assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]), ~"\uFFFD𐒋\uFFFD");
}
#[test]
fn test_truncate_utf16_at_nul() {
let v = [];
assert_eq!(truncate_utf16_at_nul(v), &[]);
let v = [0, 2, 3];
assert_eq!(truncate_utf16_at_nul(v), &[]);
let v = [1, 0, 3];
assert_eq!(truncate_utf16_at_nul(v), &[1]);
let v = [1, 2, 0];
assert_eq!(truncate_utf16_at_nul(v), &[1, 2]);
let v = [1, 2, 3];
assert_eq!(truncate_utf16_at_nul(v), &[1, 2, 3]);
}
#[test]
fn test_char_at() {
let s = ~"ศไทย中华Việt Nam";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册