4 use core::assert_matches::assert_matches;
5 use core::ffi::FromBytesUntilNulError;
6 use core::hash::{Hash, Hasher};
9 use core::hash::SipHasher13 as DefaultHasher;
14 let ptr = data.as_ptr() as *const c_char;
16 assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
17 assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
23 let s = CString::new("1234").unwrap();
24 assert_eq!(s.as_bytes(), b"1234");
25 assert_eq!(s.as_bytes_with_nul(), b"1234\0");
29 fn build_with_zero1() {
30 assert!(CString::new(&b"\0"[..]).is_err());
33 fn build_with_zero2() {
34 assert!(CString::new(vec![0]).is_err());
39 let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
40 assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
46 let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
47 assert_eq!(s.to_bytes(), b"12");
48 assert_eq!(s.to_bytes_with_nul(), b"12\0");
55 let ptr = data.as_ptr() as *const c_char;
57 let owned = unsafe { CStr::from_ptr(ptr).to_owned() };
58 assert_eq!(owned.as_bytes_with_nul(), data);
63 let data = b"123\xE2\xFA\xA6\0";
64 let ptr = data.as_ptr() as *const c_char;
65 let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
68 let mut s = DefaultHasher::new();
70 let cstr_hash = s.finish();
72 let mut s = DefaultHasher::new();
73 CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
74 let cstring_hash = s.finish();
76 assert_eq!(cstr_hash, cstring_hash);
80 fn from_bytes_with_nul() {
82 let cstr = CStr::from_bytes_with_nul(data);
83 assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
84 let cstr = CStr::from_bytes_with_nul(data);
85 assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
88 let cstr = CStr::from_bytes_with_nul(data);
89 let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
90 assert_eq!(cstr, Ok(cstr_unchecked));
95 fn from_bytes_with_nul_unterminated() {
97 let cstr = CStr::from_bytes_with_nul(data);
98 assert!(cstr.is_err());
102 fn from_bytes_with_nul_interior() {
103 let data = b"1\023\0";
104 let cstr = CStr::from_bytes_with_nul(data);
105 assert!(cstr.is_err());
109 fn cstr_from_bytes_until_nul() {
110 // Test an empty slice. This should fail because it
111 // does not contain a nul byte.
113 assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
115 // Test a non-empty slice, that does not contain a nul byte.
117 assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
119 // Test an empty nul-terminated string
121 let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
122 assert_eq!(r.to_bytes(), b"");
124 // Test a slice with the nul byte in the middle
125 let b = b"hello\0world!";
126 let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
127 assert_eq!(r.to_bytes(), b"hello");
129 // Test a slice with the nul byte at the end
131 let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
132 assert_eq!(r.to_bytes(), b"hello");
134 // Test a slice with two nul bytes at the end
135 let b = b"hello\0\0";
136 let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
137 assert_eq!(r.to_bytes(), b"hello");
139 // Test a slice containing lots of nul bytes
141 let r = CStr::from_bytes_until_nul(&b[..]).unwrap();
142 assert_eq!(r.to_bytes(), b"");
147 let orig: &[u8] = b"Hello, world!\0";
148 let cstr = CStr::from_bytes_with_nul(orig).unwrap();
149 let boxed: Box<CStr> = Box::from(cstr);
150 let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
151 assert_eq!(cstr, &*boxed);
152 assert_eq!(&*boxed, &*cstring);
153 assert_eq!(&*cstring, cstr);
158 let boxed = <Box<CStr>>::default();
159 assert_eq!(boxed.to_bytes_with_nul(), &[0]);
163 fn test_c_str_clone_into() {
164 let mut c_string = CString::new("lorem").unwrap();
165 let c_ptr = c_string.as_ptr();
166 let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
167 c_str.clone_into(&mut c_string);
168 assert_eq!(c_str, c_string.as_c_str());
169 // The exact same size shouldn't have needed to move its allocation
170 assert_eq!(c_ptr, c_string.as_ptr());
175 let orig: &[u8] = b"Hello, world!\0";
176 let cstr = CStr::from_bytes_with_nul(orig).unwrap();
177 let rc: Rc<CStr> = Rc::from(cstr);
178 let arc: Arc<CStr> = Arc::from(cstr);
180 assert_eq!(&*rc, cstr);
181 assert_eq!(&*arc, cstr);
183 let rc2: Rc<CStr> = Rc::from(cstr.to_owned());
184 let arc2: Arc<CStr> = Arc::from(cstr.to_owned());
186 assert_eq!(&*rc2, cstr);
187 assert_eq!(&*arc2, cstr);
191 fn cstr_const_constructor() {
192 const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") };
194 assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
198 fn cstr_index_from() {
199 let original = b"Hello, world!\0";
200 let cstr = CStr::from_bytes_with_nul(original).unwrap();
201 let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
203 assert_eq!(&cstr[7..], result);
208 fn cstr_index_from_empty() {
209 let original = b"Hello, world!\0";
210 let cstr = CStr::from_bytes_with_nul(original).unwrap();
211 let _ = &cstr[original.len()..];
215 fn c_string_from_empty_string() {
217 let cstring = CString::new(original).unwrap();
218 assert_eq!(original.as_bytes(), cstring.as_bytes());
219 assert_eq!([b'\0'], cstring.as_bytes_with_nul());
223 fn c_str_from_empty_string() {
224 let original = b"\0";
225 let cstr = CStr::from_bytes_with_nul(original).unwrap();
226 assert_eq!([] as [u8; 0], cstr.to_bytes());
227 assert_eq!([b'\0'], cstr.to_bytes_with_nul());