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