Merge Read/Seek stream input traits

This commit is contained in:
Mark Poliakov 2023-07-20 18:36:30 +03:00
parent 9f36ba0ffa
commit 419cd311de
2 changed files with 12 additions and 30 deletions

View File

@ -13,7 +13,7 @@ use crate::file::{parse_ident, Class};
use crate::gnu_symver::{
SymbolVersionTable, VerDefIterator, VerNeedIterator, VersionIndex, VersionIndexTable,
};
use crate::io_traits::{Read, Seek, SeekFrom};
use crate::io_traits::{InputStream, SeekFrom};
use crate::note::NoteIterator;
use crate::parse::{ParseAt, ParseError};
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
/// a `Read + Seek`.
#[derive(Debug)]
pub struct ElfStream<E: EndianParse, S: Read + Seek> {
pub struct ElfStream<E: EndianParse, S: InputStream> {
pub ehdr: FileHeader<E>,
shdrs: Vec<SectionHeader>,
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.
/// 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.
fn parse_section_headers<E: EndianParse, S: Read + Seek>(
fn parse_section_headers<E: EndianParse, S: InputStream>(
ehdr: &FileHeader<E>,
reader: &mut CachingReader<S>,
) -> Result<Vec<SectionHeader>, ParseError> {
@ -78,7 +78,7 @@ fn parse_section_headers<E: EndianParse, S: Read + Seek>(
Ok(shdr_vec)
}
fn parse_program_headers<E: EndianParse, S: Read + Seek>(
fn parse_program_headers<E: EndianParse, S: InputStream>(
ehdr: &FileHeader<E>,
reader: &mut CachingReader<S>,
) -> Result<Vec<ProgramHeader>, ParseError> {
@ -117,7 +117,7 @@ fn parse_program_headers<E: EndianParse, S: Read + Seek>(
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.
///
/// 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)]
struct CachingReader<R: Read + Seek> {
struct CachingReader<R: InputStream> {
reader: R,
stream_len: u64,
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> {
// Cache the size of the stream so that we can err (rather than OOM) on invalid
// huge read requests.

View File

@ -14,31 +14,19 @@ pub enum SeekFrom {
Current(i64),
}
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, StreamError>;
pub trait InputStream {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError>;
}
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError>;
}
#[cfg(feature = "std")]
impl<R: std::io::Read> Read for R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize, StreamError> {
std::io::Read::read(self, buf)
}
impl<R: std::io::Read> InputStream for R {
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> {
std::io::Read::read_exact(self, buf)
}
}
#[cfg(feature = "std")]
impl<S: std::io::Seek> Seek for S {
#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> {
std::io::Seek::seek(self, pos.into())
@ -58,7 +46,7 @@ impl From<SeekFrom> for std::io::SeekFrom {
#[cfg(not(feature = "std"))]
impl From<StreamError> for crate::ParseError {
fn from(e: StreamError) -> Self {
fn from(_e: StreamError) -> Self {
todo!()
}
}
@ -67,7 +55,7 @@ impl From<StreamError> for crate::ParseError {
mod no_std_stream_tests {
use crate::{abi, endian::AnyEndian, ElfStream};
use super::{Read, Seek, SeekFrom, StreamError};
use super::{InputStream, SeekFrom, StreamError};
pub struct NoStdStream {
pos: usize,
@ -81,11 +69,7 @@ mod no_std_stream_tests {
}
}
impl Read for NoStdStream {
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, StreamError> {
unimplemented!()
}
impl InputStream for NoStdStream {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), StreamError> {
if self.pos + buf.len() > self.data.len() {
unimplemented!();
@ -94,9 +78,7 @@ mod no_std_stream_tests {
self.pos += buf.len();
Ok(())
}
}
impl Seek for NoStdStream {
fn seek(&mut self, pos: SeekFrom) -> Result<u64, StreamError> {
match pos {
SeekFrom::End(offset) => {