1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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"),
}
}
}
|