aboutsummaryrefslogtreecommitdiff
path: root/vendor/object/src/read/read_ref.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/read_ref.rs')
-rw-r--r--vendor/object/src/read/read_ref.rs137
1 files changed, 0 insertions, 137 deletions
diff --git a/vendor/object/src/read/read_ref.rs b/vendor/object/src/read/read_ref.rs
deleted file mode 100644
index 8b87cba..0000000
--- a/vendor/object/src/read/read_ref.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-#![allow(clippy::len_without_is_empty)]
-
-use core::convert::TryInto;
-use core::ops::Range;
-use core::{mem, result};
-
-use crate::pod::{from_bytes, slice_from_bytes, Pod};
-
-type Result<T> = result::Result<T, ()>;
-
-/// 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.
-///
-/// 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.
-//
-// An alternative would be for methods to accept `&mut self` and use a
-// `seek` method instead of the `offset` parameters, but this is less
-// convenient for implementers.
-pub trait ReadRef<'a>: Clone + Copy {
- /// The total size of the block of data.
- fn len(self) -> Result<u64>;
-
- /// Get a reference to a `u8` slice at the given offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]>;
-
- /// Get a reference to a delimited `u8` slice which starts at range.start.
- ///
- /// Does not include the delimiter.
- ///
- /// Returns an error if the range is out of bounds or the delimiter is
- /// not found in the range.
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> 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.
- fn read_bytes(self, offset: &mut u64, size: u64) -> Result<&'a [u8]> {
- let bytes = self.read_bytes_at(*offset, size)?;
- *offset = offset.wrapping_add(size);
- Ok(bytes)
- }
-
- /// 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).
- fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T> {
- let size = mem::size_of::<T>().try_into().map_err(|_| ())?;
- let bytes = self.read_bytes(offset, size)?;
- let (t, _) = from_bytes(bytes)?;
- Ok(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`.
- fn read_at<T: Pod>(self, mut offset: u64) -> Result<&'a T> {
- self.read(&mut offset)
- }
-
- /// Get a reference to a slice of a `Pod` type at the given offset, and update the offset.
- ///
- /// Returns an error if offset or size are out of bounds.
- ///
- /// Also see the `read` method for information regarding alignment of `T`.
- fn read_slice<T: Pod>(self, offset: &mut u64, count: usize) -> Result<&'a [T]> {
- let size = count
- .checked_mul(mem::size_of::<T>())
- .ok_or(())?
- .try_into()
- .map_err(|_| ())?;
- let bytes = self.read_bytes(offset, size)?;
- let (t, _) = slice_from_bytes(bytes, count)?;
- Ok(t)
- }
-
- /// Get a reference to a slice of 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`.
- fn read_slice_at<T: Pod>(self, mut offset: u64, count: usize) -> Result<&'a [T]> {
- self.read_slice(&mut offset, count)
- }
-}
-
-impl<'a> ReadRef<'a> for &'a [u8] {
- fn len(self) -> Result<u64> {
- self.len().try_into().map_err(|_| ())
- }
-
- fn read_bytes_at(self, offset: u64, size: u64) -> Result<&'a [u8]> {
- let offset: usize = offset.try_into().map_err(|_| ())?;
- let size: usize = size.try_into().map_err(|_| ())?;
- self.get(offset..).ok_or(())?.get(..size).ok_or(())
- }
-
- fn read_bytes_at_until(self, range: Range<u64>, delimiter: u8) -> Result<&'a [u8]> {
- let start: usize = range.start.try_into().map_err(|_| ())?;
- let end: usize = range.end.try_into().map_err(|_| ())?;
- let bytes = self.get(start..end).ok_or(())?;
- match memchr::memchr(delimiter, bytes) {
- Some(len) => {
- // This will never fail.
- bytes.get(..len).ok_or(())
- }
- None => Err(()),
- }
- }
-}