Skip to content

Commit 8cc8eb7

Browse files
committed
Add c_str::CString.as_bytes_no_nul()
1 parent 9947470 commit 8cc8eb7

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

src/libstd/c_str.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use str;
7979
use vec::{ImmutableVector, MutableVector};
8080
use vec;
8181
use rt::global_heap::malloc_raw;
82+
use unstable::raw::Slice;
8283

8384
/// The representation of a C String.
8485
///
@@ -169,6 +170,7 @@ impl CString {
169170
}
170171

171172
/// Converts the CString into a `&[u8]` without copying.
173+
/// Includes the terminating NUL byte.
172174
///
173175
/// # Failure
174176
///
@@ -177,7 +179,21 @@ impl CString {
177179
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
178180
if self.buf.is_null() { fail!("CString is null!"); }
179181
unsafe {
180-
cast::transmute((self.buf, self.len() + 1))
182+
cast::transmute(Slice { data: self.buf, len: self.len() + 1 })
183+
}
184+
}
185+
186+
/// Converts the CString into a `&[u8]` without copying.
187+
/// Does not include the terminating NUL byte.
188+
///
189+
/// # Failure
190+
///
191+
/// Fails if the CString is null.
192+
#[inline]
193+
pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
194+
if self.buf.is_null() { fail!("CString is null!"); }
195+
unsafe {
196+
cast::transmute(Slice { data: self.buf, len: self.len() })
181197
}
182198
}
183199

@@ -189,8 +205,7 @@ impl CString {
189205
/// Fails if the CString is null.
190206
#[inline]
191207
pub fn as_str<'a>(&'a self) -> Option<&'a str> {
192-
let buf = self.as_bytes();
193-
let buf = buf.slice_to(buf.len()-1); // chop off the trailing NUL
208+
let buf = self.as_bytes_no_nul();
194209
str::from_utf8(buf)
195210
}
196211

@@ -417,7 +432,7 @@ mod tests {
417432
let expected = ["zero", "one"];
418433
let mut it = expected.iter();
419434
let result = from_c_multistring(ptr as *libc::c_char, None, |c| {
420-
let cbytes = c.as_bytes().slice_to(c.len());
435+
let cbytes = c.as_bytes_no_nul();
421436
assert_eq!(cbytes, it.next().unwrap().as_bytes());
422437
});
423438
assert_eq!(result, 2);
@@ -552,13 +567,31 @@ mod tests {
552567
assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
553568
}
554569

570+
#[test]
571+
fn test_as_bytes_no_nul() {
572+
let c_str = "hello".to_c_str();
573+
assert_eq!(c_str.as_bytes_no_nul(), bytes!("hello"));
574+
let c_str = "".to_c_str();
575+
let exp: &[u8] = [];
576+
assert_eq!(c_str.as_bytes_no_nul(), exp);
577+
let c_str = bytes!("foo", 0xff).to_c_str();
578+
assert_eq!(c_str.as_bytes_no_nul(), bytes!("foo", 0xff));
579+
}
580+
555581
#[test]
556582
#[should_fail]
557583
fn test_as_bytes_fail() {
558584
let c_str = unsafe { CString::new(ptr::null(), false) };
559585
c_str.as_bytes();
560586
}
561587

588+
#[test]
589+
#[should_fail]
590+
fn test_as_bytes_no_nul_fail() {
591+
let c_str = unsafe { CString::new(ptr::null(), false) };
592+
c_str.as_bytes_no_nul();
593+
}
594+
562595
#[test]
563596
fn test_as_str() {
564597
let c_str = "hello".to_c_str();

src/libstd/path/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,7 @@ impl BytesContainer for ~[u8] {
578578
impl BytesContainer for CString {
579579
#[inline]
580580
fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
581-
let s = self.as_bytes();
582-
s.slice_to(s.len()-1)
581+
self.as_bytes_no_nul()
583582
}
584583
}
585584

0 commit comments

Comments
 (0)