1+ // SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+ use core:: { error:: Error , fmt} ;
4+
5+ use alloc:: alloc:: { alloc, dealloc, Layout , LayoutError } ;
6+
7+ /// Helper class to maintain the lifetime of a memory region allocated with a non-standard alignment.
8+ /// Facilitates RAII to properly deallocate when lifetime of the object ends.
9+ ///
10+ /// Note: This uses the global Rust allocator under the hood.
11+ #[ allow( clippy:: len_without_is_empty) ]
12+ #[ derive( Debug ) ]
13+ pub struct AlignedBuffer {
14+ ptr : * mut u8 ,
15+ layout : Layout ,
16+ }
17+ impl AlignedBuffer {
18+ /// Allocate a new memory region with the requested len and alignment.
19+ pub fn alloc ( len : usize , alignment : usize ) -> Result < Self , LayoutError > {
20+ let layout = Layout :: from_size_align ( len, alignment) ?;
21+ let ptr = unsafe { alloc ( layout) } ;
22+ Ok ( Self { ptr, layout } )
23+ }
24+ /// Get a pointer to the aligned memory region managed by this instance.
25+ #[ must_use]
26+ pub const fn ptr ( & self ) -> * const u8 {
27+ self . ptr as * const u8
28+ }
29+ /// Get a mutable pointer to the aligned memory region managed by this instance.
30+ #[ must_use]
31+ pub fn ptr_mut ( & mut self ) -> * mut u8 {
32+ self . ptr
33+ }
34+ /// Get the size of the aligned memory region managed by this instance.
35+ #[ must_use]
36+ pub const fn len ( & self ) -> usize {
37+ self . layout . size ( )
38+ }
39+ /// Fill the aligned memory region with data from the given buffer.
40+ pub fn copy_from ( & mut self , data : & [ u8 ] ) {
41+ let len = data. len ( ) . min ( self . len ( ) ) ;
42+ unsafe {
43+ self . ptr . copy_from ( data. as_ptr ( ) , len) ;
44+ }
45+ }
46+ }
47+ impl Drop for AlignedBuffer {
48+ fn drop ( & mut self ) {
49+ unsafe {
50+ dealloc ( self . ptr , self . layout ) ;
51+ }
52+ }
53+ }
54+
55+
56+
57+ /// The `AlignmentError` is returned if a user-provided buffer doesn't fulfill alignment requirements.
58+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
59+ pub struct AlignmentError ;
60+ impl Error for AlignmentError { }
61+ impl fmt:: Display for AlignmentError {
62+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
63+ f. write_str ( "invalid parameters to Layout::from_size_align" )
64+ }
65+ }
0 commit comments