From 08b6cb46c6c5cc583ceccb2c29e65fc72c13f480 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 3 Aug 2013 14:13:34 -0700 Subject: [PATCH] std: add str.to_c_str() --- src/libstd/os.rs | 2 +- src/libstd/str.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index f78f5812863..294fa361324 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1948,7 +1948,7 @@ mod tests { }; assert!((ostream as uint != 0u)); let s = ~"hello"; - let mut buf = s.as_bytes_with_null().to_owned(); + let mut buf = s.to_owned().to_c_str(); let len = buf.len(); do buf.as_mut_buf |b, _len| { assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, diff --git a/src/libstd/str.rs b/src/libstd/str.rs index c30888529be..c936c1e25db 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -2024,6 +2024,13 @@ pub trait OwnedStr { fn capacity(&self) -> uint; fn to_bytes_with_null(self) -> ~[u8]; + /// Allocates a null terminate byte array. + /// + /// # Failure + /// + /// Fails if there are any null characters inside the byte array. + fn to_c_str(self) -> ~[u8]; + /// Work with the mutable byte buffer and length of a slice. /// /// The given length is one byte longer than the 'official' indexable @@ -2215,6 +2222,13 @@ impl OwnedStr for ~str { unsafe { cast::transmute(self) } } + #[inline] + fn to_c_str(self) -> ~[u8] { + let bytes = self.to_bytes_with_null(); + assert!(bytes.slice(0, bytes.len() - 1).iter().all(|byte| *byte != 0)); + bytes + } + #[inline] fn as_mut_buf(&mut self, f: &fn(*mut u8, uint) -> T) -> T { let v: &mut ~[u8] = unsafe { cast::transmute(self) }; @@ -3059,6 +3073,18 @@ mod tests { } #[test] + fn test_to_c_str() { + let s = ~"ศไทย中华Việt Nam"; + let v = ~[ + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, + 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, + 109, 0 + ]; + assert_eq!((~"").to_c_str(), ~[0]); + assert_eq!((~"abc").to_c_str(), ~['a' as u8, 'b' as u8, 'c' as u8, 0]); + assert_eq!(s.to_c_str(), v); + } + fn test_subslice_offset() { let a = "kernelsprite"; let b = a.slice(7, a.len());