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}