@@ -328,6 +328,27 @@ impl FromVecWithNulError {
328328 }
329329}
330330
331+ /// An error indicating that no nul byte was present.
332+ ///
333+ /// A slice used to create a [`CStr`] must contain a nul byte somewhere
334+ /// within the slice.
335+ ///
336+ /// This error is created by the [`CStr::from_bytes_until_nul`] method.
337+ ///
338+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
339+ #[ unstable( feature = "cstr_from_bytes_until_nul" , issue = "95027" ) ]
340+ pub struct FromBytesUntilNulError ( ( ) ) ;
341+
342+ #[ unstable( feature = "cstr_from_bytes_until_nul" , issue = "95027" ) ]
343+ impl Error for FromBytesUntilNulError { }
344+
345+ #[ unstable( feature = "cstr_from_bytes_until_nul" , issue = "95027" ) ]
346+ impl fmt:: Display for FromBytesUntilNulError {
347+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
348+ write ! ( f, "data provided does not contain a nul" )
349+ }
350+ }
351+
331352/// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
332353///
333354/// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
@@ -1239,12 +1260,60 @@ impl CStr {
12391260 }
12401261 }
12411262
1263+ /// Creates a C string wrapper from a byte slice.
1264+ ///
1265+ /// This method will create a `CStr` from any byte slice that contains at
1266+ /// least one nul byte. The caller does not need to know or specify where
1267+ /// the nul byte is located.
1268+ ///
1269+ /// If the first byte is a nul character, this method will return an
1270+ /// empty `CStr`. If multiple nul characters are present, the `CStr` will
1271+ /// end at the first one.
1272+ ///
1273+ /// If the slice only has a single nul byte at the end, this method is
1274+ /// equivalent to [`CStr::from_bytes_with_nul`].
1275+ ///
1276+ /// # Examples
1277+ /// ```
1278+ /// #![feature(cstr_from_bytes_until_nul)]
1279+ ///
1280+ /// use std::ffi::CStr;
1281+ ///
1282+ /// let mut buffer = [0u8; 16];
1283+ /// unsafe {
1284+ /// // Here we might call an unsafe C function that writes a string
1285+ /// // into the buffer.
1286+ /// let buf_ptr = buffer.as_mut_ptr();
1287+ /// buf_ptr.write_bytes(b'A', 8);
1288+ /// }
1289+ /// // Attempt to extract a C nul-terminated string from the buffer.
1290+ /// let c_str = CStr::from_bytes_until_nul(&buffer[..]).unwrap();
1291+ /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA");
1292+ /// ```
1293+ ///
1294+ #[ unstable( feature = "cstr_from_bytes_until_nul" , issue = "95027" ) ]
1295+ pub fn from_bytes_until_nul ( bytes : & [ u8 ] ) -> Result < & CStr , FromBytesUntilNulError > {
1296+ let nul_pos = memchr:: memchr ( 0 , bytes) ;
1297+ match nul_pos {
1298+ Some ( nul_pos) => {
1299+ // SAFETY: We know there is a nul byte at nul_pos, so this slice
1300+ // (ending at the nul byte) is a well-formed C string.
1301+ let subslice = & bytes[ ..nul_pos + 1 ] ;
1302+ Ok ( unsafe { CStr :: from_bytes_with_nul_unchecked ( subslice) } )
1303+ }
1304+ None => Err ( FromBytesUntilNulError ( ( ) ) ) ,
1305+ }
1306+ }
1307+
12421308 /// Creates a C string wrapper from a byte slice.
12431309 ///
12441310 /// This function will cast the provided `bytes` to a `CStr`
12451311 /// wrapper after ensuring that the byte slice is nul-terminated
12461312 /// and does not contain any interior nul bytes.
12471313 ///
1314+ /// If the nul byte may not be at the end,
1315+ /// [`CStr::from_bytes_until_nul`] can be used instead.
1316+ ///
12481317 /// # Examples
12491318 ///
12501319 /// ```
0 commit comments