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}