From 0427a45ce8fa4762b087eeaf7e24f00678ceb48b Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 28 Jan 2023 10:55:10 +0100 Subject: seeking logic --- remuxer/src/trim_writer.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 remuxer/src/trim_writer.rs (limited to 'remuxer/src/trim_writer.rs') 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 { + inner: W, + position: usize, + range: Range, +} +impl TrimWriter { + pub fn new(inner: W, range: Range) -> Self { + Self { + inner, + range, + position: 0, + } + } +} + +impl Write for TrimWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + 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 Seek for TrimWriter { + fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + 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) + } +} -- cgit v1.2.3-70-g09d2