1 //! `BufRead` pointer or `BufReader` owned. 2 3 use std::cmp; 4 use std::io; 5 use std::io::BufRead; 6 use std::io::BufReader; 7 use std::io::Read; 8 use std::mem::MaybeUninit; 9 10 use crate::misc::maybe_uninit_write_slice; 11 12 /// Helper type to simplify `BufReadIter` implementation. 13 pub(crate) enum BufReadOrReader<'a> { 14 BufReader(BufReader<&'a mut dyn Read>), 15 BufRead(&'a mut dyn BufRead), 16 } 17 18 impl<'a> Read for BufReadOrReader<'a> { read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>19 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> { 20 match self { 21 BufReadOrReader::BufReader(r) => r.read(buf), 22 BufReadOrReader::BufRead(r) => r.read(buf), 23 } 24 } 25 read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, io::Error>26 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, io::Error> { 27 match self { 28 BufReadOrReader::BufReader(r) => r.read_to_end(buf), 29 BufReadOrReader::BufRead(r) => r.read_to_end(buf), 30 } 31 } 32 read_exact(&mut self, buf: &mut [u8]) -> Result<(), io::Error>33 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), io::Error> { 34 match self { 35 BufReadOrReader::BufReader(r) => r.read_exact(buf), 36 BufReadOrReader::BufRead(r) => r.read_exact(buf), 37 } 38 } 39 } 40 41 impl<'a> BufReadOrReader<'a> { 42 /// Similar to `read_exact` but reads into `MaybeUninit`. read_exact_uninit( &mut self, buf: &mut [MaybeUninit<u8>], ) -> Result<(), io::Error>43 pub(crate) fn read_exact_uninit( 44 &mut self, 45 buf: &mut [MaybeUninit<u8>], 46 ) -> Result<(), io::Error> { 47 let mut pos = 0; 48 while pos != buf.len() { 49 let fill_buf = match self { 50 BufReadOrReader::BufReader(r) => r.fill_buf()?, 51 BufReadOrReader::BufRead(r) => r.fill_buf()?, 52 }; 53 if fill_buf.is_empty() { 54 return Err(io::Error::new( 55 io::ErrorKind::UnexpectedEof, 56 "Unexpected end of file", 57 )); 58 } 59 let consume = cmp::min(fill_buf.len(), buf.len() - pos); 60 maybe_uninit_write_slice(&mut buf[pos..pos + consume], &fill_buf[..consume]); 61 match self { 62 BufReadOrReader::BufReader(r) => r.consume(consume), 63 BufReadOrReader::BufRead(r) => r.consume(consume), 64 } 65 pos += consume; 66 } 67 Ok(()) 68 } 69 } 70 71 impl<'a> BufRead for BufReadOrReader<'a> { fill_buf(&mut self) -> Result<&[u8], io::Error>72 fn fill_buf(&mut self) -> Result<&[u8], io::Error> { 73 match self { 74 BufReadOrReader::BufReader(r) => r.fill_buf(), 75 BufReadOrReader::BufRead(r) => r.fill_buf(), 76 } 77 } 78 consume(&mut self, amt: usize)79 fn consume(&mut self, amt: usize) { 80 match self { 81 BufReadOrReader::BufReader(r) => r.consume(amt), 82 BufReadOrReader::BufRead(r) => r.consume(amt), 83 } 84 } 85 } 86