#[repr(C, align(8))]pub struct AlignedBuffer<T, const SIZE: usize>where
T: ValueType,{ /* private fields */ }Expand description
A highly optimized, aligned buffer for system call operations
This buffer provides memory-aligned storage with several key features:
- Guaranteed 8-byte alignment required by various system calls
- Zero-cost abstraction for working with raw memory
- Support for both i8 and u8 types (equivalent for byte operations)
- Safe access methods with proper bounds checking
- Lazy initialisation to avoid unnecessary memory writes
§Type Parameters
T: The element type (i8 or u8)SIZE: The fixed capacity of the buffer
§Safety
The buffer uses MaybeUninit internally, so users must ensure proper
initialisation before accessing the contents. All unsafe methods document
their safety requirements.
§Examples
use fdf::AlignedBuffer;
// Create a new aligned buffer
// Purposely set a non-aligned amount to show alignment is forced.
let mut buffer = AlignedBuffer::<u8, 1026>::new(); //You should really use 1024 here.
// Initialise the buffer with data
let data = b"Hello, World!";
unsafe {
// Copy data into the buffer
core::ptr::copy_nonoverlapping(
data.as_ptr(),
buffer.as_mut_ptr(),
data.len()
);
// Access the initialised data
let slice = buffer.get_unchecked(0..data.len());
assert_eq!(slice, data);
// Modify the buffer contents
let mut_slice = buffer.get_unchecked_mut(0..data.len());
mut_slice[0] = b'h'; // Change 'H' to 'h'
assert_eq!(&mut_slice[0..5], b"hello");
}
// The buffer maintains proper alignment for syscalls
//Protip: NEVER cast a ptr to a usize unless you're extremely sure of what you're doing!
assert!((buffer.as_ptr() as usize).is_multiple_of(8),"We expect the buffer to be aligned to 8 bytes")Implementations§
Source§impl<T, const SIZE: usize> AlignedBuffer<T, SIZE>where
T: ValueType,
impl<T, const SIZE: usize> AlignedBuffer<T, SIZE>where
T: ValueType,
pub const fn new() -> Self
pub const fn as_mut_ptr(&mut self) -> *mut T
pub const fn as_ptr(&self) -> *const T
Sourcepub const unsafe fn as_slice(&self) -> &[T]
pub const unsafe fn as_slice(&self) -> &[T]
§Safety
The buffer must be initialised before calling this
Sourcepub const unsafe fn as_mut_slice(&mut self) -> &mut [T]
pub const unsafe fn as_mut_slice(&mut self) -> &mut [T]
§Safety
The buffer must be initialised before calling this
Sourcepub unsafe fn getdents(&mut self, fd: i32) -> i64
pub unsafe fn getdents(&mut self, fd: i32) -> i64
Executes the getdents64 system call using inline assembly
This method bypasses libc to directly invoke the getdents64 system call, which is necessary to avoid certain libc quirks and limitations.
§Safety
This method uses inline assembly and directly interacts with the kernel. The caller must ensure:
- The file descriptor is valid and open for reading
- The buffer is properly aligned and sized
- Proper error handling is implemented
§Platform Specificity
This implementation is specific to Linux on supported architectures (currently x86 and aarch64) Otherwise backing up to libc
Sourcepub unsafe fn get_unchecked<R>(&self, range: R) -> &R::Outputwhere
R: SliceIndex<[T]>,
pub unsafe fn get_unchecked<R>(&self, range: R) -> &R::Outputwhere
R: SliceIndex<[T]>,
Returns a reference to a subslice without doing bounds checking
§Safety
The caller must ensure the range is within the initialised portion of the buffer. Accessing out-of-bounds or uninitialised memory is undefined behavior.
Sourcepub unsafe fn get_unchecked_mut<R>(&mut self, range: R) -> &mut R::Outputwhere
R: SliceIndex<[T]>,
pub unsafe fn get_unchecked_mut<R>(&mut self, range: R) -> &mut R::Outputwhere
R: SliceIndex<[T]>,
§Safety
The range must be within initialised portion of the buffer
Trait Implementations§
Source§impl<T, const SIZE: usize> Debug for AlignedBuffer<T, SIZE>
impl<T, const SIZE: usize> Debug for AlignedBuffer<T, SIZE>
Source§impl<T, const SIZE: usize, Idx> Index<Idx> for AlignedBuffer<T, SIZE>
impl<T, const SIZE: usize, Idx> Index<Idx> for AlignedBuffer<T, SIZE>
Auto Trait Implementations§
impl<T, const SIZE: usize> Freeze for AlignedBuffer<T, SIZE>where
T: Freeze,
impl<T, const SIZE: usize> RefUnwindSafe for AlignedBuffer<T, SIZE>where
T: RefUnwindSafe,
impl<T, const SIZE: usize> Send for AlignedBuffer<T, SIZE>where
T: Send,
impl<T, const SIZE: usize> Sync for AlignedBuffer<T, SIZE>where
T: Sync,
impl<T, const SIZE: usize> Unpin for AlignedBuffer<T, SIZE>where
T: Unpin,
impl<T, const SIZE: usize> UnwindSafe for AlignedBuffer<T, SIZE>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more