Skip to main content

musli_zerocopy/buf/
owned_buf.rs

1use core::alloc::Layout;
2use core::borrow::Borrow;
3use core::marker::PhantomData;
4use core::mem::{ManuallyDrop, MaybeUninit, align_of, size_of, size_of_val};
5use core::ops::Deref;
6use core::ptr::NonNull;
7use core::slice::{self, SliceIndex};
8
9#[cfg(feature = "std")]
10use std::io;
11
12use alloc::alloc;
13
14use crate::buf::{self, AllocError, Buf, DefaultAlignment, Padder, StoreBuf};
15use crate::endian::{ByteOrder, DefaultEndian};
16use crate::error::{Error, ErrorKind};
17use crate::mem::PackedMaybeUninit;
18use crate::pointer::{DefaultSize, Ref, Size};
19use crate::traits::{UnsizedZeroCopy, ZeroCopy};
20
21/// An allocating buffer with dynamic alignment.
22///
23/// By default this buffer starts out having the same alignment as `usize`,
24/// making it platform specific. But this alignment can grow in demand to the
25/// types being stored in it.
26///
27/// # Examples
28///
29/// ```
30/// use musli_zerocopy::{OwnedBuf, ZeroCopy};
31///
32/// #[derive(ZeroCopy)]
33/// #[repr(C, align(128))]
34/// struct Custom {
35///     field: u32
36/// }
37///
38/// let mut buf = OwnedBuf::new();
39/// buf.store(&Custom { field: 10 })?;
40/// assert!(buf.alignment() >= 128);
41/// # Ok::<_, musli_zerocopy::Error>(())
42/// ```
43pub struct OwnedBuf<E = DefaultEndian, O = DefaultSize>
44where
45    E: ByteOrder,
46    O: Size,
47{
48    data: NonNull<MaybeUninit<u8>>,
49    /// The initialized length of the buffer.
50    len: usize,
51    /// The capacity of the buffer.
52    capacity: usize,
53    /// The requested alignment.
54    requested: usize,
55    /// The current alignment.
56    align: usize,
57    /// Holding onto the current pointer size.
58    _marker: PhantomData<(E, O)>,
59}
60
61impl Default for OwnedBuf {
62    #[inline]
63    fn default() -> Self {
64        Self::new()
65    }
66}
67
68impl OwnedBuf {
69    /// Construct a new empty buffer with the default alignment.
70    ///
71    /// The default alignment is guaranteed to be larger than 0.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use musli_zerocopy::OwnedBuf;
77    ///
78    /// let buf = OwnedBuf::new();
79    /// assert!(buf.is_empty());
80    /// assert!(buf.alignment() > 0);
81    /// assert!(buf.alignment() >= buf.requested());
82    /// ```
83    pub const fn new() -> Self {
84        Self::with_alignment::<DefaultAlignment>()
85    }
86
87    /// Allocate a new buffer with the given capacity and default alignment.
88    ///
89    /// The buffer must allocate for at least the given `capacity`, but might
90    /// allocate more. If the capacity specified is `0` it will not allocate.
91    ///
92    /// # Errors
93    ///
94    /// Errors if the specified capacity and memory layout are illegal, which
95    /// happens if:
96    /// * The alignment is not a power of two.
97    /// * The specified capacity causes the needed memory to overflow
98    ///   `isize::MAX`.
99    ///
100    /// ```should_panic
101    /// use std::mem::align_of;
102    ///
103    /// use musli_zerocopy::{endian, DefaultAlignment, OwnedBuf};
104    ///
105    /// let max = isize::MAX as usize - (align_of::<DefaultAlignment>() - 1);
106    /// OwnedBuf::<endian::Native, u32>::with_capacity(max)?;
107    /// # Ok::<_, musli_zerocopy::buf::AllocError>(())
108    /// ```
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use musli_zerocopy::OwnedBuf;
114    ///
115    /// let buf = OwnedBuf::with_capacity(6)?;
116    /// assert!(buf.capacity() >= 6);
117    /// # Ok::<_, musli_zerocopy::Error>(())
118    /// ```
119    pub fn with_capacity(capacity: usize) -> Result<Self, AllocError> {
120        Self::with_capacity_and_alignment::<DefaultAlignment>(capacity)
121    }
122
123    /// Construct a new empty buffer with an alignment matching that of `T`.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// use musli_zerocopy::OwnedBuf;
129    ///
130    /// let buf = OwnedBuf::with_alignment::<u64>();
131    /// assert!(buf.is_empty());
132    /// assert!(buf.alignment() >= 8);
133    /// assert_eq!(buf.requested(), 8);
134    /// ```
135    pub const fn with_alignment<T>() -> Self {
136        let align = align_of::<T>();
137
138        Self {
139            // SAFETY: Alignment is asserted through `T`.
140            data: unsafe { dangling(align) },
141            len: 0,
142            capacity: 0,
143            requested: align,
144            align,
145            _marker: PhantomData,
146        }
147    }
148
149    /// Allocate a new buffer with the given `capacity` and an alignment
150    /// matching that of `T`.
151    ///
152    /// The buffer must allocate for at least the given `capacity`, but might
153    /// allocate more. If the capacity specified is `0` it will not allocate.
154    ///
155    /// # Errors
156    ///
157    /// Errors if the specified capacity and memory layout are illegal, which
158    /// happens if:
159    /// * The alignment is not a power of two.
160    /// * The specified capacity causes the needed memory to overflow
161    ///   `isize::MAX`.
162    ///
163    /// ```should_panic
164    /// use musli_zerocopy::OwnedBuf;
165    ///
166    /// let max = isize::MAX as usize - (8 - 1);
167    /// OwnedBuf::with_capacity_and_alignment::<u64>(max)?;
168    /// # Ok::<_, musli_zerocopy::buf::AllocError>(())
169    /// ```
170    ///
171    /// # Examples
172    ///
173    /// ```
174    /// use musli_zerocopy::OwnedBuf;
175    ///
176    /// let buf = OwnedBuf::with_capacity_and_alignment::<u16>(6)?;
177    /// assert!(buf.capacity() >= 6);
178    /// assert!(buf.alignment() >= 2);
179    /// # Ok::<_, musli_zerocopy::Error>(())
180    /// ```
181    pub fn with_capacity_and_alignment<T>(capacity: usize) -> Result<Self, AllocError> {
182        // SAFETY: Alignment of `T` is always a power of two.
183        Ok(unsafe { Self::with_capacity_and_custom_alignment(capacity, align_of::<T>())? })
184    }
185}
186
187impl<E, O> OwnedBuf<E, O>
188where
189    E: ByteOrder,
190    O: Size,
191{
192    /// Modify the buffer to utilize the specified pointer size when inserting
193    /// references.
194    ///
195    /// # Examples
196    ///
197    /// ```
198    /// use musli_zerocopy::OwnedBuf;
199    ///
200    /// let mut buf = OwnedBuf::with_capacity(1024)?
201    ///     .with_size::<u8>();
202    /// # Ok::<_, musli_zerocopy::Error>(())
203    /// ```
204    #[inline]
205    pub fn with_size<U>(self) -> OwnedBuf<E, U>
206    where
207        U: Size,
208    {
209        let this = ManuallyDrop::new(self);
210
211        OwnedBuf {
212            data: this.data,
213            len: this.len,
214            capacity: this.capacity,
215            requested: this.requested,
216            align: this.align,
217            _marker: PhantomData,
218        }
219    }
220
221    /// Modify the buffer to utilize the specified byte order when inserting
222    /// references.
223    ///
224    /// # Examples
225    ///
226    /// ```
227    /// use musli_zerocopy::{endian, OwnedBuf};
228    ///
229    /// let mut buf = OwnedBuf::with_capacity(1024)?
230    ///     .with_byte_order::<endian::Little>();
231    /// # Ok::<_, musli_zerocopy::Error>(())
232    /// ```
233    #[inline]
234    pub fn with_byte_order<U>(self) -> OwnedBuf<U, O>
235    where
236        U: ByteOrder,
237    {
238        let this = ManuallyDrop::new(self);
239
240        OwnedBuf {
241            data: this.data,
242            len: this.len,
243            capacity: this.capacity,
244            requested: this.requested,
245            align: this.align,
246            _marker: PhantomData,
247        }
248    }
249
250    // # Safety
251    //
252    // The specified alignment must be a power of two.
253    pub(crate) unsafe fn with_capacity_and_custom_alignment(
254        capacity: usize,
255        align: usize,
256    ) -> Result<Self, AllocError> where {
257        if capacity == 0 {
258            return Ok(Self {
259                // SAFETY: Alignment is asserted through `T`.
260                data: unsafe { dangling(align) },
261                len: 0,
262                capacity: 0,
263                requested: align,
264                align,
265                _marker: PhantomData,
266            });
267        }
268
269        let layout = Layout::from_size_align(capacity, align).expect("Illegal memory layout");
270
271        unsafe {
272            let data = alloc::alloc(layout);
273
274            if data.is_null() {
275                return Err(AllocError::alloc_error(layout));
276            }
277
278            Ok(Self {
279                data: NonNull::new_unchecked(data.cast()),
280                len: 0,
281                capacity,
282                requested: align,
283                align,
284                _marker: PhantomData,
285            })
286        }
287    }
288
289    /// Get the current length of the buffer.
290    ///
291    /// # Examples
292    ///
293    /// ```
294    /// use musli_zerocopy::OwnedBuf;
295    ///
296    /// let buf = OwnedBuf::new();
297    /// assert_eq!(buf.len(), 0);
298    /// ```
299    #[inline]
300    pub fn len(&self) -> usize {
301        self.len
302    }
303
304    /// Clear the current buffer.
305    ///
306    /// This won't cause any reallocations.
307    ///
308    /// # Examples
309    ///
310    /// ```
311    /// use musli_zerocopy::OwnedBuf;
312    ///
313    /// let mut buf = OwnedBuf::new();
314    /// assert_eq!(buf.capacity(), 0);
315    /// buf.extend_from_slice(&[1, 2, 3, 4])?;
316    ///
317    /// assert_eq!(buf.len(), 4);
318    /// buf.clear();
319    /// assert!(buf.capacity() > 0);
320    /// assert_eq!(buf.len(), 0);
321    /// # Ok::<_, musli_zerocopy::Error>(())
322    /// ```
323    #[inline]
324    pub fn clear(&mut self) {
325        self.len = 0;
326    }
327
328    /// Test if the buffer is empty.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use musli_zerocopy::OwnedBuf;
334    ///
335    /// let buf = OwnedBuf::new();
336    /// assert!(buf.is_empty());
337    /// ```
338    #[inline]
339    pub fn is_empty(&self) -> bool {
340        self.len == 0
341    }
342
343    /// Get the current capacity of the buffer.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// use musli_zerocopy::OwnedBuf;
349    ///
350    /// let buf = OwnedBuf::new();
351    /// assert_eq!(buf.capacity(), 0);
352    /// ```
353    #[inline]
354    pub fn capacity(&self) -> usize {
355        self.capacity
356    }
357
358    /// Return the requested alignment of the buffer.
359    ///
360    /// # Examples
361    ///
362    /// ```
363    /// use musli_zerocopy::OwnedBuf;
364    ///
365    /// let buf = OwnedBuf::with_alignment::<u64>();
366    /// assert!(buf.is_empty());
367    /// assert!(buf.alignment() >= 8);
368    /// assert_eq!(buf.requested(), 8);
369    /// ```
370    #[inline]
371    pub fn requested(&self) -> usize {
372        self.requested
373    }
374
375    /// Reserve capacity for at least `capacity` more bytes in this buffer.
376    ///
377    /// # Examples
378    ///
379    /// ```
380    /// use musli_zerocopy::OwnedBuf;
381    ///
382    /// let mut buf = OwnedBuf::new();
383    /// assert_eq!(buf.capacity(), 0);
384    ///
385    /// buf.reserve(10);
386    /// assert!(buf.capacity() >= 10);
387    /// ```
388    #[inline]
389    pub fn reserve(&mut self, capacity: usize) -> Result<(), AllocError> {
390        let new_capacity = self
391            .len
392            .checked_add(capacity)
393            .ok_or_else(|| AllocError::capacity(self.capacity, usize::MAX))?;
394        self.ensure_capacity(new_capacity)?;
395        Ok(())
396    }
397
398    /// Advance the length of the owned buffer by `size`.
399    ///
400    /// # Safety
401    ///
402    /// The caller must ensure that bytes up until `len() + size` has been
403    /// initialized in this buffer.
404    #[inline]
405    pub unsafe fn advance(&mut self, size: usize) {
406        self.len += size;
407    }
408
409    /// Get get a raw pointer to the current buffer.
410    #[inline]
411    pub(crate) fn as_ptr(&self) -> *const u8 {
412        self.data.as_ptr() as *const _
413    }
414
415    /// Get get a raw mutable pointer to the current buffer.
416    #[inline]
417    pub(crate) fn as_mut_ptr(&mut self) -> *mut MaybeUninit<u8> {
418        self.data.as_ptr()
419    }
420
421    /// Get get a raw mutable pointer to the current buffer.
422    #[inline]
423    #[cfg(test)]
424    pub(crate) fn as_nonnull(&mut self) -> NonNull<MaybeUninit<u8>> {
425        self.data
426    }
427
428    /// Extract a slice containing the entire buffer.
429    ///
430    /// # Examples
431    ///
432    /// ```
433    /// use musli_zerocopy::OwnedBuf;
434    ///
435    /// let mut buf = OwnedBuf::new();
436    /// buf.extend_from_slice(b"hello world")?;
437    /// assert_eq!(buf.as_slice(), b"hello world");
438    /// # Ok::<_, musli_zerocopy::Error>(())
439    /// ```
440    #[inline]
441    pub fn as_slice(&self) -> &[u8] {
442        unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
443    }
444
445    /// Extract a mutable slice containing the entire buffer.
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// use musli_zerocopy::OwnedBuf;
451    ///
452    /// let mut buf = OwnedBuf::new();
453    /// buf.extend_from_slice(b"hello world")?;
454    /// buf.as_mut_slice().make_ascii_uppercase();
455    /// assert_eq!(buf.as_slice(), b"HELLO WORLD");
456    /// # Ok::<_, musli_zerocopy::Error>(())
457    /// ```
458    #[inline]
459    pub fn as_mut_slice(&mut self) -> &mut [u8] {
460        // SAFETY: We only expose the initialized part of the buffer.
461        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr().cast(), self.len()) }
462    }
463
464    /// Access the buffer mutably.
465    ///
466    /// # Examples
467    ///
468    /// ```
469    /// use musli_zerocopy::OwnedBuf;
470    ///
471    /// let mut buf = OwnedBuf::new();
472    /// let slice = buf.store_unsized("hello world")?;
473    ///
474    /// // SAFETY: We don't manipulate the underlying buffer in a way which leaves uninitialized data.
475    /// let buf = unsafe { buf.as_mut_buf() };
476    ///
477    /// buf.load_mut(slice)?.make_ascii_uppercase();
478    /// assert_eq!(buf.load(slice)?, "HELLO WORLD");
479    /// # Ok::<_, musli_zerocopy::Error>(())
480    /// ```
481    ///
482    /// # Safety
483    ///
484    /// Since this allows the underlying buffer to be mutated, depending on how
485    /// the buffer is used it might result in undefined bit-patterns like
486    /// padding bytes being written to it. The caller must ensure this is not
487    /// done with the structures being written by for example calling
488    /// [`ZeroCopy::initialize_padding()`] after the contents of the buffer is
489    /// modified.
490    ///
491    /// See [`Buf::new_mut`] for more information.
492    #[inline]
493    pub unsafe fn as_mut_buf(&mut self) -> &mut Buf {
494        unsafe { Buf::new_mut(self.as_mut_slice()) }
495    }
496
497    /// Store an uninitialized value.
498    ///
499    /// This allows values to be inserted before they can be initialized, which
500    /// can be useful if you need them to be in a certain location in the buffer
501    /// but don't have access to their value yet.
502    ///
503    /// The memory for `T` will be zero-initialized at [`next_offset<T>()`] and
504    /// the length and alignment requirement of `OwnedBuf` updated to reflect
505    /// that an instance of `T` has been stored. But that representation might
506    /// not match the representation of `T`[^non-zero].
507    ///
508    /// To get the offset where the value will be written, call
509    /// [`next_offset<T>()`] before storing the value.
510    ///
511    /// > **Note:** this does not return [`MaybeUninit`], instead we use an
512    /// > internal [`MaybeUninit`] which is similar but has different
513    /// > properties. See [its documentation][MaybeUninit] for more.
514    ///
515    /// [`next_offset<T>()`]: Self::next_offset()
516    /// [^non-zero]: Like with [`NonZero*`][core::num] types.
517    ///
518    /// # Examples
519    ///
520    /// ```
521    /// use musli_zerocopy::mem::PackedMaybeUninit;
522    /// use musli_zerocopy::{OwnedBuf, Ref, ZeroCopy};
523    ///
524    /// #[derive(ZeroCopy)]
525    /// #[repr(C)]
526    /// struct Custom { field: u32, string: Ref<str> }
527    ///
528    /// let mut buf = OwnedBuf::new();
529    /// let reference: Ref<PackedMaybeUninit<Custom>> = buf.store_uninit::<Custom>()?;
530    ///
531    /// let string = buf.store_unsized("Hello World!")?;
532    ///
533    /// buf.load_uninit_mut(reference)?.write(&Custom { field: 42, string });
534    ///
535    /// let reference = reference.assume_init();
536    /// assert_eq!(reference.offset(), 0);
537    /// # Ok::<_, musli_zerocopy::Error>(())
538    /// ```
539    #[inline]
540    pub fn store_uninit<T>(&mut self) -> Result<Ref<PackedMaybeUninit<T>, E, O>, Error>
541    where
542        T: ZeroCopy,
543    {
544        // SAFETY: We've just reserved capacity for this write.
545        unsafe {
546            self.next_offset_with_and_reserve(align_of::<T>(), size_of::<T>())?;
547            let offset = self.len;
548
549            self.data
550                .as_ptr()
551                .add(self.len)
552                .write_bytes(0, size_of::<T>());
553
554            self.len += size_of::<T>();
555            Ok(Ref::try_with_metadata_unchecked(offset, ())?)
556        }
557    }
558
559    /// Write a reference that might not have been initialized.
560    ///
561    /// This does not prevent [`Ref`] from different instances of [`OwnedBuf`]
562    /// from being written. It would only result in garbled data, but wouldn't
563    /// be a safety concern.
564    ///
565    /// > **Note:** this does not return [`std::mem::MaybeUninit`], instead we
566    /// > use an internal [`MaybeUninit`] which is similar but has different
567    /// > properties. See [its documentation][MaybeUninit] for more.
568    ///
569    /// # Errors
570    ///
571    /// Errors if the reference [`Ref::offset()`] and size of `T` does not fit
572    /// within the [`len()`] of the current structure. This might happen if you
573    /// try and use a reference constructed from a different [`OwnedBuf`]
574    /// instance.
575    ///
576    /// [`len()`]: Self::len()
577    ///
578    /// ```should_panic
579    /// use musli_zerocopy::OwnedBuf;
580    ///
581    /// let mut buf2 = OwnedBuf::new();
582    /// let number = buf2.store_uninit::<u32>()?;
583    ///
584    /// let mut buf1 = OwnedBuf::new();
585    /// buf1.load_uninit_mut(number)?.write(&42u32);
586    /// # Ok::<_, musli_zerocopy::Error>(())
587    /// ```
588    ///
589    /// # Examples
590    ///
591    /// ```
592    /// use musli_zerocopy::{OwnedBuf, Ref, ZeroCopy};
593    /// use musli_zerocopy::mem::PackedMaybeUninit;
594    ///
595    /// #[derive(ZeroCopy)]
596    /// #[repr(C)]
597    /// struct Custom { field: u32, string: Ref<str> }
598    ///
599    /// let mut buf = OwnedBuf::new();
600    /// let reference: Ref<PackedMaybeUninit<Custom>> = buf.store_uninit::<Custom>()?;
601    ///
602    /// let string = buf.store_unsized("Hello World!")?;
603    ///
604    /// buf.load_uninit_mut(reference)?.write(&Custom { field: 42, string });
605    ///
606    /// let reference = reference.assume_init();
607    /// assert_eq!(reference.offset(), 0);
608    /// # Ok::<_, musli_zerocopy::Error>(())
609    /// ```
610    #[inline]
611    pub fn load_uninit_mut<T, U, I>(
612        &mut self,
613        at: Ref<PackedMaybeUninit<T>, U, I>,
614    ) -> Result<&mut PackedMaybeUninit<T>, Error>
615    where
616        T: ZeroCopy,
617        U: ByteOrder,
618        I: Size,
619    {
620        let offset = at.offset();
621
622        if offset + size_of::<T>() > self.len {
623            return Err(Error::new(ErrorKind::OutOfRangeBounds {
624                range: offset..offset + size_of::<T>(),
625                len: self.len,
626            }));
627        }
628
629        // SAFETY: `MaybeUninit<T>` has no representation requirements and is
630        // unaligned.
631        Ok(unsafe { &mut *(self.data.as_ptr().add(offset) as *mut PackedMaybeUninit<T>) })
632    }
633
634    /// Insert a value with the given size.
635    ///
636    /// The memory for `T` will be initialized at [`next_offset<T>()`] and the
637    /// length and alignment requirement of `OwnedBuf` updated to reflect that
638    /// an instance of `T` has been stored.
639    ///
640    /// To get the offset where the value will be written, call
641    /// [`next_offset<T>()`] before storing the value or access the offset
642    /// through the [`Ref::offset`] being returned.
643    ///
644    /// [`next_offset<T>()`]: Self::next_offset
645    ///
646    /// # Examples
647    ///
648    /// ```
649    /// use musli_zerocopy::{OwnedBuf, Ref, ZeroCopy};
650    ///
651    /// #[derive(ZeroCopy)]
652    /// #[repr(C)]
653    /// struct Custom { field: u32, string: Ref<str> }
654    ///
655    /// let mut buf = OwnedBuf::new();
656    ///
657    /// let string = buf.store_unsized("string")?;
658    /// let custom = buf.store(&Custom { field: 1, string })?;
659    /// let custom2 = buf.store(&Custom { field: 2, string })?;
660    ///
661    /// let custom = buf.load(custom)?;
662    /// assert_eq!(custom.field, 1);
663    /// assert_eq!(buf.load(custom.string)?, "string");
664    ///
665    /// let custom2 = buf.load(custom2)?;
666    /// assert_eq!(custom2.field, 2);
667    /// assert_eq!(buf.load(custom2.string)?, "string");
668    /// # Ok::<_, musli_zerocopy::Error>(())
669    /// ```
670    ///
671    /// Storing an array:
672    ///
673    ///
674    /// ```
675    /// use musli_zerocopy::{ZeroCopy, OwnedBuf};
676    ///
677    /// // Element with padding.
678    /// #[derive(Debug, PartialEq, ZeroCopy)]
679    /// #[repr(C)]
680    /// struct Element {
681    ///     first: u8,
682    ///     second: u32,
683    /// }
684    ///
685    /// let values = [
686    ///     Element { first: 0x01, second: 0x01020304u32 },
687    ///     Element { first: 0x02, second: 0x01020304u32 }
688    /// ];
689    ///
690    /// let mut buf = OwnedBuf::new();
691    /// let array = buf.store(&values)?;
692    /// assert_eq!(buf.load(array)?, &values);
693    /// # Ok::<_, musli_zerocopy::Error>(())
694    /// ```
695    #[inline]
696    pub fn store<T>(&mut self, value: &T) -> Result<Ref<T, E, O>, Error>
697    where
698        T: ZeroCopy,
699    {
700        self.next_offset_with_and_reserve(align_of::<T>(), size_of::<T>())?;
701
702        // SAFETY: We're ensuring to both align the internal buffer and store
703        // the value.
704        unsafe { self.store_unchecked(value) }
705    }
706
707    /// Insert a value with the given size without ensuring that the buffer has
708    /// the reserved capacity for to or is properly aligned.
709    ///
710    /// This is a low level API which is tricky to use correctly. The
711    /// recommended way to use this is through [`OwnedBuf::store`].
712    ///
713    /// [`OwnedBuf::store`]: Self::store
714    ///
715    /// # Safety
716    ///
717    /// The caller has to ensure that the buffer has the required capacity for
718    /// `&T` and is properly aligned. This can easily be accomplished by calling
719    /// [`request_align::<T>()`] followed by [`align_in_place()`] before this
720    /// function. A safe variant of this function is [`OwnedBuf::store`].
721    ///
722    /// [`align_in_place()`]: Self::align_in_place
723    /// [`OwnedBuf::store`]: Self::store
724    /// [`request_align::<T>()`]: Self::request_align
725    ///
726    /// # Examples
727    ///
728    /// ```
729    /// use std::mem::size_of;
730    ///
731    /// use musli_zerocopy::{OwnedBuf, Ref, ZeroCopy};
732    ///
733    /// #[derive(ZeroCopy)]
734    /// #[repr(C, align(4096))]
735    /// struct Custom { field: u32, string: Ref<str> }
736    ///
737    /// let mut buf = OwnedBuf::new();
738    ///
739    /// let string = buf.store_unsized("string")?;
740    ///
741    /// buf.request_align::<Custom>()?;
742    /// buf.reserve(2 * size_of::<Custom>());
743    /// buf.align_in_place()?;
744    ///
745    /// // SAFETY: We've ensure that the buffer is internally aligned and sized just above.
746    /// let custom = unsafe { buf.store_unchecked(&Custom { field: 1, string })? };
747    /// let custom2 = unsafe { buf.store_unchecked(&Custom { field: 2, string })? };
748    ///
749    /// let custom = buf.load(custom)?;
750    /// assert_eq!(custom.field, 1);
751    /// assert_eq!(buf.load(custom.string)?, "string");
752    ///
753    /// let custom2 = buf.load(custom2)?;
754    /// assert_eq!(custom2.field, 2);
755    /// assert_eq!(buf.load(custom2.string)?, "string");
756    /// # Ok::<_, musli_zerocopy::Error>(())
757    /// ```
758    #[inline]
759    pub unsafe fn store_unchecked<T>(&mut self, value: &T) -> Result<Ref<T, E, O>, Error>
760    where
761        T: ZeroCopy,
762    {
763        let offset = self.len;
764
765        unsafe {
766            let ptr = NonNull::new_unchecked(self.data.as_ptr().add(offset));
767            buf::store_unaligned(ptr, value);
768            self.len += size_of::<T>();
769            // SAFETY: We trust the calculated offset since there language
770            // invariants ensures that it cannot overflow the container size.
771            Ok(Ref::try_with_metadata_unchecked(offset, ())?)
772        }
773    }
774
775    /// Write a value to the buffer.
776    ///
777    /// ```
778    /// use musli_zerocopy::OwnedBuf;
779    ///
780    /// let mut buf = OwnedBuf::new();
781    ///
782    /// let first = buf.store_unsized("first")?;
783    /// let second = buf.store_unsized("second")?;
784    ///
785    /// dbg!(first, second);
786    ///
787    /// assert_eq!(buf.load(first)?, "first");
788    /// assert_eq!(buf.load(second)?, "second");
789    /// # Ok::<_, musli_zerocopy::Error>(())
790    /// ```
791    #[inline]
792    pub fn store_unsized<T>(&mut self, value: &T) -> Result<Ref<T, E, O>, Error>
793    where
794        T: ?Sized + UnsizedZeroCopy,
795    {
796        unsafe {
797            let size = size_of_val(value);
798            self.next_offset_with_and_reserve(T::ALIGN, size)?;
799            let offset = self.len;
800            let ptr = NonNull::new_unchecked(self.data.as_ptr().add(offset));
801            ptr.as_ptr()
802                .copy_from_nonoverlapping(value.as_ptr().cast(), size);
803
804            if T::PADDED {
805                let mut padder = Padder::new(ptr);
806                value.pad(&mut padder);
807                padder.remaining_unsized(value);
808            }
809
810            self.len += size;
811
812            // SAFETY: We trust the calculated offset since there language
813            // invariants ensures that it cannot overflow the container size.
814            Ok(Ref::try_with_metadata_unchecked(offset, value.metadata())?)
815        }
816    }
817
818    /// Insert a slice into the buffer.
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// use musli_zerocopy::OwnedBuf;
824    ///
825    /// let mut buf = OwnedBuf::new();
826    ///
827    /// let values = [buf.store_unsized("first")?, buf.store_unsized("second")?];
828    /// let slice_ref = buf.store_slice(&values)?;
829    ///
830    /// let slice = buf.load(slice_ref)?;
831    /// assert_eq!(buf.load(slice[0])?, "first");
832    /// assert_eq!(buf.load(slice[1])?, "second");
833    /// # Ok::<_, musli_zerocopy::Error>(())
834    /// ```
835    #[inline(always)]
836    pub fn store_slice<T>(&mut self, values: &[T]) -> Result<Ref<[T], E, O>, Error>
837    where
838        T: ZeroCopy,
839    {
840        self.store_unsized(values)
841    }
842
843    /// Extend the buffer from a slice.
844    ///
845    /// Note that this only extends the underlying buffer but does not ensure
846    /// that any required alignment is abided by.
847    ///
848    /// To do this, the caller must call [`request_align()`] with the appropriate
849    /// alignment, otherwise the necessary alignment to decode the buffer again
850    /// will be lost.
851    ///
852    /// [`request_align()`]: Self::request_align
853    ///
854    /// # Errors
855    ///
856    /// This is a raw API, and does not guarantee that any given alignment will
857    /// be respected. The following exemplifies incorrect use since the u32 type
858    /// required a 4-byte alignment:
859    ///
860    /// ```
861    /// use musli_zerocopy::{OwnedBuf, Ref};
862    ///
863    /// let mut buf = OwnedBuf::with_alignment::<u32>();
864    ///
865    /// // Add one byte of padding to throw of any incidental alignment.
866    /// buf.extend_from_slice(&[1])?;
867    ///
868    /// let ptr: Ref<u32> = Ref::new(buf.next_offset::<u8>()?);
869    /// buf.extend_from_slice(&[1, 2, 3, 4])?;
870    ///
871    /// // This will succeed because the buffer follows its interior alignment:
872    /// let buf = buf.as_ref();
873    ///
874    /// // This will fail, because the buffer is not aligned.
875    /// assert!(buf.load(ptr).is_err());
876    /// # Ok::<_, musli_zerocopy::Error>(())
877    /// ```
878    ///
879    /// # Examples
880    ///
881    /// ```
882    /// use musli_zerocopy::{OwnedBuf, Ref};
883    ///
884    /// let mut buf = OwnedBuf::with_alignment::<()>();
885    ///
886    /// // Add one byte of padding to throw of any incidental alignment.
887    /// buf.extend_from_slice(&[1])?;
888    ///
889    /// let ptr: Ref<u32> = Ref::new(buf.next_offset::<u32>()?);
890    /// buf.extend_from_slice(&[1, 2, 3, 4])?;
891    ///
892    /// // This will succeed because the buffer follows its interior alignment:
893    /// let buf = buf.as_ref();
894    ///
895    /// assert_eq!(*buf.load(ptr)?, u32::from_ne_bytes([1, 2, 3, 4]));
896    /// # Ok::<_, musli_zerocopy::Error>(())
897    /// ```
898    pub fn extend_from_slice(&mut self, bytes: &[u8]) -> Result<(), AllocError> {
899        self.reserve(bytes.len())?;
900
901        // SAFETY: We just allocated space for the slice.
902        unsafe {
903            self.store_bytes(bytes);
904        }
905
906        Ok(())
907    }
908
909    /// Fill and initialize the buffer with `byte` up to `len`.
910    pub(crate) fn fill(&mut self, byte: u8, len: usize) -> Result<(), AllocError> {
911        self.reserve(len)?;
912
913        unsafe {
914            let ptr = self.data.as_ptr().add(self.len);
915            ptr.write_bytes(byte, len);
916            self.len += len;
917        }
918
919        Ok(())
920    }
921
922    /// Store the slice without allocating.
923    ///
924    /// # Safety
925    ///
926    /// The caller must ensure that the buffer has the capacity for
927    /// `bytes.len()` and that the value being stored is not padded as per
928    /// `ZeroCopy::PADDED`.
929    #[inline]
930    pub(crate) unsafe fn store_bytes<T>(&mut self, values: &[T])
931    where
932        T: ZeroCopy,
933    {
934        unsafe {
935            let dst = self.as_mut_ptr().add(self.len);
936            dst.copy_from_nonoverlapping(values.as_ptr().cast(), size_of_val(values));
937            self.len += size_of_val(values);
938        }
939    }
940
941    /// Align a buffer in place if necessary.
942    ///
943    /// If [`requested()`] does not equal [`alignment()`] this will cause the buffer
944    /// to be reallocated before it is returned.
945    ///
946    /// [`requested()`]: Self::requested
947    /// [`alignment()`]: Buf::alignment
948    /// [`as_ref`]: Self::as_ref
949    ///
950    /// # Examples
951    ///
952    /// A buffer has to be a aligned in order for `load` calls to succeed
953    /// without errors.
954    ///
955    /// ```
956    /// use musli_zerocopy::OwnedBuf;
957    ///
958    /// let mut buf = OwnedBuf::with_alignment::<()>();
959    /// let number = buf.store(&1u32)?;
960    ///
961    /// buf.align_in_place()?;
962    ///
963    /// assert_eq!(buf.load(number)?, &1u32);
964    /// # Ok::<_, musli_zerocopy::Error>(())
965    /// ```
966    ///
967    /// Example using a mutable buffer. A buffer has to be a aligned in order
968    /// for `load` and `load_mut` calls to succeed without errors.
969    ///
970    /// ```
971    /// use musli_zerocopy::OwnedBuf;
972    ///
973    /// let mut buf = OwnedBuf::with_alignment::<()>();
974    /// let number = buf.store(&1u32)?;
975    ///
976    /// buf.align_in_place()?;
977    ///
978    /// // SAFETY: We're not writing data in a way which leaves uninitialized regions.
979    /// unsafe {
980    ///     *buf.as_mut_buf().load_mut(number)? += 1;
981    /// }
982    /// assert_eq!(buf.load(number)?, &2u32);
983    /// # Ok::<_, musli_zerocopy::Error>(())
984    /// ```
985    #[inline]
986    pub fn align_in_place(&mut self) -> Result<(), AllocError> {
987        // SAFETY: self.requested is guaranteed to be a power of two.
988        if !buf::is_aligned_with(self.as_ptr(), self.requested) {
989            let (old_layout, new_layout) = self.layouts(self.capacity);
990            self.alloc_new(old_layout, new_layout)?;
991        }
992
993        Ok(())
994    }
995
996    /// Request that the current buffer should have at least the specified
997    /// alignment and zero-initialize the buffer up to the next position which
998    /// matches the given alignment.
999    ///
1000    /// Note that this does not guarantee that the internal buffer is aligned
1001    /// in-memory, to ensure this you can use [`align_in_place()`].
1002    ///
1003    /// ```
1004    /// use musli_zerocopy::OwnedBuf;
1005    /// let mut buf = OwnedBuf::new();
1006    ///
1007    /// buf.extend_from_slice(&[1, 2])?;
1008    /// buf.request_align::<u32>()?;
1009    ///
1010    /// assert_eq!(buf.as_slice(), &[1, 2, 0, 0]);
1011    /// # Ok::<_, musli_zerocopy::Error>(())
1012    /// ```
1013    ///
1014    /// Calling this function only causes the underlying buffer to be realigned
1015    /// if a reallocation is triggered due to reaching its [`capacity()`].
1016    ///
1017    /// ```
1018    /// use musli_zerocopy::{endian, OwnedBuf};
1019    /// let mut buf = OwnedBuf::<endian::Native, u32>::with_capacity_and_alignment::<u16>(32)?;
1020    ///
1021    /// buf.extend_from_slice(&[1, 2])?;
1022    /// assert!(buf.alignment() >= 2);
1023    /// buf.request_align::<u32>()?;
1024    ///
1025    /// assert_eq!(buf.requested(), 4);
1026    /// assert!(buf.alignment() >= 2);
1027    ///
1028    /// buf.extend_from_slice(&[0; 32])?;
1029    /// assert_eq!(buf.requested(), 4);
1030    /// assert!(buf.alignment() >= 4);
1031    /// # Ok::<_, musli_zerocopy::Error>(())
1032    /// ```
1033    ///
1034    /// [`capacity()`]: Self::capacity
1035    /// [`align_in_place()`]: Self::align_in_place
1036    ///
1037    /// # Safety
1038    ///
1039    /// The caller must guarantee that the alignment is a power of two.
1040    ///
1041    /// # Examples
1042    ///
1043    /// ```
1044    /// use musli_zerocopy::OwnedBuf;
1045    ///
1046    /// let mut buf = OwnedBuf::new();
1047    /// buf.extend_from_slice(&[1, 2, 3, 4])?;
1048    /// buf.request_align::<u64>()?;
1049    /// buf.extend_from_slice(&[5, 6, 7, 8])?;
1050    ///
1051    /// assert_eq!(buf.as_slice(), &[1, 2, 3, 4, 0, 0, 0, 0, 5, 6, 7, 8]);
1052    /// # Ok::<_, musli_zerocopy::Error>(())
1053    /// ```
1054    #[inline]
1055    pub fn request_align<T>(&mut self) -> Result<(), AllocError>
1056    where
1057        T: ZeroCopy,
1058    {
1059        self.requested = self.requested.max(align_of::<T>());
1060        self.ensure_aligned_and_reserve(align_of::<T>(), size_of::<T>())?;
1061        Ok(())
1062    }
1063
1064    /// Ensure that the current buffer is aligned under the assumption that it needs to be allocated.
1065    #[inline]
1066    fn ensure_aligned_and_reserve(
1067        &mut self,
1068        align: usize,
1069        reserve: usize,
1070    ) -> Result<(), AllocError> {
1071        let extra = buf::padding_to(self.len, align);
1072        self.reserve(extra + reserve)?;
1073
1074        // SAFETY: The length is ensures to be within the address space.
1075        unsafe {
1076            self.data.as_ptr().add(self.len).write_bytes(0, extra);
1077            self.len += extra;
1078        }
1079
1080        Ok(())
1081    }
1082
1083    /// Construct a pointer aligned for `align` into the current buffer which
1084    /// points to the next location that will be written.
1085    #[inline]
1086    pub(crate) fn next_offset_with_and_reserve(
1087        &mut self,
1088        align: usize,
1089        reserve: usize,
1090    ) -> Result<(), AllocError> {
1091        if !align.is_power_of_two() {
1092            return Err(AllocError::capacity(0, align));
1093        }
1094        self.requested = self.requested.max(align);
1095        self.ensure_aligned_and_reserve(align, reserve)?;
1096        Ok(())
1097    }
1098
1099    /// Construct an offset aligned for `T` into the current buffer which points
1100    /// to the next location that will be written.
1101    ///
1102    /// This ensures that the alignment of the pointer is a multiple of `align`
1103    /// and that the current buffer has the capacity for store `T`.
1104    ///
1105    /// # Examples
1106    ///
1107    /// ```
1108    /// use musli_zerocopy::{OwnedBuf, Ref};
1109    ///
1110    /// let mut buf = OwnedBuf::new();
1111    ///
1112    /// // Add one byte of padding to throw of any incidental alignment.
1113    /// buf.extend_from_slice(&[1])?;
1114    ///
1115    /// let ptr: Ref<u32> = Ref::new(buf.next_offset::<u32>()?);
1116    /// buf.extend_from_slice(&[1, 2, 3, 4])?;
1117    ///
1118    /// // This will succeed because the buffer follows its interior alignment:
1119    /// let buf = buf.as_ref();
1120    ///
1121    /// assert_eq!(*buf.load(ptr)?, u32::from_ne_bytes([1, 2, 3, 4]));
1122    /// # Ok::<_, musli_zerocopy::Error>(())
1123    /// ```
1124    #[inline]
1125    pub fn next_offset<T>(&mut self) -> Result<usize, AllocError> {
1126        // SAFETY: The alignment of `T` is guaranteed to be a power of two. We
1127        // also make sure to reserve space for `T` since it is very likely that
1128        // it will be written immediately after this.
1129        self.next_offset_with_and_reserve(align_of::<T>(), size_of::<T>())?;
1130        Ok(self.len)
1131    }
1132
1133    // We never want this call to be inlined, because we take great care to
1134    // ensure that reallocations we perform publicly are performed in a sparse
1135    // way.
1136    #[inline(never)]
1137    fn ensure_capacity(&mut self, new_capacity: usize) -> Result<(), AllocError> {
1138        let new_capacity = new_capacity.max(self.requested);
1139
1140        if self.capacity >= new_capacity {
1141            return Ok(());
1142        }
1143
1144        let new_capacity = new_capacity.max((self.capacity as f32 * 1.5) as usize);
1145        let (old_layout, new_layout) = self.layouts(new_capacity);
1146
1147        if old_layout.size() == 0 {
1148            self.alloc_init(new_layout)
1149        } else if new_layout.align() == old_layout.align() {
1150            self.alloc_realloc(old_layout, new_layout)
1151        } else {
1152            self.alloc_new(old_layout, new_layout)
1153        }
1154    }
1155
1156    /// Return a pair of the currently allocated layout, and new layout that is
1157    /// requested with the given capacity.
1158    #[inline]
1159    fn layouts(&self, new_capacity: usize) -> (Layout, Layout) {
1160        // SAFETY: The existing layout cannot be invalid since it's either
1161        // checked as it's replacing the old layout, or is initialized with
1162        // known good values.
1163        let old_layout = unsafe { Layout::from_size_align_unchecked(self.capacity, self.align) };
1164        let layout =
1165            Layout::from_size_align(new_capacity, self.requested).expect("Proposed layout invalid");
1166        (old_layout, layout)
1167    }
1168
1169    /// Perform the initial allocation with the given layout and capacity.
1170    fn alloc_init(&mut self, new_layout: Layout) -> Result<(), AllocError> {
1171        unsafe {
1172            let ptr = alloc::alloc(new_layout);
1173
1174            if ptr.is_null() {
1175                return Err(AllocError::alloc_error(new_layout));
1176            }
1177
1178            self.data = NonNull::new_unchecked(ptr.cast());
1179            self.capacity = new_layout.size();
1180            self.align = self.requested;
1181            Ok(())
1182        }
1183    }
1184
1185    /// Reallocate, note that the alignment of the old layout must match the new
1186    /// one.
1187    fn alloc_realloc(&mut self, old_layout: Layout, new_layout: Layout) -> Result<(), AllocError> {
1188        debug_assert_eq!(old_layout.align(), new_layout.align());
1189
1190        unsafe {
1191            let ptr = alloc::realloc(self.as_mut_ptr().cast(), old_layout, new_layout.size());
1192
1193            if ptr.is_null() {
1194                return Err(AllocError::alloc_error(new_layout));
1195            }
1196
1197            // NB: We may simply forget the old allocation, since `realloc` is
1198            // responsible for freeing it.
1199            self.data = NonNull::new_unchecked(ptr.cast());
1200            self.capacity = new_layout.size();
1201            Ok(())
1202        }
1203    }
1204
1205    /// Perform a new allocation, deallocating the old one in the process.
1206    #[inline(always)]
1207    fn alloc_new(&mut self, old_layout: Layout, new_layout: Layout) -> Result<(), AllocError> {
1208        unsafe {
1209            let ptr = alloc::alloc(new_layout);
1210
1211            if ptr.is_null() {
1212                return Err(AllocError::alloc_error(new_layout));
1213            }
1214
1215            ptr.copy_from_nonoverlapping(self.as_ptr(), self.len);
1216            alloc::dealloc(self.as_mut_ptr().cast(), old_layout);
1217
1218            // We've deallocated the old pointer.
1219            self.data = NonNull::new_unchecked(ptr.cast());
1220            self.capacity = new_layout.size();
1221            self.align = self.requested;
1222            Ok(())
1223        }
1224    }
1225}
1226
1227/// `OwnedBuf` are `Send` because the data they reference is unaliased.
1228unsafe impl Send for OwnedBuf {}
1229/// `OwnedBuf` are `Sync` since they are `Send` and the data they reference is
1230/// unaliased.
1231unsafe impl Sync for OwnedBuf {}
1232
1233impl<E, O> Deref for OwnedBuf<E, O>
1234where
1235    E: ByteOrder,
1236    O: Size,
1237{
1238    type Target = Buf;
1239
1240    #[inline]
1241    fn deref(&self) -> &Self::Target {
1242        Buf::new(self.as_slice())
1243    }
1244}
1245
1246impl<E, O> AsRef<Buf> for OwnedBuf<E, O>
1247where
1248    E: ByteOrder,
1249    O: Size,
1250{
1251    /// Trivial `AsRef<Buf>` implementation for `OwnedBuf<O>`.
1252    ///
1253    /// # Examples
1254    ///
1255    /// ```
1256    /// use musli_zerocopy::OwnedBuf;
1257    ///
1258    /// let mut buf = OwnedBuf::new();
1259    /// let slice = buf.store_unsized("hello world")?;
1260    /// let buf = buf.as_ref();
1261    ///
1262    /// assert_eq!(buf.load(slice)?, "hello world");
1263    /// # Ok::<_, musli_zerocopy::Error>(())
1264    /// ```
1265    #[inline]
1266    fn as_ref(&self) -> &Buf {
1267        self
1268    }
1269}
1270
1271impl<E, O> Borrow<Buf> for OwnedBuf<E, O>
1272where
1273    E: ByteOrder,
1274    O: Size,
1275{
1276    #[inline]
1277    fn borrow(&self) -> &Buf {
1278        self.as_ref()
1279    }
1280}
1281
1282/// Clone the [`OwnedBuf`].
1283///
1284/// While this causes another allocation, it doesn't ensure that the returned
1285/// buffer has the [`requested()`] alignment. To achieve this prefer using
1286/// [`align_in_place()`].
1287///
1288/// [`requested()`]: Self::requested()
1289/// [`align_in_place()`]: Self::align_in_place
1290///
1291/// # Examples
1292///
1293/// ```
1294/// use std::mem::align_of;
1295///
1296/// use musli_zerocopy::{endian, OwnedBuf};
1297///
1298/// assert_ne!(align_of::<u16>(), align_of::<u32>());
1299///
1300/// let mut buf = OwnedBuf::<endian::Native, u32>::with_capacity_and_alignment::<u16>(32)?;
1301/// buf.extend_from_slice(&[1, 2, 3, 4])?;
1302/// buf.request_align::<u32>()?;
1303///
1304/// let buf2 = buf.clone();
1305/// assert!(buf2.alignment() >= align_of::<u16>());
1306///
1307/// buf.align_in_place()?;
1308/// assert!(buf.alignment() >= align_of::<u32>());
1309/// # Ok::<_, musli_zerocopy::Error>(())
1310/// ```
1311impl<E, O> Clone for OwnedBuf<E, O>
1312where
1313    E: ByteOrder,
1314    O: Size,
1315{
1316    fn clone(&self) -> Self {
1317        unsafe {
1318            let result = Self::with_capacity_and_custom_alignment(self.len, self.align);
1319
1320            let mut new = match result {
1321                Ok(new) => ManuallyDrop::new(new),
1322                Err(_) => alloc::handle_alloc_error(Layout::from_size_align_unchecked(
1323                    self.len, self.align,
1324                )),
1325            };
1326
1327            new.as_mut_ptr()
1328                .copy_from_nonoverlapping(self.as_ptr().cast(), self.len);
1329            // Set requested to the same as original.
1330            new.requested = self.requested;
1331            new.len = self.len;
1332            ManuallyDrop::into_inner(new)
1333        }
1334    }
1335}
1336
1337impl<E, O> Drop for OwnedBuf<E, O>
1338where
1339    E: ByteOrder,
1340    O: Size,
1341{
1342    fn drop(&mut self) {
1343        unsafe {
1344            if self.capacity != 0 {
1345                // SAFETY: This is guaranteed to be valid per the construction
1346                // of this type.
1347                let layout = Layout::from_size_align_unchecked(self.capacity, self.align);
1348                alloc::dealloc(self.data.as_ptr().cast(), layout);
1349            }
1350        }
1351    }
1352}
1353
1354const unsafe fn dangling(align: usize) -> NonNull<MaybeUninit<u8>> {
1355    unsafe { NonNull::new_unchecked(invalid_mut(align)) }
1356}
1357
1358// Replace with `core::ptr::invalid_mut` once stable.
1359#[allow(clippy::useless_transmute)]
1360const fn invalid_mut<T>(addr: usize) -> *mut T {
1361    // FIXME(strict_provenance_magic): I am magic and should be a compiler
1362    // intrinsic. We use transmute rather than a cast so tools like Miri can
1363    // tell that this is *not* the same as from_exposed_addr. SAFETY: every
1364    // valid integer is also a valid pointer (as long as you don't dereference
1365    // that pointer).
1366    unsafe { core::mem::transmute(addr) }
1367}
1368
1369impl<E, O> StoreBuf for OwnedBuf<E, O>
1370where
1371    E: ByteOrder,
1372    O: Size,
1373{
1374    type ByteOrder = E;
1375    type Size = O;
1376
1377    #[inline]
1378    fn len(&self) -> usize {
1379        OwnedBuf::len(self)
1380    }
1381
1382    #[inline]
1383    fn truncate(&mut self, len: usize) {
1384        if self.len > len {
1385            self.len = len;
1386        }
1387    }
1388
1389    #[inline]
1390    fn store_unsized<T>(&mut self, value: &T) -> Result<Ref<T, Self::ByteOrder, Self::Size>, Error>
1391    where
1392        T: ?Sized + UnsizedZeroCopy,
1393    {
1394        OwnedBuf::store_unsized(self, value)
1395    }
1396
1397    #[inline]
1398    fn store<T>(&mut self, value: &T) -> Result<Ref<T, Self::ByteOrder, Self::Size>, Error>
1399    where
1400        T: ZeroCopy,
1401    {
1402        OwnedBuf::store(self, value)
1403    }
1404
1405    #[inline]
1406    fn swap<T>(
1407        &mut self,
1408        a: Ref<T, Self::ByteOrder, Self::Size>,
1409        b: Ref<T, Self::ByteOrder, Self::Size>,
1410    ) -> Result<(), Error>
1411    where
1412        T: ZeroCopy,
1413    {
1414        // SAFETY: Since we are swapping two locations which have the same type
1415        // `T`, it does not affect the initialized state of the buffer.
1416        let buf = unsafe { self.as_mut_buf() };
1417        Buf::swap(buf, a, b)
1418    }
1419
1420    #[inline]
1421    fn align_in_place(&mut self) -> Result<(), AllocError> {
1422        OwnedBuf::align_in_place(self)
1423    }
1424
1425    #[inline]
1426    fn next_offset<T>(&mut self) -> Result<usize, AllocError> {
1427        OwnedBuf::next_offset::<T>(self)
1428    }
1429
1430    #[inline]
1431    fn next_offset_with_and_reserve(
1432        &mut self,
1433        align: usize,
1434        reserve: usize,
1435    ) -> Result<(), AllocError> {
1436        OwnedBuf::next_offset_with_and_reserve(self, align, reserve)
1437    }
1438
1439    #[inline]
1440    fn fill(&mut self, byte: u8, len: usize) -> Result<(), AllocError> {
1441        OwnedBuf::fill(self, byte, len)
1442    }
1443
1444    #[inline]
1445    fn get<I>(&self, index: I) -> Option<&I::Output>
1446    where
1447        I: SliceIndex<[u8]>,
1448    {
1449        Buf::get(self, index)
1450    }
1451
1452    #[inline]
1453    unsafe fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
1454    where
1455        I: SliceIndex<[u8]>,
1456    {
1457        unsafe { OwnedBuf::as_mut_buf(self).get_mut(index) }
1458    }
1459
1460    #[inline]
1461    fn as_buf(&self) -> &Buf {
1462        self
1463    }
1464
1465    #[inline]
1466    unsafe fn as_mut_buf(&mut self) -> &mut Buf {
1467        unsafe { OwnedBuf::as_mut_buf(self) }
1468    }
1469}
1470
1471#[cfg(feature = "std")]
1472#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
1473impl io::Write for OwnedBuf {
1474    #[inline]
1475    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1476        self.extend_from_slice(buf).map_err(io::Error::other)?;
1477        Ok(buf.len())
1478    }
1479
1480    #[inline]
1481    fn flush(&mut self) -> io::Result<()> {
1482        Ok(())
1483    }
1484}