• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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