Skip to content

Commit

Permalink
rust: str: add Formatter type
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Adam Bratschi-Kaye <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Reviewed-by: Gary Guo <[email protected]>
[Reworded, adapted for upstream and applied latest changes]
Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
wedsonaf authored and ojeda committed Dec 4, 2022
1 parent b18cb00 commit fffed67
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions rust/kernel/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(())
}
}
}

0 comments on commit fffed67

Please sign in to comment.