22
33use alloc:: alloc:: { Layout , LayoutError , alloc, dealloc} ;
44use core:: error:: Error ;
5- use core:: fmt;
65use core:: ptr:: NonNull ;
6+ use core:: { fmt, slice} ;
77
88/// Helper class to maintain the lifetime of a memory region allocated with a non-standard alignment.
99/// Facilitates RAII to properly deallocate when lifetime of the object ends.
@@ -51,12 +51,34 @@ impl AlignedBuffer {
5151 self . ptr . as_ptr ( )
5252 }
5353
54+ /// Get the underlying memory region as immutable slice.
55+ #[ must_use]
56+ pub const fn as_slice ( & self ) -> & [ u8 ] {
57+ unsafe { slice:: from_raw_parts ( self . ptr ( ) , self . size ( ) ) }
58+ }
59+
60+ /// Get the underlying memory region as mutable slice.
61+ #[ must_use]
62+ pub const fn as_slice_mut ( & mut self ) -> & mut [ u8 ] {
63+ unsafe { slice:: from_raw_parts_mut ( self . ptr_mut ( ) , self . size ( ) ) }
64+ }
65+
5466 /// Get the size of the aligned memory region managed by this instance.
5567 #[ must_use]
5668 pub const fn size ( & self ) -> usize {
5769 self . layout . size ( )
5870 }
5971
72+ /// Returns an iterator over the aligned buffer contents.
73+ pub fn iter ( & self ) -> impl Iterator < Item = & u8 > {
74+ self . as_slice ( ) . iter ( )
75+ }
76+
77+ /// Returns a mutable iterator over the aligned buffer contents.
78+ pub fn iter_mut ( & mut self ) -> impl Iterator < Item = & mut u8 > {
79+ self . as_slice_mut ( ) . iter_mut ( )
80+ }
81+
6082 /// Fill the aligned memory region with data from the given buffer.
6183 ///
6284 /// The length of `src` must be the same as `self`.
@@ -67,6 +89,14 @@ impl AlignedBuffer {
6789 }
6890 }
6991
92+ /// Fill the aligned memory region with data from the given iterator.
93+ /// If the given iterator is shorter than the buffer, the remaining area will be left untouched.
94+ pub fn copy_from_iter ( & mut self , src : impl Iterator < Item = u8 > ) {
95+ self . iter_mut ( )
96+ . zip ( src)
97+ . for_each ( |( dst, src_byte) | * dst = src_byte) ;
98+ }
99+
70100 /// Check the buffer's alignment against the `required_alignment`.
71101 pub fn check_alignment ( & self , required_alignment : usize ) -> Result < ( ) , AlignmentError > {
72102 //TODO: use bfr.addr() when it's available
@@ -120,4 +150,28 @@ mod tests {
120150 }
121151 }
122152 }
153+
154+ #[ test]
155+ fn test_copy_from_iter ( ) {
156+ let src8: [ u8 ; 8 ] = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
157+ {
158+ // src as large as dst
159+ let mut bfr = AlignedBuffer :: from_size_align ( 8 , 8 ) . unwrap ( ) ;
160+ bfr. copy_from_iter ( src8. iter ( ) . cloned ( ) ) ;
161+ assert_eq ! ( bfr. as_slice( ) , src8) ;
162+ }
163+ {
164+ // src larger than dst
165+ let mut bfr = AlignedBuffer :: from_size_align ( 7 , 8 ) . unwrap ( ) ;
166+ bfr. copy_from_iter ( src8. iter ( ) . cloned ( ) ) ;
167+ assert_eq ! ( bfr. as_slice( ) , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
168+ }
169+ {
170+ // src smaller than dst
171+ let mut bfr = AlignedBuffer :: from_size_align ( 9 , 8 ) . unwrap ( ) ;
172+ bfr. iter_mut ( ) . for_each ( |dst| * dst = 0 ) ; // fill with 0s
173+ bfr. copy_from_iter ( src8. iter ( ) . cloned ( ) ) ;
174+ assert_eq ! ( bfr. as_slice( ) , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 0 ] ) ;
175+ }
176+ }
123177}
0 commit comments