[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221110164152.26136-21-ojeda@kernel.org>
Date: Thu, 10 Nov 2022 17:41:32 +0100
From: Miguel Ojeda <ojeda@...nel.org>
To: Miguel Ojeda <ojeda@...nel.org>,
Wedson Almeida Filho <wedsonaf@...il.com>,
Alex Gaynor <alex.gaynor@...il.com>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>
Cc: rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org,
patches@...ts.linux.dev, Adam Bratschi-Kaye <ark.email@...il.com>
Subject: [PATCH v1 20/28] rust: str: add `Formatter` type
From: Wedson Almeida Filho <wedsonaf@...il.com>
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@...il.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@...il.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@...il.com>
[Reworded, adapted for upstream and applied latest changes]
Signed-off-by: Miguel Ojeda <ojeda@...nel.org>
---
rust/kernel/str.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
index 3fb73b888dce..db6473db31c6 100644
--- a/rust/kernel/str.rs
+++ b/rust/kernel/str.rs
@@ -415,6 +415,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.
@@ -448,3 +465,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(())
+ }
+ }
+}
--
2.38.1
Powered by blists - more mailing lists