@@ -328,6 +328,27 @@ impl FromVecWithNulError {
328
328
}
329
329
}
330
330
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
+
331
352
/// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
332
353
///
333
354
/// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
@@ -1239,12 +1260,60 @@ impl CStr {
1239
1260
}
1240
1261
}
1241
1262
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
+
1242
1308
/// Creates a C string wrapper from a byte slice.
1243
1309
///
1244
1310
/// This function will cast the provided `bytes` to a `CStr`
1245
1311
/// wrapper after ensuring that the byte slice is nul-terminated
1246
1312
/// and does not contain any interior nul bytes.
1247
1313
///
1314
+ /// If the nul byte may not be at the end,
1315
+ /// [`CStr::from_bytes_until_nul`] can be used instead.
1316
+ ///
1248
1317
/// # Examples
1249
1318
///
1250
1319
/// ```
0 commit comments