use std::io::Cursor;
use std::io::Error;
use std::io::ErrorKind;
use std::io::{self};
use qubit_io::Input;
const MAX_FRAME_LEN: usize = 64 * 1024;
fn read_frame<I>(input: &mut I) -> io::Result<Vec<u8>>
where
I: Input<Item = u8>,
{
let mut header = [0_u8; 4];
input.read_exactly(&mut header)?;
let length = u32::from_be_bytes(header) as usize;
if length > MAX_FRAME_LEN {
return Err(Error::new(ErrorKind::InvalidData, "frame is too large"));
}
let mut payload = vec![0_u8; length];
input.read_exactly(&mut payload)?;
Ok(payload)
}
fn main() -> io::Result<()> {
let mut frame = Cursor::new([0, 0, 0, 3, b'f', b'o', b'o']);
assert_eq!(b"foo", read_frame(&mut frame)?.as_slice());
let mut empty = Cursor::new([0, 0, 0, 0]);
assert!(read_frame(&mut empty)?.is_empty());
let mut oversized = Cursor::new(
u32::try_from(MAX_FRAME_LEN + 1)
.expect("frame limit fits in a u32")
.to_be_bytes(),
);
let oversized_error = read_frame(&mut oversized).expect_err("oversized frame must be rejected before allocation");
assert_eq!(ErrorKind::InvalidData, oversized_error.kind());
let mut truncated = Cursor::new([0, 0, 0, 2, b'x']);
let truncated_error = read_frame(&mut truncated).expect_err("truncated payload must fail");
assert_eq!(ErrorKind::UnexpectedEof, truncated_error.kind());
Ok(())
}