diff options
Diffstat (limited to 'vendor/object/src/read/read_ref.rs')
-rw-r--r-- | vendor/object/src/read/read_ref.rs | 137 |
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(()), - } - } -} |