diff options
author | metamuffin <metamuffin@disroot.org> | 2024-01-26 16:02:36 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-01-26 16:02:36 +0100 |
commit | 833e64c69de930ec1f596bb77e8685760831a8d5 (patch) | |
tree | 8d50df70fc7d06e62efa5692f4d6aedb21bbd586 | |
parent | e4d4b62178a1f83b4c9632b4fd8b2dcd2eef1bd9 (diff) | |
download | jellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar jellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar.bz2 jellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar.zst |
even less copying
-rw-r--r-- | ebml_derive/src/lib.rs | 2 | ||||
-rw-r--r-- | matroska/src/error.rs | 2 | ||||
-rw-r--r-- | matroska/src/write.rs | 109 |
3 files changed, 56 insertions, 57 deletions
diff --git a/ebml_derive/src/lib.rs b/ebml_derive/src/lib.rs index 34510b9..6b650f1 100644 --- a/ebml_derive/src/lib.rs +++ b/ebml_derive/src/lib.rs @@ -132,7 +132,7 @@ pub fn define_ebml(ts: TokenStream) -> TokenStream { pub fn parse(id: u64, data: &[u8]) -> crate::Result<Self> { Ok(match id { #(#parse_match),*, _ => return Err(crate::Error::UnknownID) }) } - pub fn write(&self, w: &mut Vec<u8>) -> crate::Result<()> { + pub fn write(&self, w: &mut impl std::io::Write) -> crate::Result<()> { match self { #(#write_match),* } } pub fn size(&self) -> usize { 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(()) } } |