提交 51470f3b 编写于 作者: K Kevin Ballard

c_str: Add new method .as_str() -> Option<&str>

Also rustify .as_bytes(), so it no longer calls libc::strlen() and is
inlineable.
上级 72f62abe
......@@ -15,6 +15,7 @@
use option::{Option, Some, None};
use ptr::RawPtr;
use ptr;
use str;
use str::StrSlice;
use vec::{ImmutableVector, CopyableVector};
use container::Container;
......@@ -97,15 +98,25 @@ pub fn owns_buffer(&self) -> bool {
/// # Failure
///
/// Fails if the CString is null.
#[inline]
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
#[fixed_stack_segment]; #[inline(never)];
if self.buf.is_null() { fail!("CString is null!"); }
unsafe {
let len = libc::strlen(self.buf) as uint;
let len = ptr::position(self.buf, |c| *c == 0);
cast::transmute((self.buf, len + 1))
}
}
/// Converts the CString into a `&str` without copying.
/// Returns None if the CString is not UTF-8 or is null.
#[inline]
pub fn as_str<'a>(&'a self) -> Option<&'a str> {
if self.buf.is_null() { return None; }
let buf = self.as_bytes();
let buf = buf.slice_to(buf.len()-1); // chop off the trailing NUL
str::from_utf8_slice_opt(buf)
}
/// Return a CString iterator.
pub fn iter<'a>(&'a self) -> CStringIterator<'a> {
CStringIterator {
......@@ -238,7 +249,7 @@ mod tests {
use option::{Some, None};
#[test]
fn test_to_c_str() {
fn test_str_to_c_str() {
do "".to_c_str().with_ref |buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 0);
......@@ -257,6 +268,37 @@ fn test_to_c_str() {
}
}
#[test]
fn test_vec_to_c_str() {
let b: &[u8] = [];
do b.to_c_str().with_ref |buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 0);
}
}
do bytes!("hello").to_c_str().with_ref |buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 5), 0);
}
}
do bytes!("foo", 0xff).to_c_str().with_ref |buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'f' as libc::c_char);
assert_eq!(*ptr::offset(buf, 1), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 2), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 3), 0xff);
assert_eq!(*ptr::offset(buf, 4), 0);
}
}
}
#[test]
fn test_is_null() {
let c_str = unsafe { CString::new(ptr::null(), false) };
......@@ -349,4 +391,33 @@ fn test_to_c_str_unchecked() {
}
}
}
#[test]
fn test_as_bytes() {
let c_str = "hello".to_c_str();
assert_eq!(c_str.as_bytes(), bytes!("hello", 0));
let c_str = "".to_c_str();
assert_eq!(c_str.as_bytes(), bytes!(0));
let c_str = bytes!("foo", 0xff).to_c_str();
assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
}
#[test]
#[should_fail]
fn test_as_bytes_fail() {
let c_str = unsafe { CString::new(ptr::null(), false) };
c_str.as_bytes();
}
#[test]
fn test_as_str() {
let c_str = "hello".to_c_str();
assert_eq!(c_str.as_str(), Some("hello"));
let c_str = "".to_c_str();
assert_eq!(c_str.as_str(), Some(""));
let c_str = bytes!("foo", 0xff).to_c_str();
assert_eq!(c_str.as_str(), None);
let c_str = unsafe { CString::new(ptr::null(), false) };
assert_eq!(c_str.as_str(), None);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册