hermit/
io.rs

1use alloc::string::String;
2use alloc::vec::Vec;
3use core::fmt;
4
5use crate::errno::Errno;
6
7pub type Result<T> = core::result::Result<T, crate::errno::Errno>;
8
9/// The Read trait allows for reading bytes from a source.
10///
11/// The Read trait is derived from Rust's std library.
12pub trait Read {
13	fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
14
15	/// Read all bytes until EOF in this source, placing them into buf.
16	fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
17		let start_len = buf.len();
18
19		loop {
20			let mut probe = [0u8; 512];
21
22			match self.read(&mut probe) {
23				Ok(0) => return Ok(buf.len() - start_len),
24				Ok(n) => {
25					buf.extend_from_slice(&probe[..n]);
26				}
27				Err(e) => return Err(e),
28			}
29		}
30	}
31
32	/// Read all bytes until EOF in this source, appending them to `buf`.
33	///
34	/// If successful, this function returns the number of bytes which were read
35	/// and appended to `buf`.
36	fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
37		unsafe { self.read_to_end(buf.as_mut_vec()) }
38	}
39}
40
41/// The Write trait allows for reading bytes from a source.
42///
43/// The Write trait is derived from Rust's std library.
44pub trait Write {
45	fn write(&mut self, buf: &[u8]) -> Result<usize>;
46
47	/// Attempts to write an entire buffer into this writer.
48	fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
49		while !buf.is_empty() {
50			match self.write(buf) {
51				Ok(0) => {
52					return Err(Errno::Io);
53				}
54				Ok(n) => buf = &buf[n..],
55				Err(e) => return Err(e),
56			}
57		}
58
59		Ok(())
60	}
61
62	/// Writes a formatted string into this writer, returning any error encountered.
63	fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
64		// Create a shim which translates a Write to a fmt::Write and saves
65		// off I/O errors. instead of discarding them
66		struct Adapter<'a, T: ?Sized> {
67			inner: &'a mut T,
68			error: Result<()>,
69		}
70
71		impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
72			fn write_str(&mut self, s: &str) -> fmt::Result {
73				match self.inner.write_all(s.as_bytes()) {
74					Ok(()) => Ok(()),
75					Err(e) => {
76						self.error = Err(e);
77						Err(fmt::Error)
78					}
79				}
80			}
81		}
82
83		let mut output = Adapter {
84			inner: self,
85			error: Ok(()),
86		};
87		match fmt::write(&mut output, fmt) {
88			Ok(()) => Ok(()),
89			Err(..) => {
90				// check if the error came from the underlying `Write` or not
91				if output.error.is_err() {
92					output.error
93				} else {
94					Err(Errno::Inval)
95				}
96			}
97		}
98	}
99}