From b192ec740d358d0e12eedd1308d006e080b3d8c2 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 13 Jan 2023 17:12:47 +0100 Subject: new starting with a new ebml impl --- ebml/src/read.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 ebml/src/read.rs (limited to 'ebml/src/read.rs') diff --git a/ebml/src/read.rs b/ebml/src/read.rs new file mode 100644 index 0000000..0ffb24c --- /dev/null +++ b/ebml/src/read.rs @@ -0,0 +1,96 @@ +use std::io::{Read, Seek}; + +use anyhow::{bail, Result}; +use log::debug; +use webm_iterable::matroska_spec::MatroskaSpec; + +use crate::format::matroska::{Master, MatroskaTag}; + +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"), + } + } +} -- cgit v1.2.3-70-g09d2