aboutsummaryrefslogtreecommitdiff
path: root/matroska/src/block.rs
diff options
context:
space:
mode:
Diffstat (limited to 'matroska/src/block.rs')
-rw-r--r--matroska/src/block.rs71
1 files changed, 44 insertions, 27 deletions
diff --git a/matroska/src/block.rs b/matroska/src/block.rs
index 5ab398b..1ab8ceb 100644
--- a/matroska/src/block.rs
+++ b/matroska/src/block.rs
@@ -3,16 +3,19 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2024 metamuffin <metamuffin.org>
*/
+use crate::write::vint_length;
use crate::{read::ReadExt, write::write_vint};
-use crate::Result;
-use std::io::Cursor;
+use crate::{ReadValue, Result, WriteValue};
+use std::io::{Cursor, Write};
+#[derive(Debug, PartialEq, Clone, Copy)]
pub enum LacingType {
Xiph,
FixedSize,
Ebml,
}
+#[derive(Debug, PartialEq, Clone)]
pub struct Block {
pub track: u64,
pub keyframe: bool,
@@ -23,8 +26,8 @@ pub struct Block {
pub data: Vec<u8>,
}
-impl Block {
- pub fn parse(buf: &[u8]) -> Result<Self> {
+impl ReadValue for Block {
+ fn from_buf(buf: &[u8]) -> Result<Self> {
let (track, c) = Cursor::new(buf).read_vint_len()?;
let timestamp_off = i16::from_be_bytes(buf[c..c + 2].try_into().unwrap());
let flags = buf[c + 2];
@@ -51,28 +54,42 @@ impl Block {
timestamp_off,
})
}
- pub fn dump(&self) -> Vec<u8> {
- let mut out = vec![];
- write_vint(&mut out, self.track).unwrap();
- out.extend(self.timestamp_off.to_be_bytes().into_iter());
- out.push(
- match self.discardable {
- true => 0b1,
- false => 0b0,
- } | match self.keyframe {
- true => 0b10000000,
- false => 0b00000000,
- } | match self.invisible {
- true => 0b1000,
- false => 0b0000,
- } | match self.lacing {
- Some(LacingType::Xiph) => 0b010,
- Some(LacingType::Ebml) => 0b100,
- Some(LacingType::FixedSize) => 0b110,
- None => 0b0000,
- },
- );
- out.extend(self.data.iter());
- out
+}
+
+impl WriteValue for Block {
+ fn write_to(&self, w: &mut impl Write) -> Result<()> {
+ write_vint(w, self.inner_len() as u64)?;
+ write_vint(w, self.track)?;
+ w.write_all(&self.timestamp_off.to_be_bytes())?;
+ w.write_all(&[match self.discardable {
+ true => 0b1,
+ false => 0b0,
+ } | match self.keyframe {
+ true => 0b10000000,
+ false => 0b00000000,
+ } | match self.invisible {
+ true => 0b1000,
+ false => 0b0000,
+ } | match self.lacing {
+ Some(LacingType::Xiph) => 0b010,
+ Some(LacingType::Ebml) => 0b100,
+ Some(LacingType::FixedSize) => 0b110,
+ None => 0b0000,
+ }])?;
+ w.write_all(&self.data)?;
+ Ok(())
+ }
+ fn size(&self) -> usize {
+ let il = self.inner_len();
+ vint_length(il as u64) + il
+ }
+}
+
+impl Block {
+ fn inner_len(&self) -> usize {
+ vint_length(self.track)
+ + 2 // timestamp
+ + 1 // flags
+ + self.data.len()
}
}