diff options
author | metamuffin <metamuffin@disroot.org> | 2023-01-28 10:55:10 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-01-28 10:55:10 +0100 |
commit | 0427a45ce8fa4762b087eeaf7e24f00678ceb48b (patch) | |
tree | 3f55f4bf994dbff980d930f51ac201beb22aa5e3 /remuxer/src/trim_writer.rs | |
parent | a742f7dbd8bda0bf23a6d5273e5dd2f83b9d4c9f (diff) | |
download | jellything-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.rs | 64 |
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) + } +} |