1#![cfg_attr(not(feature = "std"), no_std)]
28
29#[cfg(feature = "alloc")]
30extern crate alloc;
31
32#[cfg(feature = "alloc")]
33use alloc::vec;
34
35#[cfg(feature = "alloc")]
36use alloc::vec::Vec;
37
38#[cfg(feature = "alloc")]
39use alloc::boxed::Box;
40
41use core::fmt::Debug;
42
43pub trait Load {
49 type Error;
50
51 fn load(&mut self, destination: &mut [u8]) -> Result<(), Self::Error>;
52}
53
54#[cfg(feature = "std")]
55impl<T> Load for T
56where
57 T: std::io::Read,
58{
59 type Error = std::io::Error;
60 fn load(&mut self, destination: &mut [u8]) -> Result<(), Self::Error> {
61 self.read_exact(destination)
62 }
63}
64
65#[derive(Clone, Debug)]
73pub struct BufferedLoader<Buffer, Loader>
74where
75 Buffer: AsRef<[u8]> + AsMut<[u8]> + Debug,
76 Loader: Load,
77{
78 loader: Loader,
79 buffer: Buffer,
80
81 offset: usize,
83}
84
85impl<const N: usize, Loader> BufferedLoader<[u8; N], Loader>
86where
87 Loader: Load,
88{
89 pub fn new_static(loader: Loader) -> Self {
91 Self::new([0u8; N], loader)
92 }
93}
94
95#[cfg(feature = "alloc")]
96impl<Loader> BufferedLoader<Vec<u8>, Loader>
97where
98 Loader: Load,
99{
100 pub fn new_dynamic(loader: Loader, buffer_size: usize) -> Self {
102 Self::new(vec![0u8; buffer_size], loader)
103 }
104
105 pub fn resize(&mut self, new_size: usize) {
106 self.buffer.resize(new_size, 0);
107 self.offset = new_size;
108 }
109}
110
111#[cfg(feature = "alloc")]
112impl<Loader> BufferedLoader<Box<[u8]>, Loader>
113where
114 Loader: Load,
115{
116 pub fn new_heap(loader: Loader, buffer_size: usize) -> Self {
118 Self::new(vec![0u8; buffer_size].into_boxed_slice(), loader)
119 }
120}
121
122impl<Buffer, Loader> BufferedLoader<Buffer, Loader>
123where
124 Buffer: AsRef<[u8]> + AsMut<[u8]> + Debug,
125 Loader: Load,
126{
127 pub fn new(buffer: Buffer, loader: Loader) -> Self {
128 let offset = buffer.as_ref().len();
129 Self {
130 loader,
131 buffer,
132 offset,
133 }
134 }
135
136 pub fn loader(&mut self) -> &mut Loader {
139 self.offset = self.buffer.as_ref().len();
140 &mut self.loader
141 }
142}
143
144impl<Buffer, Loader> Load for BufferedLoader<Buffer, Loader>
145where
146 Buffer: AsRef<[u8]> + AsMut<[u8]> + Debug,
147 Loader: Load,
148{
149 type Error = Loader::Error;
150
151 fn load(&mut self, mut destination: &mut [u8]) -> Result<(), Self::Error> {
156 if destination.is_empty() {
157 return Ok(());
158 }
159
160 let buffer = self.buffer.as_mut();
161 let buffer_size = buffer.len();
162
163 let buffer_remaining = buffer_size - self.offset;
164
165 if destination.len() <= buffer_remaining {
166 let end = self.offset + destination.len();
169 destination.copy_from_slice(&buffer[self.offset..end]);
170 self.offset = end;
171 } else {
172 if buffer_remaining > 0 {
174 destination[..buffer_remaining].copy_from_slice(&buffer[self.offset..buffer_size]);
175 let copied = buffer_size - self.offset;
176 destination = &mut destination[copied..];
177 }
178
179 let buffers = destination.len() / buffer_size;
180 let remainder = destination.len() % buffer_size;
181
182 if buffers > 0 {
185 let buffers_bytes = buffers * buffer_size;
186 self.loader.load(&mut destination[..buffers_bytes])?;
187
188 destination = &mut destination[buffers_bytes..];
189 }
190
191 if remainder > 0 {
193 self.loader.load(buffer)?;
194 destination.copy_from_slice(&buffer[..remainder]);
195 self.offset = remainder;
196 } else {
197 self.offset = buffer_size;
199 }
200 }
201 Ok(())
202 }
203}
204
205#[cfg(test)]
206pub mod test {
207 use core::convert::Infallible;
208
209 use super::*;
210
211 #[derive(Default)]
212 struct Increment(u8);
213
214 impl Load for Increment {
215 type Error = Infallible;
216
217 fn load(&mut self, destination: &mut [u8]) -> Result<(), Self::Error> {
218 for each in destination {
219 *each = self.0;
220 self.0 = self.0.wrapping_add(1);
221 }
222 Ok(())
223 }
224 }
225
226 #[test]
227 fn test_static_buffered_loader() {
228 let mut loader: BufferedLoader<[u8; 8], _> =
229 BufferedLoader::new_static(Increment::default());
230 let mut buf = [0u8; 4];
231 loader.load(&mut buf).unwrap();
232 assert_eq!(buf, [0, 1, 2, 3]);
233 loader.load(&mut buf).unwrap();
234 assert_eq!(buf, [4, 5, 6, 7]);
235 loader.load(&mut buf).unwrap();
236 assert_eq!(buf, [8, 9, 10, 11]);
237
238 let mut buf = [0u8; 12];
239 loader.load(&mut buf).unwrap();
240 assert_eq!(buf, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]);
241
242 let mut buf = [0u8; 3];
243
244 loader.load(&mut buf).unwrap();
245 assert_eq!(buf, [24, 25, 26]);
246 loader.load(&mut buf).unwrap();
247 assert_eq!(buf, [27, 28, 29]);
248 loader.load(&mut buf).unwrap();
249 assert_eq!(buf, [30, 31, 32]);
250 loader.load(&mut buf).unwrap();
251 assert_eq!(buf, [33, 34, 35]);
252 loader.load(&mut buf).unwrap();
253 assert_eq!(buf, [36, 37, 38]);
254 loader.load(&mut buf).unwrap();
255 assert_eq!(buf, [39, 40, 41]);
256 loader.load(&mut buf).unwrap();
257 assert_eq!(buf, [42, 43, 44]);
258 loader.load(&mut buf).unwrap();
259 assert_eq!(buf, [45, 46, 47]);
260 loader.load(&mut buf).unwrap();
261 assert_eq!(buf, [48, 49, 50]);
262 }
263
264 #[test]
265 fn test_dynamic_buffered_loader() {
266 let mut loader = BufferedLoader::new_dynamic(Increment::default(), 8);
267 let mut buf = [0u8; 4];
268 loader.load(&mut buf).unwrap();
269 assert_eq!(buf, [0, 1, 2, 3]);
270 loader.load(&mut buf).unwrap();
271 assert_eq!(buf, [4, 5, 6, 7]);
272 loader.load(&mut buf).unwrap();
273 assert_eq!(buf, [8, 9, 10, 11]);
274
275 let mut buf = [0u8; 12];
276 loader.load(&mut buf).unwrap();
277 assert_eq!(buf, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]);
278
279 let mut buf = [0u8; 3];
280
281 loader.load(&mut buf).unwrap();
282 assert_eq!(buf, [24, 25, 26]);
283 loader.load(&mut buf).unwrap();
284 assert_eq!(buf, [27, 28, 29]);
285 loader.load(&mut buf).unwrap();
286 assert_eq!(buf, [30, 31, 32]);
287 loader.load(&mut buf).unwrap();
288 assert_eq!(buf, [33, 34, 35]);
289 loader.load(&mut buf).unwrap();
290 assert_eq!(buf, [36, 37, 38]);
291 loader.load(&mut buf).unwrap();
292 assert_eq!(buf, [39, 40, 41]);
293 loader.load(&mut buf).unwrap();
294 assert_eq!(buf, [42, 43, 44]);
295 loader.load(&mut buf).unwrap();
296 assert_eq!(buf, [45, 46, 47]);
297 loader.load(&mut buf).unwrap();
298 assert_eq!(buf, [48, 49, 50]);
299 }
300
301 #[test]
302 fn test_boxed_slice_buffered_loader() {
303 let mut loader = BufferedLoader::new_heap(Increment::default(), 8);
304 let mut buf = [0u8; 4];
305 loader.load(&mut buf).unwrap();
306 assert_eq!(buf, [0, 1, 2, 3]);
307 loader.load(&mut buf).unwrap();
308 assert_eq!(buf, [4, 5, 6, 7]);
309 loader.load(&mut buf).unwrap();
310 assert_eq!(buf, [8, 9, 10, 11]);
311
312 let mut buf = [0u8; 12];
313 loader.load(&mut buf).unwrap();
314 assert_eq!(buf, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]);
315
316 let mut buf = [0u8; 3];
317
318 loader.load(&mut buf).unwrap();
319 assert_eq!(buf, [24, 25, 26]);
320 loader.load(&mut buf).unwrap();
321 assert_eq!(buf, [27, 28, 29]);
322 loader.load(&mut buf).unwrap();
323 assert_eq!(buf, [30, 31, 32]);
324 loader.load(&mut buf).unwrap();
325 assert_eq!(buf, [33, 34, 35]);
326 loader.load(&mut buf).unwrap();
327 assert_eq!(buf, [36, 37, 38]);
328 loader.load(&mut buf).unwrap();
329 assert_eq!(buf, [39, 40, 41]);
330 loader.load(&mut buf).unwrap();
331 assert_eq!(buf, [42, 43, 44]);
332 loader.load(&mut buf).unwrap();
333 assert_eq!(buf, [45, 46, 47]);
334 loader.load(&mut buf).unwrap();
335 assert_eq!(buf, [48, 49, 50]);
336 }
337}