aboutsummaryrefslogtreecommitdiff
path: root/ebml/src/read.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ebml/src/read.rs')
-rw-r--r--ebml/src/read.rs96
1 files changed, 96 insertions, 0 deletions
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<T: Read + Seek> ReadAndSeek for T {}
+
+pub struct EbmlReader {
+ inner: Box<dyn ReadAndSeek>,
+ pub position: usize,
+}
+
+pub trait EbmlRead: Sized {
+ fn read(r: &mut EbmlReader) -> Result<Self>;
+}
+
+impl EbmlReader {
+ pub fn new<T: Seek + Read + 'static>(inner: T) -> Self {
+ Self {
+ inner: Box::new(inner),
+ position: 0,
+ }
+ }
+
+ pub fn read_byte(&mut self) -> Result<u8> {
+ 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<usize>) -> Result<Vec<u8>> {
+ 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<u64> {
+ Ok(self.read_vint_len()?.0)
+ }
+ pub fn read_utf8(&mut self, size: impl Into<usize>) -> Result<String> {
+ let b = self.read_buf(size)?;
+ Ok(String::from_utf8(b)?)
+ }
+
+ pub fn read_tag_id(&mut self) -> Result<u64> {
+ 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<usize> for EbmlSize {
+ fn into(self) -> usize {
+ match self {
+ EbmlSize::Exact(s) => s,
+ EbmlSize::Unknown => panic!("unknown size, where it should have been known"),
+ }
+ }
+}