about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2014-02-14 15:42:35 -0800
committerKevin Ballard <kevin@sb.org>2014-02-14 21:23:37 -0800
commit8cc8eb7b8e57a09652f18c466c37946e24ae8021 (patch)
tree8104e0baed41d769f4de52ade25ac6ef302b8583
parent994747022a45b5c2b03f38dddbe8b43bf09679f3 (diff)
downloadrust-8cc8eb7b8e57a09652f18c466c37946e24ae8021.tar.gz
rust-8cc8eb7b8e57a09652f18c466c37946e24ae8021.zip
Add c_str::CString.as_bytes_no_nul()
-rw-r--r--src/libstd/c_str.rs41
-rw-r--r--src/libstd/path/mod.rs3
2 files changed, 38 insertions, 6 deletions
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index fe332a60efa..adbd4be316c 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -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);
@@ -553,6 +568,17 @@ mod tests {
     }
 
     #[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() {
         let c_str = unsafe { CString::new(ptr::null(), false) };
@@ -560,6 +586,13 @@ mod tests {
     }
 
     #[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();
         assert_eq!(c_str.as_str(), Some("hello"));
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index ed0ce201750..13496033fd0 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -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()
     }
 }