@@ -355,6 +355,41 @@ impl CString {
355
355
CString { inner : v. into_boxed_slice ( ) }
356
356
}
357
357
358
+ /// Creates a C-compatible string by reading from an object that implements ```Read```.
359
+ /// It reads all characters including the null character.
360
+ ///
361
+ /// Because bytes are checked on null characters during the reading process,
362
+ /// no extra checks are required to ensure that no null characters precede the
363
+ /// terminating null character.
364
+ ///
365
+ /// # Examples
366
+ ///
367
+ /// ```
368
+ /// use std::ffi::CString;
369
+ ///
370
+ /// let test = "Example\0";
371
+ /// let string = CString::from_reader(test.as_bytes()).unwrap();
372
+ /// ```
373
+ ///
374
+ #[ stable( feature = "cstring_from_reader" , since = "1.33.0" ) ]
375
+ pub fn from_reader ( mut reader : impl io:: Read ) -> Result < CString , io:: Error >
376
+ {
377
+ let mut buffer = Vec :: new ( ) ;
378
+ let mut character: u8 = 0 ;
379
+
380
+ loop {
381
+ // Read a new character from reader and insert it into the buffer.
382
+ let slice = slice:: from_mut ( & mut character) ;
383
+ reader. read_exact ( slice) ?;
384
+ buffer. push ( character) ;
385
+
386
+ // Construct a CString if a null character has been found.
387
+ if character == 0 {
388
+ return Ok ( CString { inner : buffer. into_boxed_slice ( ) } ) ;
389
+ }
390
+ }
391
+ }
392
+
358
393
/// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
359
394
///
360
395
/// Additionally, the length of the string will be recalculated from the pointer.
@@ -1320,6 +1355,20 @@ mod tests {
1320
1355
}
1321
1356
}
1322
1357
1358
+ #[ test]
1359
+ fn read_to_cstring1 ( ) {
1360
+ let test = "Example\0 " ;
1361
+ let string = CString :: from_reader ( test. as_bytes ( ) ) . unwrap ( ) ;
1362
+ assert_eq ! ( string. as_bytes( ) , b"Example" ) ;
1363
+ }
1364
+
1365
+ #[ test]
1366
+ fn read_to_cstring2 ( ) {
1367
+ let test = "Example" ;
1368
+ let result = CString :: from_reader ( test. as_bytes ( ) ) ;
1369
+ assert_eq ! ( result. is_err( ) , true ) ;
1370
+ }
1371
+
1323
1372
#[ test]
1324
1373
fn simple ( ) {
1325
1374
let s = CString :: new ( "1234" ) . unwrap ( ) ;
0 commit comments