use crate::bases::*;
use std::io::Read;
use std::sync::Arc;
use super::ByteRegion;
#[derive(Debug)]
pub struct ByteStream {
source: Arc<dyn Source>,
region: Region,
offset: Offset,
}
impl ByteStream {
pub(crate) fn new_from_parts(source: Arc<dyn Source>, region: Region, offset: Offset) -> Self {
Self {
source,
region,
offset,
}
}
pub fn size_left(&self) -> u64 {
(self.region.end() - self.offset).into_u64()
}
pub fn size(&self) -> u64 {
self.region.size().into_u64()
}
pub fn offset(&self) -> u64 {
(self.offset - self.region.begin()).into_u64()
}
}
impl Read for ByteStream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let max_len = std::cmp::min(
buf.len() as u64,
(self.region.end() - self.offset).into_u64(),
) as usize;
let buf = &mut buf[..max_len];
match self.source.read(self.offset, buf) {
Ok(s) => {
self.offset += s;
Ok(s)
}
Err(e) => Err(std::io::Error::other(e)),
}
}
}
impl From<ByteRegion> for ByteStream {
fn from(bregion: ByteRegion) -> Self {
Self::new_from_parts(bregion.source, bregion.region, Offset::zero())
}
}