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