hyper 0.3.5

A modern HTTP library.
use std::cmp;
use std::iter;
use std::io::{self, Read, BufRead, Cursor};

pub struct BufReader<R> {
    buf: Cursor<Vec<u8>>,
    inner: R
}

const INIT_BUFFER_SIZE: usize = 4096;
const MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

impl<R: Read> BufReader<R> {
    pub fn new(rdr: R) -> BufReader<R> {
        BufReader::with_capacity(rdr, INIT_BUFFER_SIZE)
    }

    pub fn with_capacity(rdr: R, cap: usize) -> BufReader<R> {
        BufReader {
            buf: Cursor::new(Vec::with_capacity(cap)),
            inner: rdr
        }
    }

    pub fn get_ref(&self) -> &R { &self.inner }

    pub fn get_mut(&mut self) -> &mut R { &mut self.inner }

    pub fn get_buf(&self) -> &[u8] {
        self.buf.get_ref()
    }

    pub fn into_inner(self) -> R { self.inner }

    pub fn read_into_buf(&mut self) -> io::Result<usize> {
        let v = self.buf.get_mut();
        reserve(v);
        let inner = &mut self.inner;
        with_end_to_cap(v, |b| inner.read(b))
    }
}

impl<R: Read> Read for BufReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.buf.get_ref().len() == self.buf.position() as usize &&
            buf.len() >= self.buf.get_ref().capacity() {
            return self.inner.read(buf);
        }
        try!(self.fill_buf());
        self.buf.read(buf)
    }
}

impl<R: Read> BufRead for BufReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
         if self.buf.position() as usize == self.buf.get_ref().len() {
            self.buf.set_position(0);
            let v = self.buf.get_mut();
            v.truncate(0);
            let inner = &mut self.inner;
            try!(with_end_to_cap(v, |b| inner.read(b)));
         }
         self.buf.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.buf.consume(amt)
    }
}

fn with_end_to_cap<F>(v: &mut Vec<u8>, f: F) -> io::Result<usize>
    where F: FnOnce(&mut [u8]) -> io::Result<usize>
{
    let len = v.len();
    let new_area = v.capacity() - len;
    v.extend(iter::repeat(0).take(new_area));
    match f(&mut v[len..]) {
        Ok(n) => {
            v.truncate(len + n);
            Ok(n)
        }
        Err(e) => {
            v.truncate(len);
            Err(e)
        }
    }
}

#[inline]
fn reserve(v: &mut Vec<u8>) {
    let cap = v.capacity();
    if v.len() == cap {
        v.reserve(cmp::min(cap * 4, MAX_BUFFER_SIZE) - cap);
    }
}