Skip to content

Commit ede7f5f

Browse files
author
Christian
committed
Implement CString::from_reader.
1 parent cd45b19 commit ede7f5f

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/libstd/ffi/c_str.rs

+49
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,41 @@ impl CString {
355355
CString { inner: v.into_boxed_slice() }
356356
}
357357

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+
358393
/// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
359394
///
360395
/// Additionally, the length of the string will be recalculated from the pointer.
@@ -1320,6 +1355,20 @@ mod tests {
13201355
}
13211356
}
13221357

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+
13231372
#[test]
13241373
fn simple() {
13251374
let s = CString::new("1234").unwrap();

0 commit comments

Comments
 (0)