Merge Read/Seek stream input traits

This commit is contained in:
2023-07-20 18:36:30 +03:00
parent 9f36ba0ffa
commit 419cd311de
2 changed files with 12 additions and 30 deletions
+7 -7
View File
@@ -13,7 +13,7 @@ use crate::file::{parse_ident, Class};
use crate::gnu_symver::{ use crate::gnu_symver::{
SymbolVersionTable, VerDefIterator, VerNeedIterator, VersionIndex, VersionIndexTable, SymbolVersionTable, VerDefIterator, VerNeedIterator, VersionIndex, VersionIndexTable,
}; };
use crate::io_traits::{Read, Seek, SeekFrom}; use crate::io_traits::{InputStream, SeekFrom};
use crate::note::NoteIterator; use crate::note::NoteIterator;
use crate::parse::{ParseAt, ParseError}; use crate::parse::{ParseAt, ParseError};
use crate::relocation::{RelIterator, RelaIterator}; use crate::relocation::{RelIterator, RelaIterator};
@@ -28,7 +28,7 @@ use crate::file::FileHeader;
/// This type encapsulates the stream-oriented interface for parsing ELF objects from /// This type encapsulates the stream-oriented interface for parsing ELF objects from
/// a `Read + Seek`. /// a `Read + Seek`.
#[derive(Debug)] #[derive(Debug)]
pub struct ElfStream<E: EndianParse, S: Read + Seek> { pub struct ElfStream<E: EndianParse, S: InputStream> {
pub ehdr: FileHeader<E>, pub ehdr: FileHeader<E>,
shdrs: Vec<SectionHeader>, shdrs: Vec<SectionHeader>,
phdrs: Vec<ProgramHeader>, phdrs: Vec<ProgramHeader>,
@@ -40,7 +40,7 @@ pub struct ElfStream<E: EndianParse, S: Read + Seek> {
/// Returns a [ParseError] if the data bytes for the section table cannot be read. /// Returns a [ParseError] if the data bytes for the section table cannot be read.
/// i.e. if the ELF [FileHeader]'s e_shnum, e_shoff, e_shentsize are invalid and point /// i.e. if the ELF [FileHeader]'s e_shnum, e_shoff, e_shentsize are invalid and point
/// to a range in the file data that does not actually exist, or if any of the headers failed to parse. /// to a range in the file data that does not actually exist, or if any of the headers failed to parse.
fn parse_section_headers<E: EndianParse, S: Read + Seek>( fn parse_section_headers<E: EndianParse, S: InputStream>(
ehdr: &FileHeader<E>, ehdr: &FileHeader<E>,
reader: &mut CachingReader<S>, reader: &mut CachingReader<S>,
) -> Result<Vec<SectionHeader>, ParseError> { ) -> Result<Vec<SectionHeader>, ParseError> {
@@ -78,7 +78,7 @@ fn parse_section_headers<E: EndianParse, S: Read + Seek>(
Ok(shdr_vec) Ok(shdr_vec)
} }
fn parse_program_headers<E: EndianParse, S: Read + Seek>( fn parse_program_headers<E: EndianParse, S: InputStream>(
ehdr: &FileHeader<E>, ehdr: &FileHeader<E>,
reader: &mut CachingReader<S>, reader: &mut CachingReader<S>,
) -> Result<Vec<ProgramHeader>, ParseError> { ) -> Result<Vec<ProgramHeader>, ParseError> {
@@ -117,7 +117,7 @@ fn parse_program_headers<E: EndianParse, S: Read + Seek>(
Ok(phdrs_vec) Ok(phdrs_vec)
} }
impl<E: EndianParse, S: Read + Seek> ElfStream<E, S> { impl<E: EndianParse, S: InputStream> ElfStream<E, S> {
/// Do a minimal amount of parsing work to open an [ElfStream] handle from a Read+Seek containing an ELF object. /// Do a minimal amount of parsing work to open an [ElfStream] handle from a Read+Seek containing an ELF object.
/// ///
/// This parses the ELF [FileHeader], [SectionHeader] table, and [ProgramHeader] (segments) table. /// This parses the ELF [FileHeader], [SectionHeader] table, and [ProgramHeader] (segments) table.
@@ -680,13 +680,13 @@ impl<E: EndianParse, S: Read + Seek> ElfStream<E, S> {
} }
#[derive(Debug)] #[derive(Debug)]
struct CachingReader<R: Read + Seek> { struct CachingReader<R: InputStream> {
reader: R, reader: R,
stream_len: u64, stream_len: u64,
bufs: BufferMap<(usize, usize), Box<[u8]>>, bufs: BufferMap<(usize, usize), Box<[u8]>>,
} }
impl<R: Read + Seek> CachingReader<R> { impl<R: InputStream> CachingReader<R> {
fn new(mut reader: R) -> Result<Self, ParseError> { fn new(mut reader: R) -> Result<Self, ParseError> {
// Cache the size of the stream so that we can err (rather than OOM) on invalid // Cache the size of the stream so that we can err (rather than OOM) on invalid
// huge read requests. // huge read requests.
+5 -23
View File
@@ -14,31 +14,19 @@ pub enum SeekFrom {
Current(i64), Current(i64),
} }
pub trait Read { pub trait InputStream {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, StreamError>;
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError>; fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError>;
}
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError>; fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError>;
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<R: std::io::Read> Read for R { impl<R: std::io::Read> InputStream for R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, StreamError> {
std::io::Read::read(self, buf)
}
#[inline] #[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> { fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> {
std::io::Read::read_exact(self, buf) std::io::Read::read_exact(self, buf)
} }
}
#[cfg(feature = "std")]
impl<S: std::io::Seek> Seek for S {
#[inline] #[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> { fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> {
std::io::Seek::seek(self, pos.into()) std::io::Seek::seek(self, pos.into())
@@ -58,7 +46,7 @@ impl From<SeekFrom> for std::io::SeekFrom {
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
impl From<StreamError> for crate::ParseError { impl From<StreamError> for crate::ParseError {
fn from(e: StreamError) -> Self { fn from(_e: StreamError) -> Self {
todo!() todo!()
} }
} }
@@ -67,7 +55,7 @@ impl From<StreamError> for crate::ParseError {
mod no_std_stream_tests { mod no_std_stream_tests {
use crate::{abi, endian::AnyEndian, ElfStream}; use crate::{abi, endian::AnyEndian, ElfStream};
use super::{Read, Seek, SeekFrom, StreamError}; use super::{InputStream, SeekFrom, StreamError};
pub struct NoStdStream { pub struct NoStdStream {
pos: usize, pos: usize,
@@ -81,11 +69,7 @@ mod no_std_stream_tests {
} }
} }
impl Read for NoStdStream { impl InputStream for NoStdStream {
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, StreamError> {
unimplemented!()
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> { fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> {
if self.pos + buf.len() > self.data.len() { if self.pos + buf.len() > self.data.len() {
unimplemented!(); unimplemented!();
@@ -94,9 +78,7 @@ mod no_std_stream_tests {
self.pos += buf.len(); self.pos += buf.len();
Ok(()) Ok(())
} }
}
impl Seek for NoStdStream {
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> { fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> {
match pos { match pos {
SeekFrom::End(offset) => { SeekFrom::End(offset) => {