Skip to content

Commit fffed67

Browse files
wedsonafojeda
authored andcommitted
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>
1 parent b18cb00 commit fffed67

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

rust/kernel/str.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,23 @@ impl RawFormatter {
406406
}
407407
}
408408

409+
/// Creates a new instance of [`RawFormatter`] with the given buffer.
410+
///
411+
/// # Safety
412+
///
413+
/// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
414+
/// for the lifetime of the returned [`RawFormatter`].
415+
pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
416+
let pos = buf as usize;
417+
// INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements
418+
// guarantees that the memory region is valid for writes.
419+
Self {
420+
pos,
421+
beg: pos,
422+
end: pos.saturating_add(len),
423+
}
424+
}
425+
409426
/// Returns the current insert position.
410427
///
411428
/// N.B. It may point to invalid memory.
@@ -439,3 +456,43 @@ impl fmt::Write for RawFormatter {
439456
Ok(())
440457
}
441458
}
459+
460+
/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
461+
///
462+
/// Fails if callers attempt to write more than will fit in the buffer.
463+
pub(crate) struct Formatter(RawFormatter);
464+
465+
impl Formatter {
466+
/// Creates a new instance of [`Formatter`] with the given buffer.
467+
///
468+
/// # Safety
469+
///
470+
/// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
471+
/// for the lifetime of the returned [`Formatter`].
472+
#[allow(dead_code)]
473+
pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
474+
// SAFETY: The safety requirements of this function satisfy those of the callee.
475+
Self(unsafe { RawFormatter::from_buffer(buf, len) })
476+
}
477+
}
478+
479+
impl Deref for Formatter {
480+
type Target = RawFormatter;
481+
482+
fn deref(&self) -> &Self::Target {
483+
&self.0
484+
}
485+
}
486+
487+
impl fmt::Write for Formatter {
488+
fn write_str(&mut self, s: &str) -> fmt::Result {
489+
self.0.write_str(s)?;
490+
491+
// Fail the request if we go past the end of the buffer.
492+
if self.0.pos > self.0.end {
493+
Err(fmt::Error)
494+
} else {
495+
Ok(())
496+
}
497+
}
498+
}

0 commit comments

Comments
 (0)