use std::io::Read;
#[derive(PartialEq, Eq, Hash, Debug)]
pub struct BodyBytes<'a, R: Read> {
stream: R,
buf: &'a mut [u8],
pos: usize,
len: usize,
}
impl<'a, R: Read> BodyBytes<'a, R> {
pub fn new(stream: R, buf: &'a mut [u8], start: usize, len: usize) -> Self {
BodyBytes {
buf: buf,
stream: stream,
pos: start,
len: len,
}
}
}
impl<'a, R: Read> Iterator for BodyBytes<'a, R> {
type Item = std::io::Result<u8>;
fn next(&mut self) -> Option<Self::Item> {
if self.pos == self.len {
let len = match self.stream.read(self.buf) {
Ok(l) => l,
Err(e) => return Some(Err(e)),
};
if len == 0 {
return None;
}
self.pos = 0;
self.len = len;
}
let b = self.buf[self.pos];
self.pos += 1;
Some(Ok(b))
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Cursor;
#[test]
fn test_body_bytes() {
let stream = b"dy text";
let mut buf = [b'#'; 25];
(&mut buf[..]).copy_from_slice(b"GET / HTTP/1.1\r\n\r\nsome bo");
let mut r = BodyBytes::new(Cursor::new(&stream[..]), &mut buf[..], 18, 25);
assert_eq!(r.next().unwrap().unwrap(), b's');
assert_eq!(r.next().unwrap().unwrap(), b'o');
assert_eq!(r.next().unwrap().unwrap(), b'm');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b' ');
assert_eq!(r.next().unwrap().unwrap(), b'b');
assert_eq!(r.next().unwrap().unwrap(), b'o');
assert_eq!(r.next().unwrap().unwrap(), b'd');
assert_eq!(r.next().unwrap().unwrap(), b'y');
assert_eq!(r.next().unwrap().unwrap(), b' ');
assert_eq!(r.next().unwrap().unwrap(), b't');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b'x');
assert_eq!(r.next().unwrap().unwrap(), b't');
assert!(r.next().is_none());
let stream = b"abcdef";
let mut buf = [b'#'; 4];
let mut r = BodyBytes::new(Cursor::new(&stream[..]), &mut buf[..], 4, 4);
assert_eq!(r.next().unwrap().unwrap(), b'a');
assert_eq!(r.next().unwrap().unwrap(), b'b');
assert_eq!(r.next().unwrap().unwrap(), b'c');
assert_eq!(r.next().unwrap().unwrap(), b'd');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b'f');
assert!(r.next().is_none());
let stream = b"cdefgh";
let mut buf = [b'#'; 4];
(&mut buf[..2]).copy_from_slice(b"ab");
let mut r = BodyBytes::new(Cursor::new(&stream[..]), &mut buf[..], 0, 2);
assert_eq!(r.next().unwrap().unwrap(), b'a');
assert_eq!(r.next().unwrap().unwrap(), b'b');
assert_eq!(r.next().unwrap().unwrap(), b'c');
assert_eq!(r.next().unwrap().unwrap(), b'd');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b'f');
assert_eq!(r.next().unwrap().unwrap(), b'g');
assert_eq!(r.next().unwrap().unwrap(), b'h');
assert!(r.next().is_none());
let stream = b" text";
let mut buf = [b'#'; 25];
(&mut buf[..22]).copy_from_slice(b"GET / HTTP/1.1\r\n\r\nsome");
let mut r = BodyBytes::new(Cursor::new(&stream[..]), &mut buf[..], 18, 22);
assert_eq!(r.next().unwrap().unwrap(), b's');
assert_eq!(r.next().unwrap().unwrap(), b'o');
assert_eq!(r.next().unwrap().unwrap(), b'm');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b' ');
assert_eq!(r.next().unwrap().unwrap(), b't');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b'x');
assert_eq!(r.next().unwrap().unwrap(), b't');
assert!(r.next().is_none());
let stream = b"efghijklm";
let mut buf = [b'#'; 4];
(&mut buf[..]).copy_from_slice(b"abcd");
let mut r = BodyBytes::new(Cursor::new(&stream[..]), &mut buf[..], 2, 4);
assert_eq!(r.next().unwrap().unwrap(), b'c');
assert_eq!(r.next().unwrap().unwrap(), b'd');
assert_eq!(r.next().unwrap().unwrap(), b'e');
assert_eq!(r.next().unwrap().unwrap(), b'f');
assert_eq!(r.next().unwrap().unwrap(), b'g');
assert_eq!(r.next().unwrap().unwrap(), b'h');
assert_eq!(r.next().unwrap().unwrap(), b'i');
assert_eq!(r.next().unwrap().unwrap(), b'j');
assert_eq!(r.next().unwrap().unwrap(), b'k');
assert_eq!(r.next().unwrap().unwrap(), b'l');
assert_eq!(r.next().unwrap().unwrap(), b'm');
assert!(r.next().is_none());
}
}