use std::io::{Read, Seek}; use anyhow::Result; trait ReadAndSeek: Read + Seek {} impl ReadAndSeek for T {} pub struct EbmlReader { inner: Box, pub position: usize, } pub trait EbmlRead: Sized { fn read(r: &mut EbmlReader) -> Result; } impl EbmlReader { pub fn new(inner: T) -> Self { Self { inner: Box::new(inner), position: 0, } } pub fn read_byte(&mut self) -> Result { let mut b = [0u8]; self.inner.read_exact(&mut b)?; self.position += 1; Ok(b[0]) } pub fn read_buf(&mut self, size: impl Into) -> Result> { let size = size.into(); let mut b = vec![0u8; size]; self.inner.read_exact(&mut b)?; self.position += size; Ok(b) } pub fn read_vint_len(&mut self) -> Result<(u64, usize)> { let s = self.read_byte()?; let len = s.leading_zeros() + 1; let mut value = s as u64; value -= 1 << (8 - len); for _ in 0..(len - 1) { value <<= 8; value += self.read_byte()? as u64; } Ok((value, len as usize)) } pub fn read_vint(&mut self) -> Result { Ok(self.read_vint_len()?.0) } pub fn read_utf8(&mut self, size: impl Into) -> Result { let b = self.read_buf(size)?; Ok(String::from_utf8(b)?) } pub fn read_tag_id(&mut self) -> Result { let (value, len) = self.read_vint_len()?; Ok(value + (1 << (7 * len))) } } #[derive(Debug, Clone, Copy)] pub enum EbmlSize { Exact(usize), Unknown, } impl EbmlSize { #[rustfmt::skip] pub fn from_vint((value, len): (u64, usize)) -> EbmlSize { match len { 1 => if value == ((1 << (7)) - 1) { return Self::Unknown; }, 2 => if value == ((1 << (7 * 2)) - 1) { return Self::Unknown; }, 3 => if value == ((1 << (7 * 3)) - 1) { return Self::Unknown; }, 4 => if value == ((1 << (7 * 4)) - 1) { return Self::Unknown; }, 5 => if value == ((1 << (7 * 5)) - 1) { return Self::Unknown; }, 6 => if value == ((1 << (7 * 6)) - 1) { return Self::Unknown; }, 7 => if value == ((1 << (7 * 7)) - 1) { return Self::Unknown; }, 8 => if value == ((1 << (7 * 8)) - 1) { return Self::Unknown; }, _ => {}, } Self::Exact(len) } } impl Into for EbmlSize { fn into(self) -> usize { match self { EbmlSize::Exact(s) => s, EbmlSize::Unknown => panic!("unknown size, where it should have been known"), } } }