use crate::read::EbmlSize; use self::read::EbmlReader; use anyhow::{bail, Result}; use log::debug; pub mod matroska; pub mod read; pub mod write; #[derive(Debug, Clone)] pub enum Master { Start, End, } #[derive(Debug, Clone)] pub enum MatroskaTag { Ebml(Master), EbmlVersion(u64), EbmlReadVersion(u64), EbmlMaxIdLength(u64), EbmlMaxSizeLength(u64), DocType(String), DocTypeVersion(u64), DocTypeReadVersion(u64), DocTypeExtension(Master), } impl EbmlReader { pub fn read_tag(&mut self) -> Result { let id = self.read_tag_id()?; let size = EbmlSize::from_vint(self.read_vint_len()?); debug!("tag id={id:x}, size={size:?}"); Ok(match id { 0x1a45dfa3 => MatroskaTag::Ebml(Master::Start), 0x4286 => MatroskaTag::EbmlVersion(self.read_vint()?), 0x42f7 => MatroskaTag::EbmlReadVersion(self.read_vint()?), 0x42f2 => MatroskaTag::EbmlMaxIdLength(self.read_vint()?), 0x42f3 => MatroskaTag::EbmlMaxSizeLength(self.read_vint()?), 0x4282 => MatroskaTag::DocType(self.read_utf8(size)?), 0x4287 => MatroskaTag::DocTypeVersion(self.read_vint()?), 0x4285 => MatroskaTag::DocTypeReadVersion(self.read_vint()?), 0x4281 => MatroskaTag::DocTypeExtension(Master::Start), _ => bail!("thats not a tag we know..."), }) } } pub trait ValueFromBuf: Sized { fn from_buf(buf: &[u8]) -> anyhow::Result; } impl ValueFromBuf for u64 { fn from_buf(buf: &[u8]) -> anyhow::Result { if buf.len() != 8 { bail!("u64 is not 64 bits long") } Ok((buf[0] as u64) << 24 | (buf[1] as u64) << 16 | (buf[2] as u64) << 8 | (buf[3] as u64) << 0) } } impl ValueFromBuf for Vec { fn from_buf(buf: &[u8]) -> anyhow::Result { Ok(buf.to_vec()) } } impl ValueFromBuf for String { fn from_buf(buf: &[u8]) -> anyhow::Result { Ok(String::from_utf8(Vec::from(buf))?) } } impl ValueFromBuf for Master { fn from_buf(_buf: &[u8]) -> anyhow::Result { Ok(Master::Start) } }