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 | fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { |
28 | fmt&mut DebugStruct<'_, '_>.debug_struct("BufReader" ) |
29 | .field("reader" , &self.inner) |
30 | .field( |
31 | name:"buffer" , |
32 | &format_args!(" {}/ {}" , self.cap - self.pos, self.buf.len()), |
33 | ) |
34 | .finish() |
35 | } |
36 | } |
37 | |
38 | impl<R: Read> BufReader<R> { |
39 | pub fn new(inner: R) -> BufReader<R> { |
40 | BufReader::with_buf(buf:vec![0; 32 * 1024], inner) |
41 | } |
42 | |
43 | pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> { |
44 | BufReader { |
45 | inner, |
46 | buf: buf.into_boxed_slice(), |
47 | pos: 0, |
48 | cap: 0, |
49 | } |
50 | } |
51 | } |
52 | |
53 | impl<R> BufReader<R> { |
54 | pub fn get_ref(&self) -> &R { |
55 | &self.inner |
56 | } |
57 | |
58 | pub fn get_mut(&mut self) -> &mut R { |
59 | &mut self.inner |
60 | } |
61 | |
62 | pub fn into_inner(self) -> R { |
63 | self.inner |
64 | } |
65 | |
66 | pub fn reset(&mut self, inner: R) -> R { |
67 | self.pos = 0; |
68 | self.cap = 0; |
69 | mem::replace(&mut self.inner, src:inner) |
70 | } |
71 | } |
72 | |
73 | impl<R: Read> Read for BufReader<R> { |
74 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
75 | // If we don't have any buffered data and we're doing a massive read |
76 | // (larger than our internal buffer), bypass our internal buffer |
77 | // entirely. |
78 | if self.pos == self.cap && buf.len() >= self.buf.len() { |
79 | return self.inner.read(buf); |
80 | } |
81 | let nread: usize = { |
82 | let mut rem: &[u8] = self.fill_buf()?; |
83 | rem.read(buf)? |
84 | }; |
85 | self.consume(amt:nread); |
86 | Ok(nread) |
87 | } |
88 | } |
89 | |
90 | impl<R: Read> BufRead for BufReader<R> { |
91 | fn fill_buf(&mut self) -> io::Result<&[u8]> { |
92 | // If we've reached the end of our internal buffer then we need to fetch |
93 | // some more data from the underlying reader. |
94 | if self.pos == self.cap { |
95 | self.cap = self.inner.read(&mut self.buf)?; |
96 | self.pos = 0; |
97 | } |
98 | Ok(&self.buf[self.pos..self.cap]) |
99 | } |
100 | |
101 | fn consume(&mut self, amt: usize) { |
102 | self.pos = cmp::min(self.pos + amt, self.cap); |
103 | } |
104 | } |
105 | |