use std::{mem, num::NonZero};
pub use bounds::Bounds;
pub use cursor::Cursor;
pub(in crate::buffer::segments::queue) use cursor::Position;
pub use error::Error;
pub use fifo::Fifo;
pub use slice::Slice;
use crate::{
buffer,
buffer::{hold, segments, segments::queue},
depot::capacity,
};
mod bounds;
mod cursor;
mod error;
mod slice;
pub(in crate::buffer::segments) use slice::Projected;
mod fifo;
pub struct Array<'a, T, const N: usize> {
source: Iter<'a, T>,
}
impl<'a, T: buffer::raw::Segment, const N: usize> Array<'a, T, N> {
pub fn try_new(location: &queue::Cursor<'a, T>, offset: usize) -> Result<Self, queue::Bounds> {
let position = queue::Position::try_new(location, offset, N)?;
Ok(Self {
source: Iter::at(position),
})
}
pub fn contiguous(&mut self) -> Option<&'a [u8; N]> {
let Some(mut step) = Step::array(self) else {
return Some(&[0; N]);
};
step.peek().bytes().as_array()
}
pub fn copy(self, target: &mut [u8; N]) {
unsafe { buffer::raw::copy_slices(self.source, target.as_mut_ptr()) };
}
}
const _: () = assert!(size_of::<Array<'static, (), 9>>() == 3 * size_of::<usize>());
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RetainError {
Segments(segments::Error),
Copy(hold::CopyError),
}
impl From<segments::Error> for RetainError {
fn from(cause: segments::Error) -> Self {
Self::Segments(cause)
}
}
pub struct Iter<'a, T> {
location: queue::Cursor<'a, T>,
start: u32,
end: u32,
}
struct Step<'cursor, 'data, T, const MAX: usize> {
source: &'cursor mut Iter<'data, T>,
cap: NonZero<usize>,
}
impl<'cursor, 'data, T> Step<'cursor, 'data, T, { usize::MAX }> {
fn array<const N: usize>(source: &'cursor mut Array<'data, T, N>) -> Option<Self> {
let cap = NonZero::new(N)?;
Some(Self {
source: &mut source.source,
cap,
})
}
}
impl<'data, T: buffer::raw::Segment, const MAX: usize> Step<'_, 'data, T, MAX> {
fn peek(&mut self) -> buffer::raw::Chunk<'data, MAX> {
let source = &self.source;
let (location, bytes) = unsafe { source.location.locate(source.start) };
let start = (source.start - location.start) as usize;
let len = (bytes.len().get() - start).min(self.cap.get());
let part = unsafe { bytes.bytes().get_unchecked(start..start + len) };
self.source.location = location;
unsafe { buffer::raw::Chunk::new(part) }
}
fn advance(mut self) -> buffer::raw::Chunk<'data, MAX> {
let chunk = self.peek();
self.source.start += chunk.len().get() as u32;
chunk
}
}
impl<'a, T> Iter<'a, T> {
pub(in crate::buffer::segments::queue) const fn new(slice: queue::Slice<'a, T>) -> Self {
Self {
location: queue::Cursor::new(slice.queue),
start: slice.start,
end: slice.end,
}
}
}
impl<'a, T: buffer::raw::Segment> Iter<'a, T> {
pub(in crate::buffer) fn remaining(&self) -> usize {
(self.end - self.start) as usize
}
pub(in crate::buffer) unsafe fn next_chunk<const MAX: usize>(
&mut self,
cap: NonZero<usize>,
_left: NonZero<usize>,
) -> buffer::raw::Chunk<'a, MAX> {
Step { source: self, cap }.advance()
}
fn at(position: queue::Position<'_, 'a, T>) -> Self {
Self {
location: queue::Cursor {
queue: position.location.queue,
segment: position.location.segment,
start: position.location.start,
},
start: position.start,
end: position.end,
}
}
}
impl<'a, T: buffer::raw::Segment> Iterator for Iter<'a, T> {
type Item = &'a [u8];
fn next(&mut self) -> Option<Self::Item> {
let left = NonZero::new(buffer::raw::Scatter::remaining(self))?;
Some(
Step::<_, { usize::MAX }> {
source: self,
cap: left,
}
.advance()
.bytes(),
)
}
}
const _: () = assert!(mem::size_of::<Iter<'static, u64>>() == 3 * mem::size_of::<u64>());
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Capacity {
bytes: capacity::Count,
segments: capacity::Count,
}
impl Capacity {
#[must_use]
pub const fn new(bytes: capacity::Count, segments: capacity::Count) -> Self {
Self { bytes, segments }
}
#[must_use]
pub const fn bytes(self) -> capacity::Count {
self.bytes
}
#[must_use]
pub const fn segments(self) -> capacity::Count {
self.segments
}
}
const _: () = assert!(mem::size_of::<Capacity>() == mem::size_of::<u64>());