| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- use crate::kernel::constants::EFAULT;
- use crate::prelude::*;
- use core::{cmp, mem::MaybeUninit};
- #[must_use]
- pub enum FillResult {
- Done(usize),
- Partial(usize),
- Full,
- }
- impl FillResult {
- pub fn ok_or(self, err: u32) -> KResult<()> {
- match self {
- FillResult::Done(_) => Ok(()),
- _ => Err(err),
- }
- }
- pub fn should_stop(self) -> bool {
- return !matches!(self, FillResult::Done(_));
- }
- pub fn allow_partial(self) -> usize {
- match self {
- FillResult::Done(n) | FillResult::Partial(n) => n,
- FillResult::Full => 0,
- }
- }
- }
- pub trait Buffer {
- fn total(&self) -> usize;
- fn wrote(&self) -> usize;
- #[must_use]
- fn fill(&mut self, data: &[u8]) -> KResult<FillResult>;
- fn available(&self) -> usize {
- self.total() - self.wrote()
- }
- fn get_writer(&mut self) -> BufferWrite<'_, Self>
- where
- Self: Sized,
- {
- BufferWrite(self)
- }
- }
- pub trait Stream {
- fn poll_data<'a>(&mut self, buf: &'a mut [u8]) -> KResult<Option<&'a mut [u8]>>;
- fn ignore(&mut self, len: usize) -> KResult<Option<usize>>;
- }
- pub trait IntoStream {
- type Stream: Stream;
- fn into_stream(self) -> Self::Stream;
- }
- pub trait StreamRead {
- fn read_till_end(
- &mut self,
- buffer: &mut [u8],
- func: impl Fn(&mut [u8]) -> KResult<()>,
- ) -> KResult<usize>;
- fn ignore_all(&mut self) -> KResult<usize>;
- }
- impl<T> StreamRead for T
- where
- T: Stream + ?Sized,
- {
- fn read_till_end(
- &mut self,
- buffer: &mut [u8],
- func: impl Fn(&mut [u8]) -> KResult<()>,
- ) -> KResult<usize> {
- let mut total = 0;
- while let Some(data) = self.poll_data(buffer)? {
- func(data)?;
- total += data.len();
- }
- Ok(total)
- }
- fn ignore_all(&mut self) -> KResult<usize> {
- let mut total = 0;
- while let Some(len) = self.ignore(usize::MAX)? {
- total += len;
- }
- Ok(total)
- }
- }
- pub trait BufferFill<T: Copy> {
- fn copy(&mut self, object: &T) -> KResult<FillResult>;
- }
- impl<T: Copy, B: Buffer + ?Sized> BufferFill<T> for B {
- fn copy(&mut self, object: &T) -> KResult<FillResult> {
- let ptr = object as *const T as *const u8;
- let len = core::mem::size_of::<T>();
- // SAFETY: `object` is a valid object.
- self.fill(unsafe { core::slice::from_raw_parts(ptr, len) })
- }
- }
- pub struct BufferWrite<'b, B>(&'b mut B)
- where
- B: Buffer + ?Sized;
- impl<'b, B> core::fmt::Write for BufferWrite<'b, B>
- where
- B: Buffer + ?Sized,
- {
- fn write_str(&mut self, s: &str) -> core::fmt::Result {
- match self.0.fill(s.as_bytes()) {
- Ok(FillResult::Done(_)) => Ok(()),
- _ => Err(core::fmt::Error),
- }
- }
- }
- pub struct UninitBuffer<'lt, T: Copy + Sized> {
- data: Box<MaybeUninit<T>>,
- buffer: ByteBuffer<'lt>,
- }
- impl<'lt, T: Copy + Sized> UninitBuffer<'lt, T> {
- pub fn new() -> Self {
- let mut data = Box::new(MaybeUninit::uninit());
- let ptr = data.as_mut_ptr();
- Self {
- data,
- buffer: ByteBuffer::from(unsafe {
- core::slice::from_raw_parts_mut(ptr as *mut u8, core::mem::size_of::<T>())
- }),
- }
- }
- pub fn assume_filled_ref(&self) -> KResult<&T> {
- if self.buffer.available() != 0 {
- Err(EFAULT)
- } else {
- Ok(unsafe { self.data.assume_init_ref() })
- }
- }
- pub fn assume_init(self) -> KResult<T> {
- if self.buffer.available() != 0 {
- Err(EFAULT)
- } else {
- Ok(unsafe { *self.data.assume_init() })
- }
- }
- }
- impl<'lt, T: Copy + Sized> Buffer for UninitBuffer<'lt, T> {
- fn total(&self) -> usize {
- self.buffer.total()
- }
- fn wrote(&self) -> usize {
- self.buffer.wrote()
- }
- fn fill(&mut self, data: &[u8]) -> KResult<FillResult> {
- self.buffer.fill(data)
- }
- }
- pub struct ByteBuffer<'lt> {
- buf: &'lt mut [u8],
- cur: usize,
- }
- impl<'lt> ByteBuffer<'lt> {
- pub fn new(buf: &'lt mut [u8]) -> Self {
- Self { buf, cur: 0 }
- }
- pub fn available(&self) -> usize {
- self.buf.len() - self.cur
- }
- pub fn data(&self) -> &[u8] {
- &self.buf[..self.cur]
- }
- }
- impl<'lt, T: Copy + Sized> From<&'lt mut [T]> for ByteBuffer<'lt> {
- fn from(value: &'lt mut [T]) -> Self {
- Self {
- buf: unsafe {
- core::slice::from_raw_parts_mut(
- value.as_ptr() as *mut u8,
- core::mem::size_of::<T>() * value.len(),
- )
- },
- cur: 0,
- }
- }
- }
- impl Buffer for ByteBuffer<'_> {
- fn total(&self) -> usize {
- self.buf.len()
- }
- fn fill(&mut self, data: &[u8]) -> KResult<FillResult> {
- match self.available() {
- 0 => Ok(FillResult::Full),
- n if n < data.len() => {
- self.buf[self.cur..].copy_from_slice(&data[..n]);
- self.cur += n;
- Ok(FillResult::Partial(n))
- }
- _ => {
- self.buf[self.cur..self.cur + data.len()].copy_from_slice(data);
- self.cur += data.len();
- Ok(FillResult::Done(data.len()))
- }
- }
- }
- fn wrote(&self) -> usize {
- self.cur
- }
- }
- /// Iterator that generates chunks of a given length from a start index
- /// until the end of the total length.
- ///
- /// The iterator returns a tuple of (start, len) for each chunk.
- pub struct Chunks {
- end: usize,
- cur: usize,
- chunk_len: usize,
- }
- impl Chunks {
- pub const fn new(start: usize, total_len: usize, chunk_len: usize) -> Self {
- Self {
- end: start + total_len,
- cur: start,
- chunk_len,
- }
- }
- }
- impl Iterator for Chunks {
- type Item = (usize, usize);
- fn next(&mut self) -> Option<Self::Item> {
- if self.cur >= self.end {
- return None;
- }
- let start = self.cur;
- let len = cmp::min(self.chunk_len, self.end - start);
- self.cur += self.chunk_len;
- Some((start, len))
- }
- }
- pub struct ByteStream<'a> {
- data: &'a [u8],
- cur: usize,
- }
- impl<'a> ByteStream<'a> {
- pub fn new(data: &'a [u8]) -> Self {
- Self { data, cur: 0 }
- }
- }
- impl<'a> Stream for ByteStream<'a> {
- fn poll_data<'b>(&mut self, buf: &'b mut [u8]) -> KResult<Option<&'b mut [u8]>> {
- if self.cur >= self.data.len() {
- return Ok(None);
- }
- let end = core::cmp::min(self.data.len(), self.cur + buf.len());
- let data = &self.data[self.cur..end];
- let buf = &mut buf[..data.len()];
- buf.copy_from_slice(data);
- self.cur += data.len();
- Ok(Some(buf))
- }
- fn ignore(&mut self, len: usize) -> KResult<Option<usize>> {
- if self.cur >= self.data.len() {
- return Ok(None);
- }
- let remaining = self.data.len() - self.cur;
- let ignored = core::cmp::min(remaining, len);
- self.cur += ignored;
- Ok(Some(ignored))
- }
- }
- impl<'a> IntoStream for &'a [u8] {
- type Stream = ByteStream<'a>;
- fn into_stream(self) -> Self::Stream {
- ByteStream::new(self)
- }
- }
|