@@ -339,6 +339,107 @@ pub trait Read: ErrorType {
339
339
}
340
340
}
341
341
342
+ /// The [BufReader] adds buffering to any reader, analogous to [`std::io::BufReader`]
343
+ ///
344
+ /// This [BufReader] allocates it's own internal buffer of size [N].
345
+ ///
346
+ /// # Examples
347
+ ///
348
+ /// ```
349
+ /// use embedded_io::BufReader;
350
+ ///
351
+ /// fn main()-> Result<(),>
352
+ /// {
353
+ /// let reader = [0,1,2,3];
354
+ /// let mut buf_reader: BufReader<4,&[u8]> = BufReader::new(&reader);
355
+ ///
356
+ /// let current_buff = buf_reader.fill_buff()?;
357
+ ///
358
+ /// buf_reader.consume(4);
359
+ ///
360
+ /// }
361
+ ///
362
+ /// ```
363
+ pub struct BufReader < const N : usize , R : ?Sized > {
364
+ buff : [ u8 ; N ] ,
365
+ pos : usize ,
366
+ inner : R ,
367
+ }
368
+
369
+ impl < const N : usize , R : ?Sized > BufReader < N , R > {
370
+ /// Gets a reference to the underlying reader.
371
+ pub fn get_ref ( & self ) -> & R {
372
+ & self . inner
373
+ }
374
+
375
+ pub fn get_mut ( & mut self ) -> & mut R {
376
+ & mut self . inner
377
+ }
378
+
379
+ pub fn buffer ( & self ) -> & [ u8 ] {
380
+ & self . buff
381
+ }
382
+
383
+ pub fn capacity ( & self ) -> usize {
384
+ N
385
+ }
386
+
387
+ pub fn into_inner ( self ) -> R
388
+ where
389
+ R : Sized ,
390
+ {
391
+ self . inner
392
+ }
393
+
394
+ pub fn discard_buffer ( & mut self ) {
395
+ self . pos = 0 ;
396
+ }
397
+ }
398
+
399
+ impl < const N : usize , R : Read > BufReader < N , R > {
400
+ /// Creates a new [BufReader<N,R>] with a buffer capacity of `N`.
401
+ pub fn new ( reader : R ) -> Self {
402
+ Self {
403
+ buff : [ 0u8 ; N ] ,
404
+ pos : 0 ,
405
+ inner : reader,
406
+ }
407
+ }
408
+ }
409
+
410
+ impl < const N : usize , R : Read > ErrorType for BufReader < N , R > {
411
+ type Error = R :: Error ;
412
+ }
413
+
414
+ impl < const N : usize , R : Read > BufRead for BufReader < N , R > {
415
+ fn consume ( & mut self , amt : usize ) {
416
+ // remove amt bytes from the front of the buffer
417
+ // imagine the buffer is [0,1,2,3,4]
418
+ // consume(2)
419
+ // the buffer is now [2,3,4]
420
+ self . buff . copy_within ( amt..self . pos , 0 ) ;
421
+ self . pos -= amt;
422
+ }
423
+
424
+ fn fill_buf ( & mut self ) -> Result < & [ u8 ] , Self :: Error > {
425
+ // fill the inner buffer
426
+ let read_count = self . inner . read ( & mut self . buff [ self . pos ..] ) ?;
427
+ self . pos += read_count;
428
+
429
+ Ok ( & self . buff [ ..self . pos ] )
430
+ }
431
+ }
432
+
433
+ impl < const N : usize , R : Read > Read for BufReader < N , R > {
434
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
435
+ let mut rem = self . fill_buf ( ) ?;
436
+ let nread = rem. read ( buf) . unwrap ( ) ; // infallible
437
+
438
+ self . consume ( nread) ;
439
+ Ok ( nread)
440
+ }
441
+ }
442
+
342
443
/// Blocking buffered reader.
343
444
///
344
445
/// This trait is the `embedded-io` equivalent of [`std::io::BufRead`].
@@ -551,3 +652,45 @@ impl<T: ?Sized + WriteReady> WriteReady for &mut T {
551
652
T :: write_ready ( self )
552
653
}
553
654
}
655
+
656
+ #[ cfg( test) ]
657
+ mod tests {
658
+ use super :: * ;
659
+
660
+ #[ test]
661
+ fn bufread_consume_removes_bytes ( ) {
662
+ let reader = [ 0 , 1 , 2 , 3 ] ;
663
+
664
+ let mut buf_read: BufReader < 4 , & [ u8 ] > = BufReader :: new ( & reader) ;
665
+
666
+ // read bytes
667
+ let current_buff = buf_read. fill_buf ( ) . unwrap ( ) ;
668
+
669
+ assert_eq ! ( current_buff, [ 0 , 1 , 2 , 3 ] ) ;
670
+
671
+ // consume bytes
672
+ buf_read. consume ( 2 ) ;
673
+
674
+ assert_eq ! ( buf_read. fill_buf( ) . unwrap( ) , [ 2 , 3 ] ) ;
675
+ }
676
+
677
+ #[ test]
678
+ #[ should_panic]
679
+ fn bufread_panics_if_consume_more_than_n_bytes ( ) {
680
+ let reader = [ 0 , 1 , 2 , 3 ] ;
681
+
682
+ let mut buf_read: BufReader < 4 , & [ u8 ] > = BufReader :: new ( & reader) ;
683
+
684
+ buf_read. consume ( 5 ) ;
685
+ }
686
+
687
+ #[ test]
688
+ #[ should_panic]
689
+ fn bufread_panics_if_consume_more_bytes_than_filled ( ) {
690
+ let reader = [ 0 , 1 , 2 , 3 ] ;
691
+
692
+ let mut buf_read: BufReader < 4 , & [ u8 ] > = BufReader :: new ( & reader) ;
693
+
694
+ buf_read. consume ( 4 ) ;
695
+ }
696
+ }
0 commit comments