]> git.lizzy.rs Git - rust.git/commitdiff
Add c_str::CString.as_bytes_no_nul()
authorKevin Ballard <kevin@sb.org>
Fri, 14 Feb 2014 23:42:35 +0000 (15:42 -0800)
committerKevin Ballard <kevin@sb.org>
Sat, 15 Feb 2014 05:23:37 +0000 (21:23 -0800)
src/libstd/c_str.rs
src/libstd/path/mod.rs

index fe332a60efa4468ec3f37ef8e1df608323114be9..adbd4be316c8b78419834f1b38a4e2b2b86fa1be 100644 (file)
@@ -79,6 +79,7 @@
 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 @@ pub fn owns_buffer(&self) -> bool {
     }
 
     /// Converts the CString into a `&[u8]` without copying.
+    /// Includes the terminating NUL byte.
     ///
     /// # Failure
     ///
@@ -177,7 +179,21 @@ pub fn owns_buffer(&self) -> bool {
     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 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     /// 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 @@ fn test_str_multistring_parsing() {
             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 @@ fn test_as_bytes() {
         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 @@ fn test_as_bytes_fail() {
         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();
index ed0ce20175086028e921520fc944b5b47ae0208e..13496033fd0e539ddaec35b6cadba0dc5717aec4 100644 (file)
@@ -578,8 +578,7 @@ fn container_into_owned_bytes(self) -> ~[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()
     }
 }