diff options
Diffstat (limited to 'matroska')
-rw-r--r-- | matroska/Cargo.toml | 2 | ||||
-rw-r--r-- | matroska/src/bin/experiment.rs | 11 | ||||
-rw-r--r-- | matroska/src/bin/mkvdump.rs | 7 | ||||
-rw-r--r-- | matroska/src/block.rs | 2 | ||||
-rw-r--r-- | matroska/src/error.rs | 19 | ||||
-rw-r--r-- | matroska/src/lib.rs | 4 | ||||
-rw-r--r-- | matroska/src/read.rs | 45 | ||||
-rw-r--r-- | matroska/src/unflatten.rs | 3 | ||||
-rw-r--r-- | matroska/src/write.rs | 17 |
9 files changed, 67 insertions, 43 deletions
diff --git a/matroska/Cargo.toml b/matroska/Cargo.toml index e38e028..01a3be9 100644 --- a/matroska/Cargo.toml +++ b/matroska/Cargo.toml @@ -5,6 +5,6 @@ edition = "2021" [dependencies] ebml_derive = { path = "../ebml_derive" } -anyhow = "1.0.72" log = "0.4.19" env_logger = "0.10.0" +thiserror = "1.0.44" diff --git a/matroska/src/bin/experiment.rs b/matroska/src/bin/experiment.rs index fe3096e..4a8c420 100644 --- a/matroska/src/bin/experiment.rs +++ b/matroska/src/bin/experiment.rs @@ -11,10 +11,10 @@ use std::{ io::{stdout, BufReader, BufWriter}, }; -fn main() -> anyhow::Result<()> { +fn main() { env_logger::init_from_env("LOG"); let path = std::env::args().nth(1).unwrap(); - let mut r = EbmlReader::new(BufReader::new(File::open(path)?)); + let mut r = EbmlReader::new(BufReader::new(File::open(path).unwrap())); let mut w = EbmlWriter::new(BufWriter::new(stdout()), 0); // r.seek( @@ -24,11 +24,10 @@ fn main() -> anyhow::Result<()> { // .unwrap(); while let Some(tag) = r.next() { - let tag = tag?; - if MatroskaTag::is_master(tag.id())? { + let tag = tag.unwrap(); + if MatroskaTag::is_master(tag.id()).unwrap() { eprintln!("{tag:?}"); } - w.write_tag(&tag)?; + w.write_tag(&tag).unwrap(); } - Ok(()) } diff --git a/matroska/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs index ead6ece..4db1223 100644 --- a/matroska/src/bin/mkvdump.rs +++ b/matroska/src/bin/mkvdump.rs @@ -6,18 +6,17 @@ use jellymatroska::{matroska::MatroskaTag, read::EbmlReader, unflatten::IterWithPos}; use std::{fs::File, io::BufReader}; -fn main() -> anyhow::Result<()> { +fn main() { env_logger::init_from_env("LOG"); let path = std::env::args().nth(1).unwrap(); - let mut r = EbmlReader::new(BufReader::new(File::open(path)?)); + let mut r = EbmlReader::new(BufReader::new(File::open(path).unwrap())); while let Some(tag) = r.next() { - let tag = tag?; + let tag = tag.unwrap(); match tag { MatroskaTag::SimpleBlock(_) => (), // println!("{} SimpleBlock", r.position), MatroskaTag::Block(_) => (), // println!("{} Block", r.position), _ => println!("{} {tag:?}", r.position), } } - Ok(()) } diff --git a/matroska/src/block.rs b/matroska/src/block.rs index 676b042..275066e 100644 --- a/matroska/src/block.rs +++ b/matroska/src/block.rs @@ -4,7 +4,7 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use crate::{read::ReadExt, write::write_vint}; -use anyhow::Result; +use crate::Result; use std::io::Cursor; pub enum LacingType { diff --git a/matroska/src/error.rs b/matroska/src/error.rs new file mode 100644 index 0000000..02e487d --- /dev/null +++ b/matroska/src/error.rs @@ -0,0 +1,19 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error("invalid padding")] + InvalidPadding, + #[error("varint too long")] + VarintTooLong, + #[error("global tags dont provide any context")] + GlobalTagsAsContext, + #[error("invalid length of a exact size type")] + InvalidTypeLen, + #[error("invalid utf8")] + InvalidUTF8, + #[error("unknown id")] + UnknownID, + #[error("io: {0}")] + Io(std::io::Error), +} diff --git a/matroska/src/lib.rs b/matroska/src/lib.rs index b86af44..b2d052c 100644 --- a/matroska/src/lib.rs +++ b/matroska/src/lib.rs @@ -4,6 +4,7 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ pub mod block; +pub mod error; pub mod matroska; pub mod read; pub mod size; @@ -20,3 +21,6 @@ pub enum Master { Start, End, } + +pub(crate) use error::Error; +pub(crate) type Result<T> = core::result::Result<T, Error>; diff --git a/matroska/src/read.rs b/matroska/src/read.rs index e2bf15c..cb3e45e 100644 --- a/matroska/src/read.rs +++ b/matroska/src/read.rs @@ -3,8 +3,9 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ +use crate::error::Error; +use crate::Result; use crate::{matroska::MatroskaTag, size::EbmlSize, unflatten::IterWithPos, Master}; -use anyhow::{anyhow, bail, Result}; use log::{debug, warn}; use std::{ collections::VecDeque, @@ -47,14 +48,14 @@ impl EbmlReader { pub fn read_byte(&mut self) -> Result<u8> { let mut b = [0u8]; - self.inner.read_exact(&mut b)?; + self.inner.read_exact(&mut b).map_err(Error::Io)?; self.position += 1; Ok(b[0]) } pub fn read_buf(&mut self, size: impl Into<usize>) -> Result<Vec<u8>> { let size = size.into(); let mut b = vec![0u8; size]; - self.inner.read_exact(&mut b)?; + self.inner.read_exact(&mut b).map_err(Error::Io)?; self.position += size; Ok(b) } @@ -62,7 +63,7 @@ impl EbmlReader { let s = self.read_byte()?; let len = s.leading_zeros() + 1; if len > 8 { - bail!("varint too long"); + Err(Error::VarintTooLong)? } let mut value = s as u64; value -= 1 << (8 - len); @@ -77,7 +78,7 @@ impl EbmlReader { } pub fn read_utf8(&mut self, size: impl Into<usize>) -> Result<String> { let b = self.read_buf(size)?; - Ok(String::from_utf8(b)?) + Ok(String::from_utf8(b).map_err(|_| Error::InvalidUTF8)?) } pub fn read_tag_id(&mut self) -> Result<u64> { let (value, len) = self.read_vint_len()?; @@ -141,16 +142,16 @@ impl EbmlReader { /// context should be the next expected tag, such that the stack can be derived from its path. pub fn seek(&mut self, position: usize, context: MatroskaTag) -> Result<()> { - let path = context - .path() - .ok_or(anyhow!("global tags dont give context"))?; + let path = context.path().ok_or(Error::GlobalTagsAsContext)?; debug!( "seeking to {position} with a context restored from path {:x?}", path ); self.queue.clear(); self.position = position; - self.inner.seek(SeekFrom::Start(position as u64))?; + self.inner + .seek(SeekFrom::Start(position as u64)) + .map_err(Error::Io)?; self.stack = path .iter() .map(|id| StackTag { id: *id, end: None }) @@ -198,13 +199,13 @@ impl IterWithPos for EbmlReader { } pub trait ReadValue: Sized { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self>; + fn from_buf(buf: &[u8]) -> Result<Self>; } impl ReadValue for u64 { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self> { + fn from_buf(buf: &[u8]) -> Result<Self> { if buf.len() > 8 { - bail!("u64 too big") + Err(Error::InvalidTypeLen)? } let mut val = 0u64; for byte in buf { @@ -215,9 +216,9 @@ impl ReadValue for u64 { } } impl ReadValue for i64 { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self> { + fn from_buf(buf: &[u8]) -> Result<Self> { if buf.len() > 8 { - bail!("i64 too big") + Err(Error::InvalidTypeLen)? } Ok(if buf[0] > 127 { if buf.len() == 8 { @@ -231,29 +232,29 @@ impl ReadValue for i64 { } } impl ReadValue for f64 { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self> { + fn from_buf(buf: &[u8]) -> Result<Self> { Ok(if buf.len() == 4 { f32::from_be_bytes(buf.try_into().unwrap()) as f64 } else if buf.len() == 8 { f64::from_be_bytes(buf.try_into().unwrap()) } else { - bail!("float is not 4 or 8 bytes long"); + Err(Error::InvalidTypeLen)? }) } } impl ReadValue for Vec<u8> { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self> { + fn from_buf(buf: &[u8]) -> Result<Self> { Ok(buf.to_vec()) } } impl ReadValue for String { - fn from_buf(buf: &[u8]) -> anyhow::Result<Self> { - Ok(String::from_utf8(Vec::from(buf))?) + fn from_buf(buf: &[u8]) -> Result<Self> { + Ok(String::from_utf8(Vec::from(buf)).map_err(|_| Error::InvalidUTF8)?) } } impl ReadValue for Master { - fn from_buf(_: &[u8]) -> anyhow::Result<Self> { + fn from_buf(_: &[u8]) -> Result<Self> { panic!("master shall not be read like this") } } @@ -266,14 +267,14 @@ pub trait ReadExt: Read { impl<T: Read> ReadExt for T { fn read_byte(&mut self) -> Result<u8> { let mut b = [0u8]; - self.read_exact(&mut b)?; + self.read_exact(&mut b).map_err(Error::Io)?; Ok(b[0]) } fn read_vint_len(&mut self) -> Result<(u64, usize)> { let s = self.read_byte()?; let len = s.leading_zeros() + 1; if len > 8 { - bail!("varint too long"); + Err(Error::VarintTooLong)? } let mut value = s as u64; value -= 1 << (8 - len); diff --git a/matroska/src/unflatten.rs b/matroska/src/unflatten.rs index ee1a8d9..8f40819 100644 --- a/matroska/src/unflatten.rs +++ b/matroska/src/unflatten.rs @@ -4,7 +4,8 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use crate::{matroska::MatroskaTag, Master}; -use anyhow::Result; +use crate::Result; + pub trait IterWithPos { type Item; diff --git a/matroska/src/write.rs b/matroska/src/write.rs index 0b3b167..fb56cb9 100644 --- a/matroska/src/write.rs +++ b/matroska/src/write.rs @@ -3,8 +3,9 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ +use crate::error::Error; +use crate::Result; use crate::{matroska::MatroskaTag, size::EbmlSize, Master}; -use anyhow::{bail, Result}; use log::debug; use std::io::{Seek, Write}; @@ -19,7 +20,7 @@ impl<W: Write> EbmlWriter<W> { } pub fn write(&mut self, data: &[u8]) -> Result<()> { - self.inner.write_all(data)?; + self.inner.write_all(data).map_err(Error::Io)?; self.position += data.len(); Ok(()) } @@ -33,7 +34,7 @@ impl<W: Write> EbmlWriter<W> { let mut size = position - self.position; match size { 0 => return Ok(()), - 1 => bail!("this is sadly not possible"), + 1 => Err(Error::InvalidPadding)?, _ => (), } size -= 1; // subtract tag size @@ -63,7 +64,7 @@ impl<W: Write> EbmlWriter<W> { pub fn write_vint(&mut self, i: u64) -> Result<()> { if i > (1 << 56) - 1 { - bail!("vint does not fit"); + Err(Error::VarintTooLong)? } self.write_vint_len(i, vint_length(i)) } @@ -172,21 +173,21 @@ impl WriteValue for u64 { } } impl WriteValue for f64 { - fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> { + fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { w.push(0x88); w.extend_from_slice(&self.to_be_bytes()); Ok(()) } } impl WriteValue for Vec<u8> { - fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> { + fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { write_vint(w, self.len() as u64)?; w.extend_from_slice(self); Ok(()) } } impl WriteValue for String { - fn write_to(&self, w: &mut Vec<u8>) -> Result<(), anyhow::Error> { + fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { let sl = self.as_bytes(); write_vint(w, sl.len() as u64)?; w.extend_from_slice(sl); @@ -226,7 +227,7 @@ impl WriteValue for Master { pub fn write_vint(w: &mut Vec<u8>, i: u64) -> Result<()> { if i > (1 << 56) - 1 { - bail!("vint does not fit"); + Err(Error::VarintTooLong)? } let len = (64 - i.leading_zeros() as usize) / 7 + 1; let mut bytes = i.to_be_bytes(); |