Skip to content

Commit

Permalink
Implement CString::from_reader.
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian committed Mar 20, 2019
1 parent cd45b19 commit ede7f5f
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/libstd/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,41 @@ impl CString {
CString { inner: v.into_boxed_slice() }
}

/// Creates a C-compatible string by reading from an object that implements ```Read```.
/// It reads all characters including the null character.
///
/// Because bytes are checked on null characters during the reading process,
/// no extra checks are required to ensure that no null characters precede the
/// terminating null character.
///
/// # Examples
///
/// ```
/// use std::ffi::CString;
///
/// let test = "Example\0";
/// let string = CString::from_reader(test.as_bytes()).unwrap();
/// ```
///
#[stable(feature = "cstring_from_reader", since = "1.33.0")]
pub fn from_reader(mut reader: impl io::Read) -> Result<CString, io::Error>
{
let mut buffer = Vec::new();
let mut character: u8 = 0;

loop {
// Read a new character from reader and insert it into the buffer.
let slice = slice::from_mut(&mut character);
reader.read_exact(slice)?;
buffer.push(character);

// Construct a CString if a null character has been found.
if character == 0 {
return Ok(CString { inner: buffer.into_boxed_slice() });
}
}
}

/// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
///
/// Additionally, the length of the string will be recalculated from the pointer.
Expand Down Expand Up @@ -1320,6 +1355,20 @@ mod tests {
}
}

#[test]
fn read_to_cstring1() {
let test = "Example\0";
let string = CString::from_reader(test.as_bytes()).unwrap();
assert_eq!(string.as_bytes(), b"Example");
}

#[test]
fn read_to_cstring2() {
let test = "Example";
let result = CString::from_reader(test.as_bytes());
assert_eq!(result.is_err(), true);
}

#[test]
fn simple() {
let s = CString::new("1234").unwrap();
Expand Down

0 comments on commit ede7f5f

Please # to comment.