|
| 1 | +// SPDX-License-Identifier: MIT OR Apache-2.0 |
| 2 | + |
| 3 | +use alloc::alloc::{alloc, dealloc, Layout, LayoutError}; |
| 4 | + |
| 5 | +/// Helper class to maintain the lifetime of a memory region allocated with a non-standard alignment. |
| 6 | +/// Facilitates RAII to properly deallocate when lifetime of the object ends. |
| 7 | +#[allow(clippy::len_without_is_empty)] |
| 8 | +#[derive(Debug)] |
| 9 | +pub struct AlignedBuffer { |
| 10 | + ptr: *mut u8, |
| 11 | + layout: Layout, |
| 12 | +} |
| 13 | +impl AlignedBuffer { |
| 14 | + /// Allocate a new memory region with the requested len and alignment. |
| 15 | + pub fn alloc(len: usize, alignment: usize) -> Result<Self, LayoutError> { |
| 16 | + let layout = Layout::from_size_align(len, alignment)?; |
| 17 | + let ptr = unsafe { alloc(layout) }; |
| 18 | + Ok(Self { ptr, layout }) |
| 19 | + } |
| 20 | + /// Get a pointer to the aligned memory region managed by this instance. |
| 21 | + #[must_use] |
| 22 | + pub const fn ptr(&self) -> *const u8 { |
| 23 | + self.ptr as *const u8 |
| 24 | + } |
| 25 | + /// Get a mutable pointer to the aligned memory region managed by this instance. |
| 26 | + #[must_use] |
| 27 | + pub fn ptr_mut(&mut self) -> *mut u8 { |
| 28 | + self.ptr |
| 29 | + } |
| 30 | + /// Get the size of the aligned memory region managed by this instance. |
| 31 | + #[must_use] |
| 32 | + pub const fn len(&self) -> usize { |
| 33 | + self.layout.size() |
| 34 | + } |
| 35 | + /// Fill the aligned memory region with data from the given buffer. |
| 36 | + pub fn copy_from(&mut self, data: &[u8]) { |
| 37 | + let len = data.len().min(self.len()); |
| 38 | + unsafe { |
| 39 | + self.ptr.copy_from(data.as_ptr(), len); |
| 40 | + } |
| 41 | + } |
| 42 | +} |
| 43 | +impl Drop for AlignedBuffer { |
| 44 | + fn drop(&mut self) { |
| 45 | + unsafe { |
| 46 | + dealloc(self.ptr, self.layout); |
| 47 | + } |
| 48 | + } |
| 49 | +} |
0 commit comments