summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWedson Almeida Filho <wedsonaf@gmail.com>2022-11-10 17:41:32 +0100
committerMiguel Ojeda <ojeda@kernel.org>2022-12-04 01:59:15 +0100
commitfffed679eeea119c8f972954518c142ec95bda4a (patch)
tree5cbff8a0ad404cf53264298a928ae419b9076ea5
parentrust: str: add `c_str!` macro (diff)
downloadlinux-fffed679eeea119c8f972954518c142ec95bda4a.tar.xz
linux-fffed679eeea119c8f972954518c142ec95bda4a.zip
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>
-rw-r--r--rust/kernel/str.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
index a995db36486f..ce207d1b3d2a 100644
--- a/rust/kernel/str.rs
+++ b/rust/kernel/str.rs
@@ -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(())
+ }
+ }
+}