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