use crate::bases::*;
use std::{borrow::Cow, sync::Arc};
use super::ByteStream;
#[derive(Debug, Clone)]
pub struct ByteSlice<'s> {
pub(crate) source: &'s Arc<dyn Source>,
pub(crate) region: Region,
}
impl<'s> ByteSlice<'s> {
pub(crate) fn new_from_parts(source: &'s Arc<dyn Source>, region: Region) -> Self {
Self { source, region }
}
pub fn size(&self) -> Size {
self.region.size()
}
pub fn stream(&self) -> ByteStream {
ByteStream::new_from_parts(Arc::clone(self.source), self.region, self.region.begin())
}
pub fn cut(&self, offset: Offset, size: Size) -> Self {
let region = self.region.cut_rel(offset, size);
Self {
source: self.source,
region,
}
}
pub fn get_slice(&self, offset: Offset, size: usize) -> Result<Cow<[u8]>> {
let region = self.region.cut_rel_asize(offset, ASize::new(size));
self.source.get_slice(region, BlockCheck::None)
}
}
impl<'s> RandomParser for ByteSlice<'s> {
type Parser<'p> = SliceParser<'p> where 's: 'p;
fn create_parser(&self, offset: Offset) -> Result<Self::Parser<'_>> {
let size = self.region.size() - offset.into();
let size = std::cmp::min(0xFFFF_u64, size.into_u64()) as usize;
let region = self.region.cut_rel_asize(offset, size.into());
Ok(SliceParser::new(
self.source.get_slice(region, BlockCheck::None)?,
self.region.begin() + offset,
))
}
fn global_offset(&self) -> Offset {
self.region.begin()
}
fn read_slice(&self, offset: Offset, size: usize) -> Result<Cow<[u8]>> {
let region = self.region.cut_rel_asize(offset, ASize::from(size));
self.source.get_slice(region, BlockCheck::None)
}
fn read_data(&self, offset: Offset, buf: &mut [u8]) -> Result<()> {
self.source.read_exact(self.region.begin() + offset, buf)
}
}