xref: /aosp_15_r20/bootable/libbootloader/gbl/libgbl/src/image_buffer.rs (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2024, The Android Open Source Project
2*5225e6b1SAndroid Build Coastguard Worker //
3*5225e6b1SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*5225e6b1SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*5225e6b1SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*5225e6b1SAndroid Build Coastguard Worker //
7*5225e6b1SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*5225e6b1SAndroid Build Coastguard Worker //
9*5225e6b1SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*5225e6b1SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*5225e6b1SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5225e6b1SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*5225e6b1SAndroid Build Coastguard Worker // limitations under the License.
14*5225e6b1SAndroid Build Coastguard Worker 
15*5225e6b1SAndroid Build Coastguard Worker //! ImageBuffer is helper to store uninitialized memory buffer. And work with it allowing to read
16*5225e6b1SAndroid Build Coastguard Worker //! into the buffer and retrieve initialized part.
17*5225e6b1SAndroid Build Coastguard Worker //!
18*5225e6b1SAndroid Build Coastguard Worker //! Similar to [ReadBuf](https://docs.rs/tokio/latest/tokio/io/struct.ReadBuf.html) but works in
19*5225e6b1SAndroid Build Coastguard Worker //! `no_std`.
20*5225e6b1SAndroid Build Coastguard Worker 
21*5225e6b1SAndroid Build Coastguard Worker use core::mem::MaybeUninit;
22*5225e6b1SAndroid Build Coastguard Worker use liberror::{Error, Result};
23*5225e6b1SAndroid Build Coastguard Worker 
24*5225e6b1SAndroid Build Coastguard Worker /// Wrapper class for buffer received with [get_buffer] function.
25*5225e6b1SAndroid Build Coastguard Worker ///
26*5225e6b1SAndroid Build Coastguard Worker /// Helps to keep track of allocated/init memory and avoid getting same buffer more than once.
27*5225e6b1SAndroid Build Coastguard Worker #[derive(Debug)]
28*5225e6b1SAndroid Build Coastguard Worker pub struct ImageBuffer<'a> {
29*5225e6b1SAndroid Build Coastguard Worker     buffer: Option<&'a mut [MaybeUninit<u8>]>,
30*5225e6b1SAndroid Build Coastguard Worker     // number of initialized and filled bytes.
31*5225e6b1SAndroid Build Coastguard Worker     used_bytes: usize,
32*5225e6b1SAndroid Build Coastguard Worker }
33*5225e6b1SAndroid Build Coastguard Worker 
34*5225e6b1SAndroid Build Coastguard Worker // Unstable MaybeUninit API
35*5225e6b1SAndroid Build Coastguard Worker // feature = "maybe_uninit_slice", issue = "63569"
36*5225e6b1SAndroid Build Coastguard Worker 
37*5225e6b1SAndroid Build Coastguard Worker // Assuming all the elements are initialized, get a mutable slice to them.
38*5225e6b1SAndroid Build Coastguard Worker //
39*5225e6b1SAndroid Build Coastguard Worker // # Safety
40*5225e6b1SAndroid Build Coastguard Worker //
41*5225e6b1SAndroid Build Coastguard Worker // It is up to the caller to guarantee that the `MaybeUninit<T>` elements
42*5225e6b1SAndroid Build Coastguard Worker // really are in an initialized state.
43*5225e6b1SAndroid Build Coastguard Worker // Calling this when the content is not yet fully initialized causes undefined behavior.
44*5225e6b1SAndroid Build Coastguard Worker #[inline(always)]
slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T]45*5225e6b1SAndroid Build Coastguard Worker unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
46*5225e6b1SAndroid Build Coastguard Worker     // SAFETY: Caller must make sure provided data is initialized.
47*5225e6b1SAndroid Build Coastguard Worker     unsafe { &mut *(slice as *mut [MaybeUninit<T>] as *mut [T]) }
48*5225e6b1SAndroid Build Coastguard Worker }
49*5225e6b1SAndroid Build Coastguard Worker 
50*5225e6b1SAndroid Build Coastguard Worker // Assuming all the elements are initialized, get a slice of them.
51*5225e6b1SAndroid Build Coastguard Worker //
52*5225e6b1SAndroid Build Coastguard Worker // # Safety
53*5225e6b1SAndroid Build Coastguard Worker //
54*5225e6b1SAndroid Build Coastguard Worker // It is up to the caller to guarantee that the `MaybeUninit<T>` elements
55*5225e6b1SAndroid Build Coastguard Worker // really are in an initialized state.
56*5225e6b1SAndroid Build Coastguard Worker // Calling this when the content is not yet fully initialized causes undefined behavior.
57*5225e6b1SAndroid Build Coastguard Worker #[inline(always)]
slice_assume_init_ref<T>(slice: &[MaybeUninit<T>]) -> &[T]58*5225e6b1SAndroid Build Coastguard Worker unsafe fn slice_assume_init_ref<T>(slice: &[MaybeUninit<T>]) -> &[T] {
59*5225e6b1SAndroid Build Coastguard Worker     // SAFETY: Caller must make sure provided data is initialized.
60*5225e6b1SAndroid Build Coastguard Worker     unsafe { &*(slice as *const [MaybeUninit<T>] as *const [T]) }
61*5225e6b1SAndroid Build Coastguard Worker }
62*5225e6b1SAndroid Build Coastguard Worker 
63*5225e6b1SAndroid Build Coastguard Worker impl ImageBuffer<'_> {
64*5225e6b1SAndroid Build Coastguard Worker     /// Create new ImageBuffer from buffer and used_bytes
new(buffer: &mut [MaybeUninit<u8>]) -> ImageBuffer65*5225e6b1SAndroid Build Coastguard Worker     pub fn new(buffer: &mut [MaybeUninit<u8>]) -> ImageBuffer {
66*5225e6b1SAndroid Build Coastguard Worker         ImageBuffer { buffer: Some(buffer), used_bytes: 0 }
67*5225e6b1SAndroid Build Coastguard Worker     }
68*5225e6b1SAndroid Build Coastguard Worker 
69*5225e6b1SAndroid Build Coastguard Worker     /// Total buffer capacity.
capacity(&self) -> usize70*5225e6b1SAndroid Build Coastguard Worker     pub fn capacity(&self) -> usize {
71*5225e6b1SAndroid Build Coastguard Worker         self.buffer.as_ref().unwrap().len()
72*5225e6b1SAndroid Build Coastguard Worker     }
73*5225e6b1SAndroid Build Coastguard Worker 
74*5225e6b1SAndroid Build Coastguard Worker     /// Increase used part of the buffer by `len`
75*5225e6b1SAndroid Build Coastguard Worker     ///
76*5225e6b1SAndroid Build Coastguard Worker     /// Return:
77*5225e6b1SAndroid Build Coastguard Worker     /// Error() - if current used_bytes + len > capacity, or causes arithmetic overflow.
78*5225e6b1SAndroid Build Coastguard Worker     /// Ok(()) - on success
79*5225e6b1SAndroid Build Coastguard Worker     ///
80*5225e6b1SAndroid Build Coastguard Worker     /// SAFETY:
81*5225e6b1SAndroid Build Coastguard Worker     /// It is up to the user to guarantee that `len` bytes for tail was initialized and filled.
advance_used(&mut self, len: usize) -> Result<()>82*5225e6b1SAndroid Build Coastguard Worker     pub unsafe fn advance_used(&mut self, len: usize) -> Result<()> {
83*5225e6b1SAndroid Build Coastguard Worker         let Some(new_len) = self.used_bytes.checked_add(len) else {
84*5225e6b1SAndroid Build Coastguard Worker             return Err(Error::Other(Some("Used bytes overflow")));
85*5225e6b1SAndroid Build Coastguard Worker         };
86*5225e6b1SAndroid Build Coastguard Worker         if new_len > self.capacity() {
87*5225e6b1SAndroid Build Coastguard Worker             return Err(Error::BufferTooSmall(Some(new_len)));
88*5225e6b1SAndroid Build Coastguard Worker         }
89*5225e6b1SAndroid Build Coastguard Worker         self.used_bytes = new_len;
90*5225e6b1SAndroid Build Coastguard Worker         Ok(())
91*5225e6b1SAndroid Build Coastguard Worker     }
92*5225e6b1SAndroid Build Coastguard Worker 
93*5225e6b1SAndroid Build Coastguard Worker     /// Return used and tail parts of the buffer
get_split(&self) -> (&[u8], &[MaybeUninit<u8>])94*5225e6b1SAndroid Build Coastguard Worker     pub fn get_split(&self) -> (&[u8], &[MaybeUninit<u8>]) {
95*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = self.buffer.as_ref().unwrap().split_at(self.used_bytes);
96*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
97*5225e6b1SAndroid Build Coastguard Worker         //
98*5225e6b1SAndroid Build Coastguard Worker         // ImageBuffer user guarantees that changing used elements means they were initialized.
99*5225e6b1SAndroid Build Coastguard Worker         // And object assumes initialized only for slice [..used_bytes]
100*5225e6b1SAndroid Build Coastguard Worker         let initialized = unsafe { slice_assume_init_ref(used) };
101*5225e6b1SAndroid Build Coastguard Worker         (initialized, tail)
102*5225e6b1SAndroid Build Coastguard Worker     }
103*5225e6b1SAndroid Build Coastguard Worker 
104*5225e6b1SAndroid Build Coastguard Worker     /// Return used and tail parts of the buffer
get_split_mut(&mut self) -> (&mut [u8], &mut [MaybeUninit<u8>])105*5225e6b1SAndroid Build Coastguard Worker     pub fn get_split_mut(&mut self) -> (&mut [u8], &mut [MaybeUninit<u8>]) {
106*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = self.buffer.as_mut().unwrap().split_at_mut(self.used_bytes);
107*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
108*5225e6b1SAndroid Build Coastguard Worker         //
109*5225e6b1SAndroid Build Coastguard Worker         // ImageBuffer user guaranties that changing used elements means they were initialized.
110*5225e6b1SAndroid Build Coastguard Worker         // And object assumes initialized only for slice [..used_bytes]
111*5225e6b1SAndroid Build Coastguard Worker         let initialized = unsafe { slice_assume_init_mut(used) };
112*5225e6b1SAndroid Build Coastguard Worker         (initialized, tail)
113*5225e6b1SAndroid Build Coastguard Worker     }
114*5225e6b1SAndroid Build Coastguard Worker 
115*5225e6b1SAndroid Build Coastguard Worker     /// Slice of the buffer that is used
used(&self) -> &[u8]116*5225e6b1SAndroid Build Coastguard Worker     pub fn used(&self) -> &[u8] {
117*5225e6b1SAndroid Build Coastguard Worker         let (used, _) = self.get_split();
118*5225e6b1SAndroid Build Coastguard Worker         used
119*5225e6b1SAndroid Build Coastguard Worker     }
120*5225e6b1SAndroid Build Coastguard Worker 
121*5225e6b1SAndroid Build Coastguard Worker     /// Slice of the buffer that is used
used_mut(&mut self) -> &mut [u8]122*5225e6b1SAndroid Build Coastguard Worker     pub fn used_mut(&mut self) -> &mut [u8] {
123*5225e6b1SAndroid Build Coastguard Worker         let (used, _) = self.get_split_mut();
124*5225e6b1SAndroid Build Coastguard Worker         used
125*5225e6b1SAndroid Build Coastguard Worker     }
126*5225e6b1SAndroid Build Coastguard Worker 
127*5225e6b1SAndroid Build Coastguard Worker     /// Return part of the buffer that is not used
tail(&mut self) -> &mut [MaybeUninit<u8>]128*5225e6b1SAndroid Build Coastguard Worker     pub fn tail(&mut self) -> &mut [MaybeUninit<u8>] {
129*5225e6b1SAndroid Build Coastguard Worker         let (_, tail) = self.get_split_mut();
130*5225e6b1SAndroid Build Coastguard Worker         tail
131*5225e6b1SAndroid Build Coastguard Worker     }
132*5225e6b1SAndroid Build Coastguard Worker }
133*5225e6b1SAndroid Build Coastguard Worker 
134*5225e6b1SAndroid Build Coastguard Worker impl AsRef<[MaybeUninit<u8>]> for ImageBuffer<'_> {
as_ref(&self) -> &[MaybeUninit<u8>]135*5225e6b1SAndroid Build Coastguard Worker     fn as_ref(&self) -> &[MaybeUninit<u8>] {
136*5225e6b1SAndroid Build Coastguard Worker         self.buffer.as_ref().unwrap()
137*5225e6b1SAndroid Build Coastguard Worker     }
138*5225e6b1SAndroid Build Coastguard Worker }
139*5225e6b1SAndroid Build Coastguard Worker 
140*5225e6b1SAndroid Build Coastguard Worker impl AsMut<[MaybeUninit<u8>]> for ImageBuffer<'_> {
as_mut(&mut self) -> &mut [MaybeUninit<u8>]141*5225e6b1SAndroid Build Coastguard Worker     fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] {
142*5225e6b1SAndroid Build Coastguard Worker         self.buffer.as_mut().unwrap()
143*5225e6b1SAndroid Build Coastguard Worker     }
144*5225e6b1SAndroid Build Coastguard Worker }
145*5225e6b1SAndroid Build Coastguard Worker 
146*5225e6b1SAndroid Build Coastguard Worker impl PartialEq for ImageBuffer<'_> {
eq(&self, other: &Self) -> bool147*5225e6b1SAndroid Build Coastguard Worker     fn eq(&self, other: &Self) -> bool {
148*5225e6b1SAndroid Build Coastguard Worker         self.used() == other.used()
149*5225e6b1SAndroid Build Coastguard Worker     }
150*5225e6b1SAndroid Build Coastguard Worker }
151*5225e6b1SAndroid Build Coastguard Worker 
152*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
153*5225e6b1SAndroid Build Coastguard Worker /// Helper to create ImageBuffers from Vec<u8>
154*5225e6b1SAndroid Build Coastguard Worker pub struct ImageBufferVec {
155*5225e6b1SAndroid Build Coastguard Worker     buf: Vec<u8>,
156*5225e6b1SAndroid Build Coastguard Worker }
157*5225e6b1SAndroid Build Coastguard Worker 
158*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
159*5225e6b1SAndroid Build Coastguard Worker impl ImageBufferVec {
new(buf: Vec<u8>) -> Self160*5225e6b1SAndroid Build Coastguard Worker     pub fn new(buf: Vec<u8>) -> Self {
161*5225e6b1SAndroid Build Coastguard Worker         Self { buf }
162*5225e6b1SAndroid Build Coastguard Worker     }
163*5225e6b1SAndroid Build Coastguard Worker 
get(&mut self) -> ImageBuffer164*5225e6b1SAndroid Build Coastguard Worker     pub fn get(&mut self) -> ImageBuffer {
165*5225e6b1SAndroid Build Coastguard Worker         ImageBuffer::new(Self::slice_assume_not_init_mut(self.buf.as_mut_slice()))
166*5225e6b1SAndroid Build Coastguard Worker     }
167*5225e6b1SAndroid Build Coastguard Worker 
slice_assume_not_init_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>]168*5225e6b1SAndroid Build Coastguard Worker     fn slice_assume_not_init_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>] {
169*5225e6b1SAndroid Build Coastguard Worker         // SAFETY: similar to safety notes for `slice_get_ref`, but we have a
170*5225e6b1SAndroid Build Coastguard Worker         // mutable reference which is also guaranteed to be valid for writes.
171*5225e6b1SAndroid Build Coastguard Worker         unsafe { &mut *(slice as *mut [T] as *mut [MaybeUninit<T>]) }
172*5225e6b1SAndroid Build Coastguard Worker     }
173*5225e6b1SAndroid Build Coastguard Worker }
174*5225e6b1SAndroid Build Coastguard Worker 
175*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
176*5225e6b1SAndroid Build Coastguard Worker mod test {
177*5225e6b1SAndroid Build Coastguard Worker     use super::*;
178*5225e6b1SAndroid Build Coastguard Worker 
179*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_capacity()180*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_capacity() {
181*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(ImageBufferVec::new(vec![0u8; 0]).get().capacity(), 0);
182*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(ImageBufferVec::new(vec![0u8; 0]).get().capacity(), 0);
183*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(ImageBufferVec::new(vec![0u8; 1]).get().capacity(), 1);
184*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(ImageBufferVec::new(vec![0u8; 100]).get().capacity(), 100);
185*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(
186*5225e6b1SAndroid Build Coastguard Worker             ImageBufferVec::new(vec![0u8; 128 * 1024 * 1024]).get().capacity(),
187*5225e6b1SAndroid Build Coastguard Worker             128 * 1024 * 1024
188*5225e6b1SAndroid Build Coastguard Worker         );
189*5225e6b1SAndroid Build Coastguard Worker     }
190*5225e6b1SAndroid Build Coastguard Worker 
191*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_used()192*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_used() {
193*5225e6b1SAndroid Build Coastguard Worker         let mut img_buf_vec = ImageBufferVec::new(vec![0u8; 100]);
194*5225e6b1SAndroid Build Coastguard Worker         let mut img_buf = img_buf_vec.get();
195*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used().len(), 0);
196*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut().len(), 0);
197*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
198*5225e6b1SAndroid Build Coastguard Worker         // All data in img_buf is initialized since it was created from vec
199*5225e6b1SAndroid Build Coastguard Worker         unsafe { img_buf.advance_used(1).unwrap() };
200*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used().len(), 1);
201*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut().len(), 1);
202*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
203*5225e6b1SAndroid Build Coastguard Worker         // All data in img_buf is initialized since it was created from vec
204*5225e6b1SAndroid Build Coastguard Worker         unsafe { img_buf.advance_used(3).unwrap() };
205*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used().len(), 4);
206*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut().len(), 4);
207*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(
208*5225e6b1SAndroid Build Coastguard Worker             // SAFETY:
209*5225e6b1SAndroid Build Coastguard Worker             // All data in img_buf is initialized since it was created from vec
210*5225e6b1SAndroid Build Coastguard Worker             unsafe { img_buf.advance_used(1024) },
211*5225e6b1SAndroid Build Coastguard Worker             Err(Error::BufferTooSmall(Some(1028)))
212*5225e6b1SAndroid Build Coastguard Worker         );
213*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used().len(), 4);
214*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut().len(), 4);
215*5225e6b1SAndroid Build Coastguard Worker     }
216*5225e6b1SAndroid Build Coastguard Worker 
217*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_get_split()218*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_get_split() {
219*5225e6b1SAndroid Build Coastguard Worker         let mut img_buf_vec = ImageBufferVec::new(vec![0u8, 1, 2, 3]);
220*5225e6b1SAndroid Build Coastguard Worker         let mut img_buf = img_buf_vec.get();
221*5225e6b1SAndroid Build Coastguard Worker 
222*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used(), [].as_slice());
223*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut(), [].as_mut_slice());
224*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.tail().len(), 4);
225*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split();
226*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [].as_slice());
227*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 4);
228*5225e6b1SAndroid Build Coastguard Worker 
229*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split_mut();
230*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [].as_mut_slice());
231*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 4);
232*5225e6b1SAndroid Build Coastguard Worker 
233*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
234*5225e6b1SAndroid Build Coastguard Worker         // All data in img_buf is initialized since it was created from vec
235*5225e6b1SAndroid Build Coastguard Worker         unsafe { img_buf.advance_used(2).unwrap() };
236*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used(), [0, 1].as_slice());
237*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut(), [0, 1].as_mut_slice());
238*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.tail().len(), 2);
239*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split();
240*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [0, 1].as_slice());
241*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 2);
242*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split_mut();
243*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [0, 1].as_mut_slice());
244*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 2);
245*5225e6b1SAndroid Build Coastguard Worker 
246*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
247*5225e6b1SAndroid Build Coastguard Worker         // All data in img_buf is initialized since it was created from vec
248*5225e6b1SAndroid Build Coastguard Worker         unsafe { img_buf.advance_used(2).unwrap() };
249*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used(), [0, 1, 2, 3].as_slice());
250*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.used_mut(), [0, 1, 2, 3].as_mut_slice());
251*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(img_buf.tail().len(), 0);
252*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split();
253*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [0, 1, 2, 3].as_slice());
254*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 0);
255*5225e6b1SAndroid Build Coastguard Worker         let (used, tail) = img_buf.get_split_mut();
256*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(used, [0, 1, 2, 3].as_mut_slice());
257*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(tail.len(), 0);
258*5225e6b1SAndroid Build Coastguard Worker     }
259*5225e6b1SAndroid Build Coastguard Worker 
260*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_eq_not_init()261*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_eq_not_init() {
262*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(
263*5225e6b1SAndroid Build Coastguard Worker             ImageBufferVec::new(vec![0u8, 1, 2]).get(),
264*5225e6b1SAndroid Build Coastguard Worker             ImageBufferVec::new(vec![0u8, 1, 2]).get()
265*5225e6b1SAndroid Build Coastguard Worker         );
266*5225e6b1SAndroid Build Coastguard Worker     }
267*5225e6b1SAndroid Build Coastguard Worker 
268*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_eq_init_same()269*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_eq_init_same() {
270*5225e6b1SAndroid Build Coastguard Worker         let mut v1 = ImageBufferVec::new(vec![0u8, 1, 2]);
271*5225e6b1SAndroid Build Coastguard Worker         let mut v2 = ImageBufferVec::new(vec![0u8, 1, 2]);
272*5225e6b1SAndroid Build Coastguard Worker         let mut image_buffer_1 = v1.get();
273*5225e6b1SAndroid Build Coastguard Worker         let mut image_buffer_2 = v2.get();
274*5225e6b1SAndroid Build Coastguard Worker 
275*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
276*5225e6b1SAndroid Build Coastguard Worker         // Buffers initialised on creation.
277*5225e6b1SAndroid Build Coastguard Worker         unsafe {
278*5225e6b1SAndroid Build Coastguard Worker             image_buffer_1.advance_used(3).unwrap();
279*5225e6b1SAndroid Build Coastguard Worker             image_buffer_2.advance_used(3).unwrap();
280*5225e6b1SAndroid Build Coastguard Worker         }
281*5225e6b1SAndroid Build Coastguard Worker 
282*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(image_buffer_1, image_buffer_2);
283*5225e6b1SAndroid Build Coastguard Worker     }
284*5225e6b1SAndroid Build Coastguard Worker 
285*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_image_buffer_eq_diff_capacity()286*5225e6b1SAndroid Build Coastguard Worker     fn test_image_buffer_eq_diff_capacity() {
287*5225e6b1SAndroid Build Coastguard Worker         let mut v1 = ImageBufferVec::new(vec![0u8, 1, 2]);
288*5225e6b1SAndroid Build Coastguard Worker         let mut v2 = ImageBufferVec::new(vec![0u8, 1, 2, 3]);
289*5225e6b1SAndroid Build Coastguard Worker         let mut image_buffer_1 = v1.get();
290*5225e6b1SAndroid Build Coastguard Worker         let mut image_buffer_2 = v2.get();
291*5225e6b1SAndroid Build Coastguard Worker 
292*5225e6b1SAndroid Build Coastguard Worker         // SAFETY:
293*5225e6b1SAndroid Build Coastguard Worker         // Buffers initialised on creation.
294*5225e6b1SAndroid Build Coastguard Worker         unsafe {
295*5225e6b1SAndroid Build Coastguard Worker             image_buffer_1.advance_used(2).unwrap();
296*5225e6b1SAndroid Build Coastguard Worker             image_buffer_2.advance_used(2).unwrap();
297*5225e6b1SAndroid Build Coastguard Worker         }
298*5225e6b1SAndroid Build Coastguard Worker 
299*5225e6b1SAndroid Build Coastguard Worker         assert_eq!(image_buffer_1, image_buffer_2);
300*5225e6b1SAndroid Build Coastguard Worker     }
301*5225e6b1SAndroid Build Coastguard Worker }
302