Add c_str::CString.as_bytes_no_nul()

This commit is contained in:
Kevin Ballard 2014-02-14 15:42:35 -08:00
parent 994747022a
commit 8cc8eb7b8e
2 changed files with 38 additions and 6 deletions

View File

@ -79,6 +79,7 @@ use str;
use vec::{ImmutableVector, MutableVector};
use vec;
use rt::global_heap::malloc_raw;
use unstable::raw::Slice;
/// The representation of a C String.
///
@ -169,6 +170,7 @@ impl CString {
}
/// Converts the CString into a `&[u8]` without copying.
/// Includes the terminating NUL byte.
///
/// # Failure
///
@ -177,7 +179,21 @@ impl CString {
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
if self.buf.is_null() { fail!("CString is null!"); }
unsafe {
cast::transmute((self.buf, self.len() + 1))
cast::transmute(Slice { data: self.buf, len: self.len() + 1 })
}
}
/// Converts the CString into a `&[u8]` without copying.
/// Does not include the terminating NUL byte.
///
/// # Failure
///
/// Fails if the CString is null.
#[inline]
pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
if self.buf.is_null() { fail!("CString is null!"); }
unsafe {
cast::transmute(Slice { data: self.buf, len: self.len() })
}
}
@ -189,8 +205,7 @@ impl CString {
/// Fails if the CString is null.
#[inline]
pub fn as_str<'a>(&'a self) -> Option<&'a str> {
let buf = self.as_bytes();
let buf = buf.slice_to(buf.len()-1); // chop off the trailing NUL
let buf = self.as_bytes_no_nul();
str::from_utf8(buf)
}
@ -417,7 +432,7 @@ mod tests {
let expected = ["zero", "one"];
let mut it = expected.iter();
let result = from_c_multistring(ptr as *libc::c_char, None, |c| {
let cbytes = c.as_bytes().slice_to(c.len());
let cbytes = c.as_bytes_no_nul();
assert_eq!(cbytes, it.next().unwrap().as_bytes());
});
assert_eq!(result, 2);
@ -552,6 +567,17 @@ mod tests {
assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
}
#[test]
fn test_as_bytes_no_nul() {
let c_str = "hello".to_c_str();
assert_eq!(c_str.as_bytes_no_nul(), bytes!("hello"));
let c_str = "".to_c_str();
let exp: &[u8] = [];
assert_eq!(c_str.as_bytes_no_nul(), exp);
let c_str = bytes!("foo", 0xff).to_c_str();
assert_eq!(c_str.as_bytes_no_nul(), bytes!("foo", 0xff));
}
#[test]
#[should_fail]
fn test_as_bytes_fail() {
@ -559,6 +585,13 @@ mod tests {
c_str.as_bytes();
}
#[test]
#[should_fail]
fn test_as_bytes_no_nul_fail() {
let c_str = unsafe { CString::new(ptr::null(), false) };
c_str.as_bytes_no_nul();
}
#[test]
fn test_as_str() {
let c_str = "hello".to_c_str();

View File

@ -578,8 +578,7 @@ impl BytesContainer for ~[u8] {
impl BytesContainer for CString {
#[inline]
fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
let s = self.as_bytes();
s.slice_to(s.len()-1)
self.as_bytes_no_nul()
}
}