/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.0.30/src/bufreader.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2013 The Rust Project Developers. See the COPYRIGHT |
2 | | // file at the top-level directory of this distribution and at |
3 | | // <https://github.com/rust-lang/rust/blob/HEAD/COPYRIGHT>. |
4 | | // |
5 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
6 | | // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
7 | | // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
8 | | // option. This file may not be copied, modified, or distributed |
9 | | // except according to those terms. |
10 | | |
11 | | use std::cmp; |
12 | | use std::io; |
13 | | use std::io::prelude::*; |
14 | | use std::mem; |
15 | | |
16 | | pub struct BufReader<R> { |
17 | | inner: R, |
18 | | buf: Box<[u8]>, |
19 | | pos: usize, |
20 | | cap: usize, |
21 | | } |
22 | | |
23 | | impl<R> ::std::fmt::Debug for BufReader<R> |
24 | | where |
25 | | R: ::std::fmt::Debug, |
26 | | { |
27 | 0 | fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { |
28 | 0 | fmt.debug_struct("BufReader") |
29 | 0 | .field("reader", &self.inner) |
30 | 0 | .field( |
31 | 0 | "buffer", |
32 | 0 | &format_args!("{}/{}", self.cap - self.pos, self.buf.len()), |
33 | 0 | ) |
34 | 0 | .finish() |
35 | 0 | } |
36 | | } |
37 | | |
38 | | impl<R: Read> BufReader<R> { |
39 | 0 | pub fn new(inner: R) -> BufReader<R> { |
40 | 0 | BufReader::with_buf(vec![0; 32 * 1024], inner) |
41 | 0 | } |
42 | | |
43 | 0 | pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> { |
44 | 0 | BufReader { |
45 | 0 | inner, |
46 | 0 | buf: buf.into_boxed_slice(), |
47 | 0 | pos: 0, |
48 | 0 | cap: 0, |
49 | 0 | } |
50 | 0 | } |
51 | | } |
52 | | |
53 | | impl<R> BufReader<R> { |
54 | 0 | pub fn get_ref(&self) -> &R { |
55 | 0 | &self.inner |
56 | 0 | } |
57 | | |
58 | 0 | pub fn get_mut(&mut self) -> &mut R { |
59 | 0 | &mut self.inner |
60 | 0 | } |
61 | | |
62 | 0 | pub fn into_inner(self) -> R { |
63 | 0 | self.inner |
64 | 0 | } |
65 | | |
66 | 0 | pub fn reset(&mut self, inner: R) -> R { |
67 | 0 | self.pos = 0; |
68 | 0 | self.cap = 0; |
69 | 0 | mem::replace(&mut self.inner, inner) |
70 | 0 | } |
71 | | } |
72 | | |
73 | | impl<R: Read> Read for BufReader<R> { |
74 | 0 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
75 | 0 | // If we don't have any buffered data and we're doing a massive read |
76 | 0 | // (larger than our internal buffer), bypass our internal buffer |
77 | 0 | // entirely. |
78 | 0 | if self.pos == self.cap && buf.len() >= self.buf.len() { |
79 | 0 | return self.inner.read(buf); |
80 | 0 | } |
81 | 0 | let nread = { |
82 | 0 | let mut rem = self.fill_buf()?; |
83 | 0 | rem.read(buf)? |
84 | | }; |
85 | 0 | self.consume(nread); |
86 | 0 | Ok(nread) |
87 | 0 | } |
88 | | } |
89 | | |
90 | | impl<R: Read> BufRead for BufReader<R> { |
91 | 0 | fn fill_buf(&mut self) -> io::Result<&[u8]> { |
92 | 0 | // If we've reached the end of our internal buffer then we need to fetch |
93 | 0 | // some more data from the underlying reader. |
94 | 0 | if self.pos == self.cap { |
95 | 0 | self.cap = self.inner.read(&mut self.buf)?; |
96 | 0 | self.pos = 0; |
97 | 0 | } |
98 | 0 | Ok(&self.buf[self.pos..self.cap]) |
99 | 0 | } |
100 | | |
101 | 0 | fn consume(&mut self, amt: usize) { |
102 | 0 | self.pos = cmp::min(self.pos + amt, self.cap); |
103 | 0 | } |
104 | | } |