use crate::error::Error;
pub struct TlsReader<'a> {
bytes: &'a [u8],
position: usize,
}
impl<'a> TlsReader<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self { bytes, position: 0 }
}
pub fn remaining(&self) -> usize {
self.bytes.len() - self.position
}
pub fn is_empty(&self) -> bool {
self.remaining() == 0
}
pub fn read_u8(&mut self) -> Result<u8, Error> {
Ok(self.read_bytes(1)?[0])
}
pub fn read_u16(&mut self) -> Result<u16, Error> {
Ok(u16::from_be_bytes(self.read_array::<2>()?))
}
pub fn read_u24(&mut self) -> Result<usize, Error> {
let bytes = self.read_array::<3>()?;
Ok((usize::from(bytes[0]) << 16) | (usize::from(bytes[1]) << 8) | usize::from(bytes[2]))
}
pub fn read_bytes(&mut self, len: usize) -> Result<&'a [u8], Error> {
let remaining = self.remaining();
if remaining < len {
return Err(Error::UnexpectedEof {
needed: len,
remaining,
});
}
let start = self.position;
let end = start + len;
self.position = end;
Ok(&self.bytes[start..end])
}
pub fn read_array<const N: usize>(&mut self) -> Result<[u8; N], Error> {
let bytes = self.read_bytes(N)?;
Ok(bytes
.try_into()
.expect("slice length must match requested array length"))
}
}