use std::io::{Error, ErrorKind, Read};
const BUFFER_SIZE: usize = 65_536;
const MIN_PEEK_REQUIREMENT: usize = 8;
#[derive(Debug)]
pub struct ByteBuffer<R> {
reader: R,
buffer: [u8; BUFFER_SIZE],
next_byte_index: usize,
stop_byte_index: usize,
}
impl<R> ByteBuffer<R>
where
R: Read,
{
pub fn wrap(reader: R) -> ByteBuffer<R> {
ByteBuffer {
reader,
buffer: [0_u8; BUFFER_SIZE],
next_byte_index: 0,
stop_byte_index: 0,
}
}
fn is_buffer_empty(&self) -> bool {
self.stop_byte_index == self.next_byte_index
}
fn fill_buffer(&mut self) -> Result<(), Error> {
loop {
let outcome = self.reader.read(&mut self.buffer);
if let Err(e) = outcome {
if e.kind() == ErrorKind::Interrupted {
continue;
} else {
return Err(e);
}
} else {
self.stop_byte_index = outcome?;
self.next_byte_index = 0;
return Ok(());
}
}
}
pub fn read_next(&mut self) -> Result<Option<u8>, Error> {
if self.is_buffer_empty() {
self.fill_buffer()?;
}
if self.is_buffer_empty() {
return Ok(None);
}
let byte = self.buffer[self.next_byte_index];
self.next_byte_index += 1;
Ok(Some(byte))
}
pub fn peek(&mut self) -> Result<&[u8], Error> {
if self.is_buffer_empty() {
self.fill_buffer()?;
}
if self.is_buffer_empty() {
return Ok(&[0_u8; 0]);
}
if (BUFFER_SIZE - self.next_byte_index) < MIN_PEEK_REQUIREMENT {
self.shunt_to_left();
}
while (self.stop_byte_index - self.next_byte_index) < MIN_PEEK_REQUIREMENT {
if self.top_up_buffer()? == 0 {
break;
}
}
Ok(&self.buffer[self.next_byte_index..self.stop_byte_index])
}
fn shunt_to_left(&mut self) {
let length = self.stop_byte_index - self.next_byte_index;
for i in 0..length {
self.buffer[i] = self.buffer[self.next_byte_index + i];
}
self.next_byte_index = 0;
self.stop_byte_index = length;
}
fn top_up_buffer(&mut self) -> Result<usize, Error> {
loop {
let outcome = self
.reader
.read(&mut self.buffer[self.stop_byte_index..BUFFER_SIZE]);
if let Err(e) = outcome {
if e.kind() == ErrorKind::Interrupted {
continue;
} else {
return Err(e);
}
} else {
let read_count = outcome?;
self.stop_byte_index += read_count;
return Ok(read_count);
}
}
}
}
#[cfg(test)]
mod tests {
use std::io::Cursor;
use super::*;
#[test]
fn test_read_next() -> Result<(), Error> {
let bytes = [0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
let mut buffer = ByteBuffer::wrap(&bytes[..]);
assert_eq!(buffer.read_next()?, Some(0xEF));
assert_eq!(buffer.read_next()?, Some(0xBB));
assert_eq!(buffer.read_next()?, Some(0xBF));
assert_eq!(buffer.read_next()?, Some(0x3C));
assert_eq!(buffer.read_next()?, Some(0x3F));
assert_eq!(buffer.read_next()?, Some(0x78));
assert_eq!(buffer.read_next()?, Some(0x6D));
assert_eq!(buffer.read_next()?, Some(0x6C));
assert_eq!(buffer.read_next()?, Some(0x20));
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn accepts_mut_ref_read() -> Result<(), Error> {
let mut cursor = Cursor::new("some input");
let mut buffer = ByteBuffer::wrap(&mut cursor);
assert_eq!(buffer.read_next()?, Some(0x73));
let mut mini_buffer = [0_u8; 1];
let read_count = cursor.read(&mut mini_buffer)?;
assert!(read_count < 2);
Ok(())
}
#[test]
fn test_read_next_empty_input() -> Result<(), Error> {
let bytes: [u8; 0] = [];
let mut buffer = ByteBuffer::wrap(&bytes[..]);
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_peek_input_exceeds_buffer_size() -> Result<(), Error> {
let start_of_xml_bytes: [u8; 22] = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
let mut bytes: Vec<u8> = Vec::with_capacity(BUFFER_SIZE + start_of_xml_bytes.len());
bytes.resize(BUFFER_SIZE, 0x20);
for b in start_of_xml_bytes {
bytes.push(b);
}
let mut buffer = ByteBuffer::wrap(&bytes[..]);
for _ in 0..(BUFFER_SIZE - 4) {
assert_eq!(buffer.read_next()?, Some(0x20));
}
assert_eq!(buffer.next_byte_index, BUFFER_SIZE - 4);
assert_eq!(buffer.stop_byte_index, BUFFER_SIZE);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(peek[0], 0x20);
assert_eq!(peek[1], 0x20);
assert_eq!(peek[2], 0x20);
assert_eq!(peek[3], 0x20);
assert_eq!(peek[4], 0xEF);
assert_eq!(peek[5], 0xBB);
assert_eq!(peek[6], 0xBF);
assert_eq!(peek[7], 0x3C);
Ok(())
}
#[test]
fn test_peek() -> Result<(), Error> {
let bytes = [0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
assert!(bytes.len() < MIN_PEEK_REQUIREMENT);
let mut buffer = ByteBuffer::wrap(&bytes[..]);
let peek = buffer.peek()?;
assert_eq!(peek.len(), 7);
assert_eq!(peek, &bytes);
Ok(())
}
#[test]
fn test_peek_after_read() -> Result<(), Error> {
let bytes = [0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
let mut buffer = ByteBuffer::wrap(&bytes[..]);
buffer.read_next()?;
buffer.read_next()?;
buffer.read_next()?;
let peek = buffer.peek()?;
assert_eq!(peek.len(), 4);
assert_eq!(peek, &bytes[3..]);
Ok(())
}
#[test]
fn test_peek_minimum() -> Result<(), Error> {
let bytes = [0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
assert!(bytes.len() > MIN_PEEK_REQUIREMENT);
let mut buffer = ByteBuffer::wrap(&bytes[..]);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(
&peek[0..MIN_PEEK_REQUIREMENT],
&bytes[0..MIN_PEEK_REQUIREMENT]
);
Ok(())
}
#[test]
fn test_peek_after_shunt() -> Result<(), Error> {
let bytes = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
assert!(bytes.len() > MIN_PEEK_REQUIREMENT);
let mut buffer = ByteBuffer::wrap(&bytes[..]);
let initial_read_size = 8;
for _ in 0..initial_read_size {
buffer.read_next()?;
}
let previous_next_index = buffer.next_byte_index;
let previous_stop_index = buffer.stop_byte_index;
buffer.shunt_to_left();
assert_eq!(buffer.next_byte_index, 0);
assert_eq!(
buffer.stop_byte_index,
previous_stop_index - previous_next_index
);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(
&peek[0..MIN_PEEK_REQUIREMENT],
&bytes[initial_read_size..(MIN_PEEK_REQUIREMENT + initial_read_size)]
);
assert_eq!(buffer.read_next()?, Some(bytes[initial_read_size]));
Ok(())
}
struct SlowReader {
content: Vec<u8>,
next_index: usize,
}
impl SlowReader {
fn new(content: Vec<u8>) -> Self {
SlowReader {
content,
next_index: 0,
}
}
}
impl Read for SlowReader {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.next_index == self.content.len() {
Ok(0)
} else {
buf[0] = self.content[self.next_index];
self.next_index += 1;
Ok(1)
}
}
}
#[test]
fn test_peek_slow_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
let slow_reader = SlowReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(slow_reader);
let peek = buffer.peek()?;
assert_eq!(peek.len(), 7);
assert_eq!(peek, &bytes);
Ok(())
}
#[test]
fn test_peek_after_read_slow_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
let slow_reader = SlowReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(slow_reader);
buffer.read_next()?;
buffer.read_next()?;
buffer.read_next()?;
let peek = buffer.peek()?;
assert_eq!(peek.len(), 4);
assert_eq!(peek, &bytes[3..]);
Ok(())
}
#[test]
fn test_peek_minimum_slow_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
let slow_reader = SlowReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(slow_reader);
let peek = buffer.peek()?;
assert_eq!(peek.len(), MIN_PEEK_REQUIREMENT);
assert_eq!(peek, &bytes[0..MIN_PEEK_REQUIREMENT]);
Ok(())
}
#[test]
fn test_peek_after_shunt_slow_read() -> Result<(), Error> {
let bytes = vec![
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
assert!(bytes.len() > MIN_PEEK_REQUIREMENT);
let slow_reader = SlowReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(slow_reader);
let initial_read_size = 8;
for _ in 0..initial_read_size {
buffer.read_next()?;
}
let previous_next_index = buffer.next_byte_index;
let previous_stop_index = buffer.stop_byte_index;
buffer.shunt_to_left();
assert_eq!(buffer.next_byte_index, 0);
assert_eq!(
buffer.stop_byte_index,
previous_stop_index - previous_next_index
);
let peek = buffer.peek()?;
assert!(peek.len() == MIN_PEEK_REQUIREMENT);
assert_eq!(
&peek[0..MIN_PEEK_REQUIREMENT],
&bytes[initial_read_size..(MIN_PEEK_REQUIREMENT + initial_read_size)]
);
assert_eq!(buffer.read_next()?, Some(bytes[initial_read_size]));
Ok(())
}
#[test]
fn test_read_next_slow_reader() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
let slow_reader = SlowReader::new(bytes);
let mut buffer = ByteBuffer::wrap(slow_reader);
assert_eq!(buffer.read_next()?, Some(0xEF));
assert_eq!(buffer.read_next()?, Some(0xBB));
assert_eq!(buffer.read_next()?, Some(0xBF));
assert_eq!(buffer.read_next()?, Some(0x3C));
assert_eq!(buffer.read_next()?, Some(0x3F));
assert_eq!(buffer.read_next()?, Some(0x78));
assert_eq!(buffer.read_next()?, Some(0x6D));
assert_eq!(buffer.read_next()?, Some(0x6C));
assert_eq!(buffer.read_next()?, Some(0x20));
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_read_next_empty_input_slow_reader() -> Result<(), Error> {
let bytes = vec![];
let slow_reader = SlowReader::new(bytes);
let mut buffer = ByteBuffer::wrap(slow_reader);
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_read_next_slow_reader_input_exceeds_buffer_size() -> Result<(), Error> {
let start_of_xml_bytes: [u8; 22] = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
let mut bytes: Vec<u8> = Vec::with_capacity(BUFFER_SIZE + start_of_xml_bytes.len());
bytes.resize(BUFFER_SIZE, 0x20);
for b in start_of_xml_bytes {
bytes.push(b);
}
let slow_reader = SlowReader::new(bytes);
let mut buffer = ByteBuffer::wrap(slow_reader);
for _ in 0..BUFFER_SIZE {
assert_eq!(buffer.read_next()?, Some(0x20));
}
assert_eq!(buffer.read_next()?, Some(0xEF));
assert_eq!(buffer.read_next()?, Some(0xBB));
assert_eq!(buffer.read_next()?, Some(0xBF));
assert_eq!(buffer.read_next()?, Some(0x3C));
assert_eq!(buffer.read_next()?, Some(0x3F));
assert_eq!(buffer.read_next()?, Some(0x78));
assert_eq!(buffer.read_next()?, Some(0x6D));
assert_eq!(buffer.read_next()?, Some(0x6C));
assert_eq!(buffer.read_next()?, Some(0x20));
assert_eq!(buffer.read_next()?, Some(0x76));
assert_eq!(buffer.read_next()?, Some(0x65));
assert_eq!(buffer.read_next()?, Some(0x72));
assert_eq!(buffer.read_next()?, Some(0x73));
assert_eq!(buffer.read_next()?, Some(0x69));
assert_eq!(buffer.read_next()?, Some(0x6F));
assert_eq!(buffer.read_next()?, Some(0x6E));
assert_eq!(buffer.read_next()?, Some(0x3D));
assert_eq!(buffer.read_next()?, Some(0x22));
assert_eq!(buffer.read_next()?, Some(0x31));
assert_eq!(buffer.read_next()?, Some(0x2E));
assert_eq!(buffer.read_next()?, Some(0x30));
assert_eq!(buffer.read_next()?, Some(0x22));
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_peek_slow_reader_input_exceeds_buffer_size() -> Result<(), Error> {
let start_of_xml_bytes: [u8; 22] = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
let mut bytes: Vec<u8> = Vec::with_capacity(BUFFER_SIZE + start_of_xml_bytes.len());
bytes.resize(BUFFER_SIZE, 0x20);
for b in start_of_xml_bytes {
bytes.push(b);
}
let slow_reader = SlowReader::new(bytes);
let mut buffer = ByteBuffer::wrap(slow_reader);
for _ in 0..(BUFFER_SIZE - 4) {
assert_eq!(buffer.read_next()?, Some(0x20));
}
let peek = buffer.peek()?;
assert_eq!(peek.len(), MIN_PEEK_REQUIREMENT);
assert_eq!(peek[0], 0x20);
assert_eq!(peek[1], 0x20);
assert_eq!(peek[2], 0x20);
assert_eq!(peek[3], 0x20);
assert_eq!(peek[4], 0xEF);
assert_eq!(peek[5], 0xBB);
assert_eq!(peek[6], 0xBF);
assert_eq!(peek[7], 0x3C);
Ok(())
}
struct DistractedReader {
content: Vec<u8>,
next_index: usize,
next_read_will_be_interrupted: bool,
}
impl DistractedReader {
fn new(content: Vec<u8>) -> Self {
DistractedReader {
content,
next_index: 0,
next_read_will_be_interrupted: true,
}
}
}
impl Read for DistractedReader {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.next_read_will_be_interrupted {
self.next_read_will_be_interrupted = false;
return Err(Error::new(
std::io::ErrorKind::Interrupted,
"Deliberate interrupt for test purposes!",
));
}
self.next_read_will_be_interrupted = true;
if self.next_index == self.content.len() {
Ok(0)
} else {
let read_limit = buf.len().min(self.content.len() - self.next_index);
buf[..read_limit].copy_from_slice(&self.content[self.next_index..][..read_limit]);
self.next_index += read_limit;
Ok(read_limit)
}
}
}
#[test]
fn test_peek_distracted_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
let distracted_reader = DistractedReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(distracted_reader);
let peek = buffer.peek()?;
assert_eq!(peek.len(), 7);
assert_eq!(peek, &bytes);
Ok(())
}
#[test]
fn test_peek_after_read_distracted_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D];
let distracted_reader = DistractedReader::new(bytes);
let mut buffer = ByteBuffer::wrap(distracted_reader);
buffer.read_next()?;
buffer.read_next()?;
buffer.read_next()?;
let peek = buffer.peek()?;
assert_eq!(peek.len(), 4);
assert_eq!(peek, &vec![0x3C, 0x3F, 0x78, 0x6D]);
Ok(())
}
#[test]
fn test_peek_minimum_distracted_read() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
let distracted_reader = DistractedReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(distracted_reader);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(
&peek[0..MIN_PEEK_REQUIREMENT],
&bytes[0..MIN_PEEK_REQUIREMENT]
);
Ok(())
}
#[test]
fn test_peek_after_shunt_distracted_read() -> Result<(), Error> {
let bytes = vec![
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
assert!(bytes.len() > MIN_PEEK_REQUIREMENT);
let distracted_reader = DistractedReader::new(bytes.clone());
let mut buffer = ByteBuffer::wrap(distracted_reader);
let initial_read_size = 8;
for _ in 0..initial_read_size {
buffer.read_next()?;
}
let previous_next_index = buffer.next_byte_index;
let previous_stop_index = buffer.stop_byte_index;
buffer.shunt_to_left();
assert_eq!(buffer.next_byte_index, 0);
assert_eq!(
buffer.stop_byte_index,
previous_stop_index - previous_next_index
);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(
&peek[0..MIN_PEEK_REQUIREMENT],
&bytes[initial_read_size..(MIN_PEEK_REQUIREMENT + initial_read_size)]
);
assert_eq!(buffer.read_next()?, Some(bytes[initial_read_size]));
Ok(())
}
#[test]
fn test_read_next_distracted_reader() -> Result<(), Error> {
let bytes = vec![0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20];
let distracted_reader = DistractedReader::new(bytes);
let mut buffer = ByteBuffer::wrap(distracted_reader);
assert_eq!(buffer.read_next()?, Some(0xEF));
assert_eq!(buffer.read_next()?, Some(0xBB));
assert_eq!(buffer.read_next()?, Some(0xBF));
assert_eq!(buffer.read_next()?, Some(0x3C));
assert_eq!(buffer.read_next()?, Some(0x3F));
assert_eq!(buffer.read_next()?, Some(0x78));
assert_eq!(buffer.read_next()?, Some(0x6D));
assert_eq!(buffer.read_next()?, Some(0x6C));
assert_eq!(buffer.read_next()?, Some(0x20));
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_read_next_empty_input_distracted_reader() -> Result<(), Error> {
let bytes = vec![];
let distracted_reader = DistractedReader::new(bytes);
let mut buffer = ByteBuffer::wrap(distracted_reader);
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_read_next_distracted_reader_input_exceeds_buffer_size() -> Result<(), Error> {
let start_of_xml_bytes: [u8; 22] = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
let mut bytes: Vec<u8> = Vec::with_capacity(BUFFER_SIZE + start_of_xml_bytes.len());
bytes.resize(BUFFER_SIZE, 0x20);
for b in start_of_xml_bytes {
bytes.push(b);
}
let distracted_reader = DistractedReader::new(bytes);
let mut buffer = ByteBuffer::wrap(distracted_reader);
for _ in 0..BUFFER_SIZE {
assert_eq!(buffer.read_next()?, Some(0x20));
}
assert_eq!(buffer.read_next()?, Some(0xEF));
assert_eq!(buffer.read_next()?, Some(0xBB));
assert_eq!(buffer.read_next()?, Some(0xBF));
assert_eq!(buffer.read_next()?, Some(0x3C));
assert_eq!(buffer.read_next()?, Some(0x3F));
assert_eq!(buffer.read_next()?, Some(0x78));
assert_eq!(buffer.read_next()?, Some(0x6D));
assert_eq!(buffer.read_next()?, Some(0x6C));
assert_eq!(buffer.read_next()?, Some(0x20));
assert_eq!(buffer.read_next()?, Some(0x76));
assert_eq!(buffer.read_next()?, Some(0x65));
assert_eq!(buffer.read_next()?, Some(0x72));
assert_eq!(buffer.read_next()?, Some(0x73));
assert_eq!(buffer.read_next()?, Some(0x69));
assert_eq!(buffer.read_next()?, Some(0x6F));
assert_eq!(buffer.read_next()?, Some(0x6E));
assert_eq!(buffer.read_next()?, Some(0x3D));
assert_eq!(buffer.read_next()?, Some(0x22));
assert_eq!(buffer.read_next()?, Some(0x31));
assert_eq!(buffer.read_next()?, Some(0x2E));
assert_eq!(buffer.read_next()?, Some(0x30));
assert_eq!(buffer.read_next()?, Some(0x22));
assert_eq!(buffer.read_next()?, None);
Ok(())
}
#[test]
fn test_peek_distracted_reader_input_exceeds_buffer_size() -> Result<(), Error> {
let start_of_xml_bytes: [u8; 22] = [
0xEF, 0xBB, 0xBF, 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22,
];
let mut bytes: Vec<u8> = Vec::with_capacity(BUFFER_SIZE + start_of_xml_bytes.len());
bytes.resize(BUFFER_SIZE, 0x20);
for b in start_of_xml_bytes {
bytes.push(b);
}
let distracted_reader = DistractedReader::new(bytes);
let mut buffer = ByteBuffer::wrap(distracted_reader);
for _ in 0..(BUFFER_SIZE - 4) {
assert_eq!(buffer.read_next()?, Some(0x20));
}
assert_eq!(buffer.next_byte_index, BUFFER_SIZE - 4);
assert_eq!(buffer.stop_byte_index, BUFFER_SIZE);
let peek = buffer.peek()?;
assert!(peek.len() >= MIN_PEEK_REQUIREMENT);
assert_eq!(peek[0], 0x20);
assert_eq!(peek[1], 0x20);
assert_eq!(peek[2], 0x20);
assert_eq!(peek[3], 0x20);
assert_eq!(peek[4], 0xEF);
assert_eq!(peek[5], 0xBB);
assert_eq!(peek[6], 0xBF);
assert_eq!(peek[7], 0x3C);
Ok(())
}
}