aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src/trim_writer.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-28 10:55:10 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-28 10:55:10 +0100
commit0427a45ce8fa4762b087eeaf7e24f00678ceb48b (patch)
tree3f55f4bf994dbff980d930f51ac201beb22aa5e3 /remuxer/src/trim_writer.rs
parenta742f7dbd8bda0bf23a6d5273e5dd2f83b9d4c9f (diff)
downloadjellything-0427a45ce8fa4762b087eeaf7e24f00678ceb48b.tar
jellything-0427a45ce8fa4762b087eeaf7e24f00678ceb48b.tar.bz2
jellything-0427a45ce8fa4762b087eeaf7e24f00678ceb48b.tar.zst
seeking logic
Diffstat (limited to 'remuxer/src/trim_writer.rs')
-rw-r--r--remuxer/src/trim_writer.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/remuxer/src/trim_writer.rs b/remuxer/src/trim_writer.rs
new file mode 100644
index 0000000..65d3589
--- /dev/null
+++ b/remuxer/src/trim_writer.rs
@@ -0,0 +1,64 @@
+use std::{
+ io::{Seek, Write},
+ ops::Range,
+};
+
+use anyhow::anyhow;
+use log::warn;
+
+pub struct TrimWriter<W> {
+ inner: W,
+ position: usize,
+ range: Range<usize>,
+}
+impl<W: Write> TrimWriter<W> {
+ pub fn new(inner: W, range: Range<usize>) -> Self {
+ Self {
+ inner,
+ range,
+ position: 0,
+ }
+ }
+}
+
+impl<W: Write> Write for TrimWriter<W> {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ let start = self.range.start as isize - self.position as isize;
+ let end = self.range.end as isize - self.position as isize;
+
+ let start = start.clamp(0, buf.len() as isize) as usize;
+ let end = end.clamp(0, buf.len() as isize) as usize;
+
+ if self.position >= self.range.end {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ anyhow!("range ended"),
+ ));
+ }
+
+ let buf = &buf[start..end];
+ if !buf.is_empty() {
+ self.inner.write_all(buf)?;
+ self.position += buf.len()
+ }
+ Ok(buf.len())
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ self.inner.flush()
+ }
+}
+
+impl<W> Seek for TrimWriter<W> {
+ fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
+ match pos {
+ std::io::SeekFrom::Start(s) => self.position = s as usize,
+ std::io::SeekFrom::End(_) => unimplemented!(),
+ std::io::SeekFrom::Current(s) => self.position += s as usize,
+ }
+ if self.position < self.range.end {
+ warn!("seeked beyond end")
+ }
+ Ok(self.position as u64)
+ }
+}