pub trait ReadRef<'a>: Clone + Copy {
// Required methods
fn len(self) -> Result<u64, ()>;
fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8], ()>;
fn read_bytes_at_until(
self,
range: Range<u64>,
delimiter: u8,
) -> Result<&'a [u8], ()>;
// Provided methods
fn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8], ()> { ... }
fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T, ()> { ... }
fn read_at<T: Pod>(self, offset: u64) -> Result<&'a T, ()> { ... }
fn read_slice<T: Pod>(
self,
offset: &mut u64,
count: usize,
) -> Result<&'a [T], ()> { ... }
fn read_slice_at<T: Pod>(
self,
offset: u64,
count: usize,
) -> Result<&'a [T], ()> { ... }
}
Expand description
A trait for reading references to Pod
types from a block of data.
This allows parsers to handle both of these cases:
- the block of data exists in memory, and it is desirable to use references to this block instead of copying it,
- the block of data exists in storage, and it is desirable to read on demand to minimize I/O and memory usage.
A block of data typically exists in memory as a result of using a memory
mapped file, and the crate was written with this use case in mind.
Reading the entire file into a Vec
is also possible, but it often uses
more I/O and memory.
Both of these are handled by the ReadRef
implementation for &[u8]
.
For the second use case, the ReadRef
trait is implemented for
&ReadCache
. This is useful for environments where
memory mapped files are not available or not suitable, such as WebAssembly.
This differs from reading into a Vec
in that it only reads the portions
of the file that are needed for parsing.
The methods accept self
by value because Self
is expected to behave
similar to a reference: it may be a reference with a lifetime of 'a
,
or it may be a wrapper of a reference.
The Clone
and Copy
bounds are for convenience, and since Self
is
expected to be similar to a reference, these are easily satisfied.
Object file parsers typically use offsets to locate the structures
in the block, and will most commonly use the *_at
methods to
read a structure at a known offset.
Occasionally file parsers will need to treat the block as a stream, and so convenience methods are provided that update an offset with the size that was read.
Required Methods§
Provided Methods§
sourcefn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8], ()>
fn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8], ()>
Get a reference to a u8
slice at the given offset, and update the offset.
Returns an error if offset or size are out of bounds.
sourcefn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T, ()>
fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T, ()>
Get a reference to a Pod
type at the given offset, and update the offset.
Returns an error if offset or size are out of bounds.
The default implementation uses read_bytes
, and returns an error if
read_bytes
does not return bytes with the correct alignment for T
.
Implementors may want to provide their own implementation that ensures
the alignment can be satisfied. Alternatively, only use this method with
types that do not need alignment (see the unaligned
feature of this crate).
sourcefn read_at<T: Pod>(self, offset: u64) -> Result<&'a T, ()>
fn read_at<T: Pod>(self, offset: u64) -> Result<&'a T, ()>
Get a reference to a Pod
type at the given offset.
Returns an error if offset or size are out of bounds.
Also see the read
method for information regarding alignment of T
.