aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-26 16:02:36 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-26 16:02:36 +0100
commit833e64c69de930ec1f596bb77e8685760831a8d5 (patch)
tree8d50df70fc7d06e62efa5692f4d6aedb21bbd586
parente4d4b62178a1f83b4c9632b4fd8b2dcd2eef1bd9 (diff)
downloadjellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar
jellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar.bz2
jellything-833e64c69de930ec1f596bb77e8685760831a8d5.tar.zst
even less copying
-rw-r--r--ebml_derive/src/lib.rs2
-rw-r--r--matroska/src/error.rs2
-rw-r--r--matroska/src/write.rs109
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(())
}
}