diff options
Diffstat (limited to 'matroska/src')
-rw-r--r-- | matroska/src/error.rs | 2 | ||||
-rw-r--r-- | matroska/src/write.rs | 109 |
2 files changed, 55 insertions, 56 deletions
diff --git a/matroska/src/error.rs b/matroska/src/error.rs index 367b017..11cd82a 100644 --- a/matroska/src/error.rs +++ b/matroska/src/error.rs @@ -20,5 +20,5 @@ pub enum Error { #[error("unknown id")] UnknownID, #[error("io: {0}")] - Io(std::io::Error), + Io(#[from] std::io::Error), } diff --git a/matroska/src/write.rs b/matroska/src/write.rs index 3b127f8..aaf11d9 100644 --- a/matroska/src/write.rs +++ b/matroska/src/write.rs @@ -19,12 +19,6 @@ impl<W: Write> EbmlWriter<W> { Self { inner, position } } - pub fn write(&mut self, data: &[u8]) -> Result<()> { - self.inner.write_all(data).map_err(Error::Io)?; - self.position += data.len(); - Ok(()) - } - pub fn position(&self) -> usize { self.position } @@ -46,34 +40,27 @@ impl<W: Write> EbmlWriter<W> { // _ if size < (1 << 21) => size -= 3, // _ if size < (1 << 28) => size -= 4, // _ if size < (1 << 35) => size -= 5, - // _ => bail!("padding to large"), + // _ => bail!("padding too large"), // } - self.write(&[0xec])?; + self.write_all(&[0xec])?; self.write_vint_len(size.try_into().unwrap(), 4)?; - self.write(&vec![0; size])?; + self.write_all(&vec![0; size])?; Ok(()) } + #[inline] pub fn write_tag(&mut self, tag: &MatroskaTag) -> Result<()> { - let mut buf = vec![]; - tag.write_full(&mut buf)?; - self.write(&buf)?; + tag.write_full(self)?; Ok(()) } - pub fn write_vint(&mut self, i: u64) -> Result<()> { - if i > (1 << 56) - 1 { - Err(Error::VarintTooLong)? - } - self.write_vint_len(i, vint_length(i)) - } - pub fn write_vint_len(&mut self, i: u64, len: usize) -> Result<()> { let mut bytes = i.to_be_bytes(); let trunc = &mut bytes[(8 - len)..]; trunc[0] |= 1 << (8 - len); - self.write(trunc) + self.write_all(trunc)?; + Ok(()) } } @@ -89,9 +76,23 @@ impl<W: Seek> Seek for EbmlWriter<W> { } } +impl<W: Write> Write for EbmlWriter<W> { + fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { + let size = self.inner.write(buf)?; + self.position += size; + Ok(size) + } + + fn flush(&mut self) -> std::io::Result<()> { + todo!() + } +} + impl MatroskaTag { - pub fn write_full(&self, w: &mut Vec<u8>) -> Result<()> { - w.extend(self.id().to_be_bytes().iter().skip_while(|&v| *v == 0u8)); + pub fn write_full(&self, w: &mut impl Write) -> Result<()> { + for b in self.id().to_be_bytes().iter().skip_while(|&v| *v == 0u8) { + w.write_all(&[*b])?; + } self.write(w)?; Ok(()) } @@ -100,7 +101,7 @@ impl MatroskaTag { } } -pub fn write_vint(w: &mut Vec<u8>, i: u64) -> Result<()> { +pub fn write_vint(w: &mut impl Write, i: u64) -> Result<()> { if i > (1 << 56) - 1 { Err(Error::VarintTooLong)? } @@ -108,7 +109,7 @@ pub fn write_vint(w: &mut Vec<u8>, i: u64) -> Result<()> { let mut bytes = i.to_be_bytes(); let trunc = &mut bytes[(8 - len)..]; trunc[0] |= 1 << (8 - len); - w.extend_from_slice(trunc); + w.write_all(trunc)?; Ok(()) } @@ -135,28 +136,28 @@ pub fn bad_vint_length(v: u64) -> usize { pub trait WriteValue { /// writes the contents of a tag, including the size but excluding the id. - fn write_to(&self, w: &mut Vec<u8>) -> Result<()>; + fn write_to(&self, w: &mut impl Write) -> Result<()>; fn size(&self) -> usize; } impl WriteValue for i64 { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { match 64 - self.leading_zeros() { x if x <= 8 => { - w.push(0x81); - w.extend_from_slice(&(*self as i8).to_be_bytes()); + w.write_all(&[0x81])?; + w.write_all(&(*self as i8).to_be_bytes())?; } x if x <= 16 => { - w.push(0x82); - w.extend_from_slice(&(*self as i16).to_be_bytes()); + w.write_all(&[0x82])?; + w.write_all(&(*self as i16).to_be_bytes())?; } x if x <= 32 => { - w.push(0x84); - w.extend_from_slice(&(*self as i32).to_be_bytes()); + w.write_all(&[0x84])?; + w.write_all(&(*self as i32).to_be_bytes())?; } _ => { - w.push(0x88); - w.extend_from_slice(&self.to_be_bytes()); + w.write_all(&[0x88])?; + w.write_all(&self.to_be_bytes())?; } }; Ok(()) @@ -172,23 +173,23 @@ impl WriteValue for i64 { } } impl WriteValue for u64 { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { match 64 - self.leading_zeros() { x if x <= 8 => { - w.push(0x81); - w.extend_from_slice(&(*self as u8).to_be_bytes()); + w.write_all(&[0x81])?; + w.write_all(&(*self as u8).to_be_bytes())?; } x if x <= 16 => { - w.push(0x82); - w.extend_from_slice(&(*self as u16).to_be_bytes()); + w.write_all(&[0x82])?; + w.write_all(&(*self as u16).to_be_bytes())?; } x if x <= 32 => { - w.push(0x84); - w.extend_from_slice(&(*self as u32).to_be_bytes()); + w.write_all(&[0x84])?; + w.write_all(&(*self as u32).to_be_bytes())?; } _ => { - w.push(0x88); - w.extend_from_slice(&self.to_be_bytes()); + w.write_all(&[0x88])?; + w.write_all(&self.to_be_bytes())?; } }; Ok(()) @@ -203,9 +204,9 @@ impl WriteValue for u64 { } } impl WriteValue for f64 { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { - w.push(0x88); - w.extend_from_slice(&self.to_be_bytes()); + fn write_to(&self, w: &mut impl Write) -> Result<()> { + w.write_all(&[0x88])?; + w.write_all(&self.to_be_bytes())?; Ok(()) } fn size(&self) -> usize { @@ -213,9 +214,9 @@ impl WriteValue for f64 { } } impl WriteValue for Vec<u8> { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { write_vint(w, self.len() as u64)?; - w.extend_from_slice(self); + w.write_all(self)?; Ok(()) } @@ -224,10 +225,10 @@ impl WriteValue for Vec<u8> { } } impl WriteValue for String { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { let sl = self.as_bytes(); write_vint(w, sl.len() as u64)?; - w.extend_from_slice(sl); + w.write_all(sl)?; Ok(()) } @@ -236,10 +237,10 @@ impl WriteValue for String { } } impl WriteValue for EbmlSize { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { match self { EbmlSize::Exact(s) => write_vint(w, *s as u64)?, - EbmlSize::Unknown => w.extend_from_slice(&(u64::MAX >> 7).to_be_bytes()), + EbmlSize::Unknown => w.write_all(&(u64::MAX >> 7).to_be_bytes())?, } Ok(()) } @@ -253,7 +254,7 @@ impl WriteValue for EbmlSize { } impl WriteValue for Master { - fn write_to(&self, w: &mut Vec<u8>) -> Result<()> { + fn write_to(&self, w: &mut impl Write) -> Result<()> { match self { Master::Start => EbmlSize::Unknown.write_to(w), Master::End => { @@ -265,11 +266,9 @@ impl WriteValue for Master { size += c.size_full(); } EbmlSize::Exact(size).write_to(w)?; - let k = w.len(); for c in c { c.write_full(w)?; } - debug_assert_eq!(w.len() - k, size, "real size of collected differs"); Ok(()) } } |