use std::io::{Read};
use std::error::Error as stdError;
use thiserror::Error;
use std::fmt::{Display, Formatter};
#[derive(Error, Debug)]
pub enum DataDecodeError {
#[error(transparent)]
IO(#[from] std::io::Error),
#[error(transparent)]
InvalidData(#[from] InvalidDataError)
}
#[non_exhaustive]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum InvalidDataError{
NotEnoughBytes,
IntegerOverflow,
InvalidUtf8
}
impl Display for InvalidDataError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
Self::NotEnoughBytes => write!(f, "not enough bytes to decode"),
Self::IntegerOverflow => write!(f, "decoded integer overflowed"),
Self::InvalidUtf8 => write!(f, "data could not be decoded as valid utf8"),
}
}
}
impl stdError for InvalidDataError{
fn source(&self) -> Option<&(dyn stdError + 'static)> {
None }
fn description(&self) -> &str {
"use of deprecated description() method on std::error::Error"
}
fn cause(&self) -> Option<&dyn stdError> {
None }
}
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct BinaryReader<T: Read> {
input: T,
buf: Vec<u8>,
num_bytes_read: u64
}
impl<T> BinaryReader<T>
where T: Read {
pub fn new(input: T) -> Self {
Self {
input,
buf: Vec::new(),
num_bytes_read: 0
}
}
pub fn num_bytes_read(&self) -> u64 {
self.num_bytes_read
}
fn ensure_internal_buffer_size(&mut self, min_size: usize) -> Result<bool, std::io::Error>{
if self.buf.len() >= min_size {
return Ok(true);
}
self.input.read_to_end(&mut self.buf)?;
Ok(self.buf.len() >= min_size)
}
pub fn read_byte(&mut self) -> Result<u8, DataDecodeError> {
Ok(self.read_bytes(1)?[0])
}
pub fn read_bytes(&mut self, num_bytes: usize) -> Result<Vec<u8>, DataDecodeError> {
if num_bytes > self.buf.len() && !self.ensure_internal_buffer_size(num_bytes)? {
return Err(DataDecodeError::InvalidData(InvalidDataError::NotEnoughBytes))
}
self.num_bytes_read += num_bytes as u64;
Ok(Vec::from_iter(self.buf.drain(0..num_bytes)))
}
pub fn peek_byte(&mut self) -> Result<u8, DataDecodeError> {
Ok(self.peek_bytes(1)?[0])
}
pub fn peek_bytes(&mut self, num_bytes: usize) -> Result<&[u8], DataDecodeError> {
if !self.ensure_internal_buffer_size(num_bytes)? {
Err(DataDecodeError::InvalidData(InvalidDataError::NotEnoughBytes))
} else {
Ok(&self.buf.as_slice()[1..num_bytes])
}
}
pub fn read_7_bit_encoded_int(&mut self) -> Result<i32, DataDecodeError> {
const MAX_BYTES: u32 = 5;
let mut output: i32 = 0;
let mut bytes_read = 0;
loop {
let byte = self.read_byte()?;
let lower_bits = byte & 0b01111111;
let high_bit = byte & 0b10000000;
output += (lower_bits as i32) << (7 * bytes_read);
if high_bit == 0 {
return Ok(output)
}
bytes_read+=1;
if bytes_read >= MAX_BYTES - 1{
break; }
}
let max_value_for_most_significant_bit = u8::pow(2, 32 - 28) - 1;
let last_byte: u8 = self.read_byte()?;
if last_byte > max_value_for_most_significant_bit {
Err(DataDecodeError::InvalidData(InvalidDataError::IntegerOverflow))
} else {
Ok(output + ((last_byte as i32) << 28_i32))
}
}
pub fn read_7_bit_encoded_int64(&mut self) -> Result<i64, DataDecodeError> {
const MAX_BYTES: u32 = 10;
let mut output: i64 = 0;
let mut bytes_read = 0;
loop {
let byte: u8 = self.read_byte()?;
let lower_bits = byte & 0b01111111;
let high_bit = byte & 0b10000000;
output += (lower_bits as i64) << (7 * bytes_read);
if high_bit == 0 {
return Ok(output);
}
bytes_read+=1;
if bytes_read >= MAX_BYTES - 1 {
break;
}
}
let max_value_for_most_significant_bit = u8::pow(2, 64 - 63) - 1;
let last_byte = self.read_byte()?;
if last_byte > max_value_for_most_significant_bit {
Err(InvalidDataError::IntegerOverflow.into())
} else {
Ok(output + ((last_byte as i64) << 63))
}
}
pub fn read_boolean(&mut self) -> Result<bool, DataDecodeError> {
let byte = self.read_byte()?;
Ok(byte != 0)
}
pub fn read_f32(&mut self) -> Result<f32, DataDecodeError> {
let bytes: [u8; 4] = self.read_bytes(4)?.try_into().unwrap();
Ok(f32::from_le_bytes(bytes))
}
pub fn read_f64(&mut self) -> Result<f64, DataDecodeError> {
let bytes: [u8; 8] = self.read_bytes(8)?.try_into().unwrap();
Ok(f64::from_le_bytes(bytes))
}
#[cfg_attr(docsrs, doc(cfg(feature = "f16")))]
#[cfg(feature = "f16")]
pub fn read_f16(&mut self) -> Result<f16, DataDecodeError> {
let bytes: [u8; 2] = self.read_bytes(2)?.try_into().unwrap();
Ok(f16::from_le_bytes(bytes))
}
pub fn read_string(&mut self) -> Result<String, DataDecodeError> {
let length: usize = self.read_7_bit_encoded_int()?.try_into().unwrap();
let string_bytes = self.read_bytes(length)?;
match std::str::from_utf8(string_bytes.as_slice()) {
Ok(v) => Ok(v.to_string()),
Err(_) => Err(DataDecodeError::InvalidData(InvalidDataError::InvalidUtf8))
}
}
pub fn read_i8(&mut self) -> Result<i8, DataDecodeError> {
let bytes: [u8; 1] = [self.read_byte()?];
Ok(i8::from_le_bytes(bytes))
}
pub fn read_i16(&mut self) -> Result<i16, DataDecodeError> {
let bytes: [u8; 2] = self.read_bytes(2)?.try_into().unwrap();
Ok(i16::from_le_bytes(bytes))
}
pub fn read_i32(&mut self) -> Result<i32, DataDecodeError> {
let bytes: [u8; 4] = self.read_bytes(4)?.try_into().unwrap();
Ok(i32::from_le_bytes(bytes))
}
pub fn read_i64(&mut self) -> Result<i64, DataDecodeError> {
let bytes: [u8; 8] = self.read_bytes(8)?.try_into().unwrap();
Ok(i64::from_le_bytes(bytes))
}
pub fn read_u16(&mut self) -> Result<u16, DataDecodeError> {
let bytes: [u8; 2] = self.read_bytes(2)?.try_into().unwrap();
Ok(u16::from_le_bytes(bytes))
}
pub fn read_u32(&mut self) -> Result<u32, DataDecodeError> {
let bytes: [u8; 4] = self.read_bytes(4)?.try_into().unwrap();
Ok(u32::from_le_bytes(bytes))
}
pub fn read_u64(&mut self) -> Result<u64, DataDecodeError> {
let bytes: [u8; 8] = self.read_bytes(8)?.try_into().unwrap();
Ok(u64::from_le_bytes(bytes))
}
pub fn read_char(&mut self) -> Result<char, DataDecodeError> {
const MAX_BYTES_PER_CHAR: usize = 4;
let mut bytes: [u8; MAX_BYTES_PER_CHAR] = [0; MAX_BYTES_PER_CHAR];
let mut current_index: usize = 0;
let mut num_chars_read: usize = 0;
let mut decode_result: Result<String, std::string::FromUtf8Error>;
loop {
bytes[current_index] = self.read_byte()?;
decode_result = String::from_utf8(bytes.to_vec());
if let Ok(result) = &decode_result {
let mut result = result.as_str();
while result.chars().last() == Some(char::from(0)) && result.chars().collect::<Vec<_>>().len() > 1 {
result = &result[0..result.len() - 1];
}
num_chars_read = result.chars().count();
break;
} else {
current_index+=1;
if current_index >= MAX_BYTES_PER_CHAR {
break;
}
}
}
if num_chars_read == 1 {
if let Ok(result) = decode_result {
return Ok(result.chars().next().expect("?"))
}
}
Err(DataDecodeError::InvalidData(InvalidDataError::InvalidUtf8)) }
}