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