• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://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 {
fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error>27     fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
28         fmt.debug_struct("BufReader")
29             .field("reader", &self.inner)
30             .field(
31                 "buffer",
32                 &format_args!("{}/{}", self.cap - self.pos, self.buf.len()),
33             )
34             .finish()
35     }
36 }
37 
38 impl<R: Read> BufReader<R> {
new(inner: R) -> BufReader<R>39     pub fn new(inner: R) -> BufReader<R> {
40         BufReader::with_buf(vec![0; 32 * 1024], inner)
41     }
42 
with_buf(buf: Vec<u8>, inner: R) -> BufReader<R>43     pub fn with_buf(buf: Vec<u8>, inner: R) -> BufReader<R> {
44         BufReader {
45             inner: inner,
46             buf: buf.into_boxed_slice(),
47             pos: 0,
48             cap: 0,
49         }
50     }
51 }
52 
53 impl<R> BufReader<R> {
get_ref(&self) -> &R54     pub fn get_ref(&self) -> &R {
55         &self.inner
56     }
57 
get_mut(&mut self) -> &mut R58     pub fn get_mut(&mut self) -> &mut R {
59         &mut self.inner
60     }
61 
into_inner(self) -> R62     pub fn into_inner(self) -> R {
63         self.inner
64     }
65 
reset(&mut self, inner: R) -> R66     pub fn reset(&mut self, inner: R) -> R {
67         self.pos = 0;
68         self.cap = 0;
69         mem::replace(&mut self.inner, inner)
70     }
71 }
72 
73 impl<R: Read> Read for BufReader<R> {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>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 = {
82             let mut rem = self.fill_buf()?;
83             rem.read(buf)?
84         };
85         self.consume(nread);
86         Ok(nread)
87     }
88 }
89 
90 impl<R: Read> BufRead for BufReader<R> {
fill_buf(&mut self) -> io::Result<&[u8]>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 
consume(&mut self, amt: usize)101     fn consume(&mut self, amt: usize) {
102         self.pos = cmp::min(self.pos + amt, self.cap);
103     }
104 }
105