use std::io::Read;
use super::{SeekRead, Source, SourceCaps};
use crate::error::Result;
pub struct ReaderSource {
inner: Box<dyn Read + Send>,
}
impl ReaderSource {
pub fn new<R: Read + Send + 'static>(inner: R) -> Self {
Self {
inner: Box::new(inner),
}
}
}
impl Read for ReaderSource {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.inner.read(buf)
}
}
impl Source for ReaderSource {
fn caps(&self) -> SourceCaps {
SourceCaps {
seekable: false,
len: None,
}
}
fn as_seek(&mut self) -> Option<&mut dyn SeekRead> {
None
}
}
pub struct PeekSource {
inner: Box<dyn Source>,
prefix: Vec<u8>,
pos: usize,
}
impl PeekSource {
pub fn fill(mut inner: Box<dyn Source>, n: usize) -> Result<Self> {
let mut prefix = vec![0u8; n];
let mut filled = 0;
while filled < n {
match inner.read(&mut prefix[filled..])? {
0 => break,
k => filled += k,
}
}
prefix.truncate(filled);
Ok(Self {
inner,
prefix,
pos: 0,
})
}
pub fn prefix(&self) -> &[u8] {
&self.prefix
}
}
impl Read for PeekSource {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.pos < self.prefix.len() {
let n = (self.prefix.len() - self.pos).min(buf.len());
buf[..n].copy_from_slice(&self.prefix[self.pos..self.pos + n]);
self.pos += n;
return Ok(n);
}
self.inner.read(buf)
}
}
impl Source for PeekSource {
fn caps(&self) -> SourceCaps {
SourceCaps {
seekable: false,
len: None,
}
}
fn as_seek(&mut self) -> Option<&mut dyn SeekRead> {
None
}
}