ms_pdb_msf/
stream_reader.rsuse super::*;
pub struct StreamReader<'a, F> {
stream: u32,
stream_size: u32,
is_nil: bool,
page_size: PageSize,
page_map: &'a [Page],
file: &'a F,
pos: u64,
}
impl<'a, F: ReadAt> StreamReader<'a, F> {
pub(crate) fn new(
pdb: &'a Msf<F>,
stream: u32,
stream_size: u32,
page_map: &'a [Page],
pos: u64,
) -> Self {
Self {
stream,
stream_size: if stream_size == NIL_STREAM_SIZE {
0
} else {
stream_size
},
is_nil: stream_size == NIL_STREAM_SIZE,
page_size: pdb.pages.page_size,
page_map,
file: &pdb.file,
pos,
}
}
pub fn len(&self) -> u32 {
self.stream_size
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn is_nil(&self) -> bool {
self.is_nil
}
}
impl<'a, F: ReadAt> Seek for StreamReader<'a, F> {
fn seek(&mut self, from: SeekFrom) -> std::io::Result<u64> {
let new_pos: i64 = match from {
SeekFrom::Start(offset) => offset as i64,
SeekFrom::End(signed_offset) => signed_offset + self.stream_size as i64,
SeekFrom::Current(signed_offset) => self.pos as i64 + signed_offset,
};
if new_pos < 0 {
return Err(std::io::ErrorKind::InvalidInput.into());
}
self.pos = new_pos as u64;
Ok(self.pos)
}
}
impl<'a, F: ReadAt> Read for StreamReader<'a, F> {
fn read(&mut self, dst: &mut [u8]) -> std::io::Result<usize> {
let (n, new_pos) = super::read::read_stream_core(
self.stream,
self.file,
self.page_size,
self.stream_size,
self.page_map,
self.pos,
dst,
)?;
self.pos = new_pos;
Ok(n)
}
}
impl<'a, F: ReadAt> ReadAt for StreamReader<'a, F> {
fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<()> {
let (n, _new_pos) = super::read::read_stream_core(
self.stream,
self.file,
self.page_size,
self.stream_size,
self.page_map,
offset,
buf,
)?;
if n != buf.len() {
return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof));
}
Ok(())
}
fn read_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<usize> {
let (n, _new_pos) = super::read::read_stream_core(
self.stream,
self.file,
self.page_size,
self.stream_size,
self.page_map,
offset,
buf,
)?;
Ok(n)
}
}