raw_writer.rs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // SPDX-License-Identifier: GPL-2.0
  2. use core::fmt::{self, Write};
  3. use crate::error::Result;
  4. use crate::prelude::EINVAL;
  5. /// A mutable reference to a byte buffer where a string can be written into.
  6. ///
  7. /// # Invariants
  8. ///
  9. /// `buffer` is always null terminated.
  10. pub(crate) struct RawWriter<'a> {
  11. buffer: &'a mut [u8],
  12. pos: usize,
  13. }
  14. impl<'a> RawWriter<'a> {
  15. /// Create a new `RawWriter` instance.
  16. fn new(buffer: &'a mut [u8]) -> Result<RawWriter<'a>> {
  17. *(buffer.last_mut().ok_or(EINVAL)?) = 0;
  18. // INVARIANT: We null terminated the buffer above.
  19. Ok(Self { buffer, pos: 0 })
  20. }
  21. pub(crate) fn from_array<const N: usize>(
  22. a: &'a mut [crate::ffi::c_char; N],
  23. ) -> Result<RawWriter<'a>> {
  24. Self::new(
  25. // SAFETY: the buffer of `a` is valid for read and write as `u8` for
  26. // at least `N` bytes.
  27. unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr().cast::<u8>(), N) },
  28. )
  29. }
  30. }
  31. impl Write for RawWriter<'_> {
  32. fn write_str(&mut self, s: &str) -> fmt::Result {
  33. let bytes = s.as_bytes();
  34. let len = bytes.len();
  35. // We do not want to overwrite our null terminator
  36. if self.pos + len > self.buffer.len() - 1 {
  37. return Err(fmt::Error);
  38. }
  39. // INVARIANT: We are not overwriting the last byte
  40. self.buffer[self.pos..self.pos + len].copy_from_slice(bytes);
  41. self.pos += len;
  42. Ok(())
  43. }
  44. }