Skip to main content

o3/buffer/raw/
mod.rs

1use std::{
2    marker, mem,
3    num::NonZero,
4    slice::{from_raw_parts, from_raw_parts_mut},
5};
6
7use crate::{
8    base::num,
9    buffer,
10    buffer::{
11        pool::{self, owners, state},
12        resident, segments,
13        storage::provided,
14    },
15    mem::rc,
16};
17mod slices;
18pub use slices::Slices;
19mod store;
20pub use store::Store;
21mod segment;
22pub use segment::Segment;
23mod scatter;
24pub use scatter::Scatter;
25pub(in crate::buffer) use slices::{Exclusive, Prefix, SliceExt};
26
27/// # Safety
28/// The `buffer::raw::Source` contract must hold. `buffer::Cursor` must expose that same range.
29/// Consumption must advance exactly the proved prefix and preserve the remaining bytes.
30pub unsafe trait Consume: AsRef<[u8]> {
31    fn consume<const MAX: u32>(prefix: Consumed<'_, '_, Self, MAX>);
32}
33
34// SAFETY: admission retains this exact initialized slice exclusively.
35unsafe impl Consume for &mut [u8] {
36    fn consume<const MAX: u32>(prefix: Consumed<'_, '_, Self, MAX>) {
37        let (target, end) = prefix.into_parts();
38        let bytes = mem::take(target);
39        // SAFETY: the source-bound end is within this unchanged slice.
40        *target = unsafe { bytes.get_unchecked_mut(end.count().get() as usize..) };
41    }
42}
43
44// SAFETY: the view retains its immutable byte borrow and original source;
45// consumption only selects the admitted suffix of that same borrow.
46unsafe impl<S: ?Sized> Consume for buffer::View<'_, S> {
47    fn consume<const MAX: u32>(prefix: Consumed<'_, '_, Self, MAX>) {
48        let (view, end) = prefix.into_parts();
49        // SAFETY: the prefix owns the exact view and its validated bound.
50        view.bytes = unsafe { view.bytes.get_unchecked(end.count().get() as usize..) };
51    }
52}
53
54/// One owner edge that can retain the same backing independently.
55/// # Safety
56/// `try_retain` preserves backing identity, access, and branded lifetimes.
57pub unsafe trait Retain: Sized {
58    fn try_retain(&self) -> Result<Self, rc::Error>;
59}
60
61// SAFETY: Some retains the same owner and lifetime; None retains no backing.
62unsafe impl<T: Retain> Retain for Option<T> {
63    fn try_retain(&self) -> Result<Self, rc::Error> {
64        self.as_ref().map(T::try_retain).transpose()
65    }
66}
67
68/// Retains a complete source whose UTF-8 was already validated.
69/// # Safety
70/// The source's entire unchanged visible range is valid UTF-8.
71pub unsafe fn utf8<O: Source>(owner: O) -> buffer::storage::Str<O> {
72    // SAFETY: the caller proves UTF-8 for this complete immutable source.
73    unsafe { buffer::storage::Str::new(owner) }
74}
75
76/// # Safety
77/// Preserve the owner, visible range, resident capacity, and owner lifetimes.
78/// Allocate, copy, and clone nothing; do not introduce sharing.
79pub unsafe trait Convert<T> {
80    fn into(self) -> T;
81}
82
83// SAFETY: identity retains the complete original value and its byte storage.
84unsafe impl<T> Convert<T> for T {
85    fn into(self) -> T {
86        self
87    }
88}
89
90/// Storage retaining one exact nonempty physical owner.
91pub trait Unary<T> {
92    fn item(&self) -> &segments::Item<T>;
93}
94
95/// # Safety
96/// Source and returned totals remain equal and unchanged through exhaustion: exact nonoverflowing owner count, visible byte sum and resident charge sum.
97/// The count is at least two. Success yields exactly that many nonempty owners, never more on failure; preserve backing and borrows.
98/// The returned iterator and totals remain valid when either is dropped first.
99pub unsafe trait Sequence<T: buffer::raw::Segment>: Sized + Total {
100    type Item;
101    type Error;
102    fn owners(self) -> (impl Iterator<Item = Self::Item>, impl Total);
103
104    fn reject(self, error: crate::alloc::Error) -> Self::Error;
105}
106
107pub trait Total {
108    fn count(&self) -> segments::Count;
109    fn is_empty(&self) -> bool {
110        self.len() == 0
111    }
112
113    fn len(&self) -> usize;
114    fn resident(&self) -> usize;
115}
116
117/// Immutable scattered bytes with an exact length and borrowed cursor.
118///
119/// # Safety
120/// `chunks()` has `len()` remaining; offset cursors exist through the end.
121pub unsafe trait Chunks {
122    type Cursor<'data>: Scatter<'data>
123    where
124        Self: 'data;
125
126    fn is_empty(&self) -> bool {
127        self.len() == 0
128    }
129
130    fn len(&self) -> usize;
131    fn chunks(&self) -> Self::Cursor<'_>;
132    fn cursor(&self, offset: usize) -> Option<Self::Cursor<'_>> {
133        Scatter::seek(self.chunks(), offset)
134    }
135
136    /// Copies an exact array-sized suffix without changing the retained source.
137    fn suffix<const N: usize>(&self) -> Option<[u8; N]> {
138        let mut cursor = self.chunks();
139        let skipped = buffer::raw::Scatter::remaining(&cursor).checked_sub(N)?;
140        segments::scatter::Take::new(&mut cursor, skipped).finish();
141        let mut output = [0; N];
142        let source = segments::scatter::Take::new(&mut cursor, usize::MAX);
143        // SAFETY: admission and exact traversal leave N bytes in the retained
144        // source, disjoint from this exclusive array of the same length.
145        unsafe {
146            buffer::raw::copy_slices(source.map(|chunk| chunk.bytes()), output.as_mut_ptr());
147        }
148        Some(output)
149    }
150}
151
152/// An owned admission retaining its operation proof until storage accepts it.
153/// # Safety
154/// Move only the original owner; the projection must retain its lifetime and exactly `bytes()`.
155pub unsafe trait Input<T> {
156    fn bytes(&self) -> &[u8];
157    fn into_item(self) -> (T, impl for<'a> FnOnce(&'a mut T) -> &'a mut [u8]);
158}
159
160/// Projects fixed-residency items admitted by their original native context.
161pub trait Fixed<T> {
162    fn resident(&self) -> NonZero<u32>;
163
164    /// # Safety
165    /// Own this context's unique item; its full retained backing fits `resident()`.
166    /// Its prefix is initialized; `limit` is that ceiling and backing/layout live for `'a`.
167    unsafe fn project<'a, 'id>(&'a self, item: &'a mut T, limit: Limit<'id>)
168    -> Projection<'a, 'id>;
169
170    /// # Safety
171    /// Own its context's unique initialized item; full backing fits `resident()` and lives for `'d`.
172    /// Its layout and `resident()` match this arena's unchanged layout and resident ceiling.
173    unsafe fn insert<'d>(
174        vacant: provided::Vacant<'d, T, (), &'d Self>,
175        item: T,
176    ) -> provided::Unique<'d>
177    where
178        Self: Sized,
179    {
180        let context = vacant.context();
181        vacant.insert_with(item, |item, limit| {
182            // SAFETY: native admission supplied this exact context and item;
183            // the arena retains both and issues the context's resident ceiling.
184            unsafe { context.project(item, limit) }
185        })
186    }
187}
188
189/// Exact arenas entered together with their external accounting generation.
190/// # Safety
191/// Roots must borrow their original arenas. The terminal must reclaim every item and charge.
192pub unsafe trait Arenas: Unpin {
193    type Roots<'d>: 'd
194    where
195        Self: 'd;
196
197    /// # Safety
198    /// Invoke the terminal once after all issued access ends, while every charged budget lives.
199    unsafe fn enter(&mut self) -> (Self::Roots<'_>, impl FnOnce() + '_);
200}
201
202// SAFETY: disjoint owners retain their exact roots and terminate in reverse order.
203unsafe impl<A: Arenas, B: Arenas> Arenas for (A, B) {
204    type Roots<'d>
205        = (A::Roots<'d>, B::Roots<'d>)
206    where
207        Self: 'd;
208
209    unsafe fn enter(&mut self) -> (Self::Roots<'_>, impl FnOnce() + '_) {
210        // SAFETY: the caller supplies the same generation and terminal ordering for both owners.
211        let (first, finish) = unsafe { self.0.enter() };
212        let (second, end) = unsafe { self.1.enter() };
213        ((first, second), move || {
214            end();
215            finish();
216        })
217    }
218}
219
220/// A mutable projection proven to fit its resident byte ceiling.
221#[repr(transparent)]
222pub struct Projection<'a, 'id> {
223    bytes: &'a mut [u8],
224    operation: marker::PhantomData<fn(&'id mut ()) -> &'id mut ()>,
225}
226
227impl<'a> Projection<'a, '_> {
228    pub(in crate::buffer) const fn into_inner(self) -> &'a mut [u8] {
229        self.bytes
230    }
231}
232
233/// Immutable UTF-8 in one exact allocation bound to its paying domain.
234pub type Text<'d> = buffer::storage::Str<resident::Exact<'d>>;
235
236/// Exclusive initialized suffix retained through its output operation.
237pub struct Output<'a, L = pool::Layout> {
238    target: &'a mut pool::Span<owners::Plain<L>, pool::Owned, state::Initialized>,
239}
240
241impl<L> pool::Span<owners::Plain<L>, pool::Owned, state::Initialized> {
242    pub fn output(&mut self) -> Output<'_, L> {
243        Output { target: self }
244    }
245}
246
247impl<'a, L> Output<'a, L> {
248    pub fn is_empty(&self) -> bool {
249        self.len() == 0
250    }
251
252    pub fn len(&self) -> usize {
253        self.target.capacity().get() as usize - self.target.len()
254    }
255
256    pub fn as_mut_slice(&mut self) -> &mut [u8] {
257        let (data, start) = buffer::raw::Prefix::prefix(self.target);
258        // SAFETY: Initialized retains every byte of this exact exclusive suffix.
259        unsafe { range_mut(data.cast(), start as usize, self.len()) }
260    }
261
262    /// # Safety
263    /// The foreign operation must prove `len` fits this unchanged output.
264    pub unsafe fn complete(self, len: NonZero<usize>) {
265        *Exclusive::len_mut(self.target) += len.get() as u32;
266    }
267}
268
269const _: () = assert!(size_of::<Output<'_>>() == size_of::<usize>());
270
271/// # Safety
272/// Shared access preserves its exact backing, range, and contents until exclusive mutation.
273/// Writes preserve the initialized prefix; successful writes append their complete input.
274pub unsafe trait Source: AsRef<[u8]> {}
275
276// SAFETY: the stronger cursor contract requires this stable-source contract.
277unsafe impl<T: buffer::raw::Consume> Source for T {}
278
279/// # Safety
280/// `AsMut::as_mut` returns the full Source range with its pre-call pointer and length, unchanged after the loan.
281/// The call changes no owner, descriptor, extent, or bytes; caller slice writes are allowed, and other exclusive operations retain their own contracts.
282pub unsafe trait Mutable: Source + AsMut<[u8]> {}
283
284/// # Safety
285/// Every `provided::Mutable::try_take` implementation returns the exact requested prefix
286/// and retains its disjoint suffix, contents, owner and lifetimes; failure changes nothing.
287pub unsafe trait Split: Mutable {}
288
289/// # Safety
290/// Freezing retains the exact backing, initialized range, contents, owner and lifetimes.
291/// It allocates, copies and clones nothing and introduces no sharing.
292pub unsafe trait Freeze: Source + Sized {
293    type Output: Source;
294
295    fn freeze(self) -> Self::Output;
296}
297
298/// # Safety
299/// Retain source borrows and stable `len`; initialize exactly that prefix once.
300/// Never read uninitialized output, retain its access, or invalidate source borrows.
301pub unsafe trait Initializer {
302    fn len(&self) -> usize;
303
304    fn is_empty(&self) -> bool {
305        self.len() == 0
306    }
307
308    /// # Safety
309    /// `target` exclusively retains at least `self.len()` writable bytes.
310    unsafe fn initialize(&self, target: *mut mem::MaybeUninit<u8>);
311}
312
313pub(in crate::buffer) use store::{Backing, Debit, Header, Heap, Policy, Rc};
314
315mod length;
316pub use length::Length;
317mod limit;
318pub use limit::Limit;
319mod consumed;
320pub use consumed::Consumed;
321pub(in crate::buffer) use consumed::Selection;
322mod slice;
323pub use slice::Slice;
324
325/// One proven non-empty span borrowed from its source.
326#[repr(transparent)]
327pub struct Chunk<'data, const MAX: usize = { usize::MAX }> {
328    bytes: &'data [u8],
329}
330
331/// Borrows exactly `len` initialized bytes at `start` of one allocation.
332/// # Safety
333/// `pointer.add(start)` must be valid. A nonempty selected range must contain
334/// `len` initialized bytes in one allocation retained for `'a`, without
335/// overlapping exclusive access. The nonnull selected pointer and extent must
336/// satisfy [`from_raw_parts`], including its `isize` bound and empty-range rules.
337pub(in crate::buffer) unsafe fn range<'a>(
338    pointer: *const u8,
339    start: usize,
340    len: usize,
341) -> &'a [u8] {
342    // SAFETY: the caller proved this exact initialized subrange of one allocation.
343    unsafe { from_raw_parts(pointer.add(start), len) }
344}
345
346/// Borrows the same initialized subrange exclusively.
347///
348/// # Safety
349/// As [`range`], with exclusive access to the selected range for `'a`.
350/// Other accesses during that loan must be disjoint; the selected pointer and
351/// extent must satisfy [`from_raw_parts_mut`], including its empty-range rules.
352pub(in crate::buffer) unsafe fn range_mut<'a>(
353    pointer: *mut u8,
354    start: usize,
355    len: usize,
356) -> &'a mut [u8] {
357    // SAFETY: the caller proved this exact initialized subrange and its exclusive retention.
358    unsafe { from_raw_parts_mut(pointer.add(start), len) }
359}
360
361impl<'data, const MAX: usize> Chunk<'data, MAX> {
362    /// Retains one exact initialized span from its original immutable borrow.
363    ///
364    /// # Safety
365    /// `bytes` is non-empty and `bytes.len() <= MAX`.
366    pub unsafe fn new(bytes: &'data [u8]) -> Self {
367        Self { bytes }
368    }
369
370    pub const fn bytes(&self) -> &'data [u8] {
371        self.bytes
372    }
373
374    pub const fn len(&self) -> num::bounded::NonZeroUsize<1, MAX> {
375        // SAFETY: construction proves the retained span is non-empty and bounded by MAX.
376        unsafe { num::bounded::raw::nonzero_usize(self.bytes.len()) }
377    }
378}
379
380const _: () = {
381    assert!(mem::size_of::<Chunk<'static>>() == mem::size_of::<&[u8]>());
382    assert!(mem::size_of::<Option<Chunk<'static>>>() == mem::size_of::<&[u8]>());
383};
384
385/// Copies slices consecutively without publishing a length.
386///
387/// # Safety
388/// The finite source sequence's total length must fit `isize` without overflow.
389/// `target` must be nonnull and retain exclusive writable storage for that range
390/// in one allocation; an aligned dangling pointer is allowed for a zero total.
391/// Sources must remain valid and disjoint from the entire destination throughout
392/// the call. Iterator callbacks must preserve these conditions and must not
393/// access the destination.
394pub unsafe fn copy_slices<'a>(sources: impl IntoIterator<Item = &'a [u8]>, target: *mut u8) {
395    let mut offset = 0;
396    for source in sources {
397        // SAFETY: the caller retains all sources and their complete disjoint target.
398        unsafe { source.copy_to(target.add(offset)) };
399        offset += source.len();
400    }
401}