@@ -284,102 +284,6 @@ impl<'flash, F: Flash> FlashExt<'flash> for &'flash F {
284
284
}
285
285
}
286
286
287
- /// Adapter for working with a sub-region of a [`Flash`] type.
288
- ///
289
- /// Reads and writes on the device will be constrained to a given [`Region`].
290
- /// This is especially useful for operating on a blob contained within another
291
- /// region of flash.
292
- ///
293
- /// There is no requirement that [`Region`] actually overlap with the address
294
- /// space of `F`; the [`Flash`] implementation is still responsible for doing
295
- /// bounds checks, after offsets are bounds-checked within `Region`.
296
- #[ derive( Copy , Clone ) ]
297
- pub struct SubFlash < F > ( pub F , pub Region ) ;
298
-
299
- impl < F : Flash > SubFlash < F > {
300
- /// Creates a new `SubFlash` representing the entirety of the given device.
301
- pub fn full ( flash : F ) -> Result < Self , Error > {
302
- let region = Region :: new ( 0 , flash. size ( ) ?) ;
303
- Ok ( Self ( flash, region) )
304
- }
305
- }
306
-
307
- impl < F > SubFlash < F > {
308
- /// Interprets `region` as a subregion of this `SubFlash`, returning a new
309
- /// `SubFlash` that represents that region.
310
- pub fn reslice ( self , region : Region ) -> Option < Self > {
311
- if region. len >= self . 1 . len {
312
- return None ;
313
- }
314
-
315
- Some ( Self (
316
- self . 0 ,
317
- Region :: new (
318
- self . 1 . ptr . address . checked_add ( region. ptr . address ) ?,
319
- region. len ,
320
- ) ,
321
- ) )
322
- }
323
- }
324
-
325
- unsafe impl < F : Flash > Flash for SubFlash < F > {
326
- #[ inline]
327
- fn size ( & self ) -> Result < u32 , Error > {
328
- Ok ( self . 1 . len )
329
- }
330
-
331
- #[ inline]
332
- fn read ( & self , offset : Ptr , out : & mut [ u8 ] ) -> Result < ( ) , Error > {
333
- if offset. address >= self . 1 . len {
334
- return Err ( Error :: OutOfRange ) ;
335
- }
336
- let offset = offset
337
- . address
338
- . checked_add ( self . 1 . ptr . address )
339
- . ok_or ( Error :: OutOfRange ) ?;
340
-
341
- self . 0 . read ( Ptr :: new ( offset) , out)
342
- }
343
-
344
- #[ inline]
345
- fn read_direct < ' a : ' c , ' b : ' c , ' c > (
346
- & ' a self ,
347
- region : Region ,
348
- arena : & ' b dyn Arena ,
349
- align : usize ,
350
- ) -> Result < & ' c [ u8 ] , Error > {
351
- if region. ptr . address >= self . 1 . len {
352
- return Err ( Error :: OutOfRange ) ;
353
- }
354
- let offset = region
355
- . ptr
356
- . address
357
- . checked_add ( self . 1 . ptr . address )
358
- . ok_or ( Error :: OutOfRange ) ?;
359
-
360
- self . 0
361
- . read_direct ( Region :: new ( offset, region. len ) , arena, align)
362
- }
363
-
364
- #[ inline]
365
- fn program ( & mut self , offset : Ptr , buf : & [ u8 ] ) -> Result < ( ) , Error > {
366
- if offset. address >= self . 1 . len {
367
- return Err ( Error :: OutOfRange ) ;
368
- }
369
- let offset = offset
370
- . address
371
- . checked_add ( self . 1 . ptr . address )
372
- . ok_or ( Error :: OutOfRange ) ?;
373
-
374
- self . 0 . program ( Ptr :: new ( offset) , buf)
375
- }
376
-
377
- #[ inline]
378
- fn flush ( & mut self ) -> Result < ( ) , Error > {
379
- self . 0 . flush ( )
380
- }
381
- }
382
-
383
287
/// Adapter for converting RAM-backed storage into a [`Flash`].
384
288
///
385
289
/// For the purposes of this type, "RAM-backed" means that `AsRef<[u8]>`
@@ -535,10 +439,29 @@ impl<F: Flash> FlashIo<F> {
535
439
pub fn skip ( & mut self , bytes : usize ) {
536
440
self . cursor = self . cursor . saturating_add ( bytes as u32 ) ;
537
441
}
442
+
443
+ /// Skips the "end" pointer `bytes` bytes forward.
444
+ ///
445
+ /// This operation always succeeds, but attempting to read past the end of
446
+ /// flash will always result in an error.
447
+ pub fn take ( & mut self , bytes : usize ) {
448
+ self . len = self . len . saturating_sub ( bytes as u32 ) ;
449
+ }
450
+
451
+ /// Adapts this `FlashIo` to only read bytes out from the selected
452
+ /// `Region`.
453
+ pub fn reslice ( & mut self , region : Region ) {
454
+ self . cursor = region. ptr . address ;
455
+ self . len = region. end ( ) ;
456
+ }
538
457
}
539
458
540
459
impl < F : Flash > io:: Read for FlashIo < F > {
541
460
fn read_bytes ( & mut self , out : & mut [ u8 ] ) -> Result < ( ) , io:: Error > {
461
+ if self . remaining_data ( ) == 0 {
462
+ return Err ( io:: Error :: BufferExhausted ) ;
463
+ }
464
+
542
465
self . flash
543
466
. read ( Ptr :: new ( self . cursor ) , out)
544
467
. map_err ( |_| io:: Error :: Internal ) ?;
@@ -569,6 +492,10 @@ impl<F: Flash> Iterator for FlashIo<F> {
569
492
570
493
impl < F : Flash > io:: Write for FlashIo < F > {
571
494
fn write_bytes ( & mut self , buf : & [ u8 ] ) -> Result < ( ) , io:: Error > {
495
+ if self . remaining_data ( ) == 0 {
496
+ return Err ( io:: Error :: BufferExhausted ) ;
497
+ }
498
+
572
499
self . flash
573
500
. program ( Ptr :: new ( self . cursor ) , buf)
574
501
. map_err ( |_| io:: Error :: Internal ) ?;
@@ -634,7 +561,7 @@ impl Region {
634
561
635
562
/// Returns a `Region` big enough to hold a `[T]` with the given number of
636
563
/// elements.
637
- ///
564
+ ///
638
565
/// Returns `None` on overflow`.
639
566
pub fn for_slice < T > ( n : usize ) -> Option < Self > {
640
567
Some ( Self :: new ( 0 , mem:: size_of :: < T > ( ) . checked_mul ( n) ? as u32 ) )
@@ -653,7 +580,7 @@ impl Region {
653
580
654
581
/// Interprets `sub` as a subregion of `self`, returning a new `Region` of
655
582
/// the same size as `sub`.
656
- ///
583
+ ///
657
584
/// Returns `None` if `sub` is not a subregion of `self`.
658
585
pub fn subregion ( self , sub : Region ) -> Option < Self > {
659
586
if sub. len . saturating_add ( sub. ptr . address ) > self . len {
@@ -667,17 +594,20 @@ impl Region {
667
594
}
668
595
669
596
/// Contracts `self` by dropping the first `n` bytes.
670
- ///
597
+ ///
671
598
/// Returns `None` if `n` is greater than `self.len`, or if any overflow
672
599
/// occurs.
673
600
pub fn skip ( self , n : u32 ) -> Option < Self > {
674
- Some ( Region :: new ( self . ptr . address . checked_add ( n) ?, self . len . checked_sub ( n) ?) )
601
+ Some ( Region :: new (
602
+ self . ptr . address . checked_add ( n) ?,
603
+ self . len . checked_sub ( n) ?,
604
+ ) )
675
605
}
676
606
677
607
/// Contracts `self` by dropping the last `n` bytes.
678
- ///
608
+ ///
679
609
/// Returns `None` if `n` is greater than `self.len`.
680
- pub fn skip_back ( self , n : u32 ) -> Option < Self > {
610
+ pub fn take ( self , n : u32 ) -> Option < Self > {
681
611
Some ( Region :: new ( self . ptr . address , self . len . checked_sub ( n) ?) )
682
612
}
683
613
}
0 commit comments