brintos

brintos / linux-shallow public Read only

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