rust: str: add `Formatter` type
Add the `Formatter` type, which leverages `RawFormatter`, but fails if callers attempt to write more than will fit in the buffer. In order to so, implement the `RawFormatter::from_buffer()` constructor as well. Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com> Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> [Reworded, adapted for upstream and applied latest changes] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
b18cb00e5a
commit
fffed679ee
|
@ -406,6 +406,23 @@ impl RawFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new instance of [`RawFormatter`] with the given buffer.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
|
||||
/// for the lifetime of the returned [`RawFormatter`].
|
||||
pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
|
||||
let pos = buf as usize;
|
||||
// INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements
|
||||
// guarantees that the memory region is valid for writes.
|
||||
Self {
|
||||
pos,
|
||||
beg: pos,
|
||||
end: pos.saturating_add(len),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current insert position.
|
||||
///
|
||||
/// N.B. It may point to invalid memory.
|
||||
|
@ -439,3 +456,43 @@ impl fmt::Write for RawFormatter {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
|
||||
///
|
||||
/// Fails if callers attempt to write more than will fit in the buffer.
|
||||
pub(crate) struct Formatter(RawFormatter);
|
||||
|
||||
impl Formatter {
|
||||
/// Creates a new instance of [`Formatter`] with the given buffer.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
|
||||
/// for the lifetime of the returned [`Formatter`].
|
||||
#[allow(dead_code)]
|
||||
pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
|
||||
// SAFETY: The safety requirements of this function satisfy those of the callee.
|
||||
Self(unsafe { RawFormatter::from_buffer(buf, len) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Formatter {
|
||||
type Target = RawFormatter;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for Formatter {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.0.write_str(s)?;
|
||||
|
||||
// Fail the request if we go past the end of the buffer.
|
||||
if self.0.pos > self.0.end {
|
||||
Err(fmt::Error)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue