diff options
author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/gimli/src/read/endian_reader.rs | |
parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip |
Deleted vendor folder
Diffstat (limited to 'vendor/gimli/src/read/endian_reader.rs')
-rw-r--r-- | vendor/gimli/src/read/endian_reader.rs | 639 |
1 files changed, 0 insertions, 639 deletions
diff --git a/vendor/gimli/src/read/endian_reader.rs b/vendor/gimli/src/read/endian_reader.rs deleted file mode 100644 index 8852b38..0000000 --- a/vendor/gimli/src/read/endian_reader.rs +++ /dev/null @@ -1,639 +0,0 @@ -//! Defining custom `Reader`s quickly. - -use alloc::borrow::Cow; -use alloc::rc::Rc; -use alloc::string::String; -use alloc::sync::Arc; -use core::fmt::Debug; -use core::ops::{Deref, Index, Range, RangeFrom, RangeTo}; -use core::slice; -use core::str; -use stable_deref_trait::CloneStableDeref; - -use crate::endianity::Endianity; -use crate::read::{Error, Reader, ReaderOffsetId, Result}; - -/// A reference counted, non-thread-safe slice of bytes and associated -/// endianity. -/// -/// ``` -/// # #[cfg(feature = "std")] { -/// use std::rc::Rc; -/// -/// let buf = Rc::from(&[1, 2, 3, 4][..]); -/// let reader = gimli::EndianRcSlice::new(buf, gimli::NativeEndian); -/// # let _ = reader; -/// # } -/// ``` -pub type EndianRcSlice<Endian> = EndianReader<Endian, Rc<[u8]>>; - -/// An atomically reference counted, thread-safe slice of bytes and associated -/// endianity. -/// -/// ``` -/// # #[cfg(feature = "std")] { -/// use std::sync::Arc; -/// -/// let buf = Arc::from(&[1, 2, 3, 4][..]); -/// let reader = gimli::EndianArcSlice::new(buf, gimli::NativeEndian); -/// # let _ = reader; -/// # } -/// ``` -pub type EndianArcSlice<Endian> = EndianReader<Endian, Arc<[u8]>>; - -/// An easy way to define a custom `Reader` implementation with a reference to a -/// generic buffer of bytes and an associated endianity. -/// -/// Note that the whole original buffer is kept alive in memory even if there is -/// only one reader that references only a handful of bytes from that original -/// buffer. That is, `EndianReader` will not do any copying, moving, or -/// compacting in order to free up unused regions of the original buffer. If you -/// require this kind of behavior, it is up to you to implement `Reader` -/// directly by-hand. -/// -/// # Example -/// -/// Say you have an `mmap`ed file that you want to serve as a `gimli::Reader`. -/// You can wrap that `mmap`ed file up in a `MmapFile` type and use -/// `EndianReader<Rc<MmapFile>>` or `EndianReader<Arc<MmapFile>>` as readers as -/// long as `MmapFile` dereferences to the underlying `[u8]` data. -/// -/// ``` -/// use std::io; -/// use std::ops::Deref; -/// use std::path::Path; -/// use std::slice; -/// use std::sync::Arc; -/// -/// /// A type that represents an `mmap`ed file. -/// #[derive(Debug)] -/// pub struct MmapFile { -/// ptr: *const u8, -/// len: usize, -/// } -/// -/// impl MmapFile { -/// pub fn new(path: &Path) -> io::Result<MmapFile> { -/// // Call `mmap` and check for errors and all that... -/// # unimplemented!() -/// } -/// } -/// -/// impl Drop for MmapFile { -/// fn drop(&mut self) { -/// // Call `munmap` to clean up after ourselves... -/// # unimplemented!() -/// } -/// } -/// -/// // And `MmapFile` can deref to a slice of the `mmap`ed region of memory. -/// impl Deref for MmapFile { -/// type Target = [u8]; -/// fn deref(&self) -> &[u8] { -/// unsafe { -/// slice::from_raw_parts(self.ptr, self.len) -/// } -/// } -/// } -/// -/// /// A type that represents a shared `mmap`ed file. -/// #[derive(Debug, Clone)] -/// pub struct ArcMmapFile(Arc<MmapFile>); -/// -/// // And `ArcMmapFile` can deref to a slice of the `mmap`ed region of memory. -/// impl Deref for ArcMmapFile { -/// type Target = [u8]; -/// fn deref(&self) -> &[u8] { -/// &self.0 -/// } -/// } -/// -/// // These are both valid for any `Rc` or `Arc`. -/// unsafe impl gimli::StableDeref for ArcMmapFile {} -/// unsafe impl gimli::CloneStableDeref for ArcMmapFile {} -/// -/// /// A `gimli::Reader` that is backed by an `mmap`ed file! -/// pub type MmapFileReader<Endian> = gimli::EndianReader<Endian, ArcMmapFile>; -/// # fn test(_: &MmapFileReader<gimli::NativeEndian>) { } -/// ``` -#[derive(Debug, Clone, Copy, Hash)] -pub struct EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - range: SubRange<T>, - endian: Endian, -} - -impl<Endian, T1, T2> PartialEq<EndianReader<Endian, T2>> for EndianReader<Endian, T1> -where - Endian: Endianity, - T1: CloneStableDeref<Target = [u8]> + Debug, - T2: CloneStableDeref<Target = [u8]> + Debug, -{ - fn eq(&self, rhs: &EndianReader<Endian, T2>) -> bool { - self.bytes() == rhs.bytes() - } -} - -impl<Endian, T> Eq for EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ -} - -// This is separated out from `EndianReader` so that we can avoid running afoul -// of borrowck. We need to `read_slice(&mut self, ...) -> &[u8]` and then call -// `self.endian.read_whatever` on the result. The problem is that the returned -// slice keeps the `&mut self` borrow active, so we wouldn't be able to access -// `self.endian`. Splitting the sub-range out from the endian lets us work -// around this, making it so that only the `self.range` borrow is held active, -// not all of `self`. -// -// This also serves to encapsulate the unsafe code concerning `CloneStableDeref`. -// The `bytes` member is held so that the bytes live long enough, and the -// `CloneStableDeref` ensures these bytes never move. The `ptr` and `len` -// members point inside `bytes`, and are updated during read operations. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -struct SubRange<T> -where - T: CloneStableDeref<Target = [u8]> + Debug, -{ - bytes: T, - ptr: *const u8, - len: usize, -} - -unsafe impl<T> Send for SubRange<T> where T: CloneStableDeref<Target = [u8]> + Debug + Send {} - -unsafe impl<T> Sync for SubRange<T> where T: CloneStableDeref<Target = [u8]> + Debug + Sync {} - -impl<T> SubRange<T> -where - T: CloneStableDeref<Target = [u8]> + Debug, -{ - #[inline] - fn new(bytes: T) -> Self { - let ptr = bytes.as_ptr(); - let len = bytes.len(); - SubRange { bytes, ptr, len } - } - - #[inline] - fn bytes(&self) -> &[u8] { - // Safe because `T` implements `CloneStableDeref`, `bytes` can't be modified, - // and all operations that modify `ptr` and `len` ensure they stay in range. - unsafe { slice::from_raw_parts(self.ptr, self.len) } - } - - #[inline] - fn len(&self) -> usize { - self.len - } - - #[inline] - fn truncate(&mut self, len: usize) { - assert!(len <= self.len); - self.len = len; - } - - #[inline] - fn skip(&mut self, len: usize) { - assert!(len <= self.len); - self.ptr = unsafe { self.ptr.add(len) }; - self.len -= len; - } - - #[inline] - fn read_slice(&mut self, len: usize) -> Option<&[u8]> { - if self.len() < len { - None - } else { - // Same as for `bytes()`. - let bytes = unsafe { slice::from_raw_parts(self.ptr, len) }; - self.skip(len); - Some(bytes) - } - } -} - -impl<Endian, T> EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - /// Construct a new `EndianReader` with the given bytes. - #[inline] - pub fn new(bytes: T, endian: Endian) -> EndianReader<Endian, T> { - EndianReader { - range: SubRange::new(bytes), - endian, - } - } - - /// Return a reference to the raw bytes underlying this reader. - #[inline] - pub fn bytes(&self) -> &[u8] { - self.range.bytes() - } -} - -/// # Range Methods -/// -/// Unfortunately, `std::ops::Index` *must* return a reference, so we can't -/// implement `Index<Range<usize>>` to return a new `EndianReader` the way we -/// would like to. Instead, we abandon fancy indexing operators and have these -/// plain old methods. -impl<Endian, T> EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - /// Take the given `start..end` range of the underlying buffer and return a - /// new `EndianReader`. - /// - /// ``` - /// # #[cfg(feature = "std")] { - /// use gimli::{EndianReader, LittleEndian}; - /// use std::sync::Arc; - /// - /// let buf = Arc::<[u8]>::from(&[0x01, 0x02, 0x03, 0x04][..]); - /// let reader = EndianReader::new(buf.clone(), LittleEndian); - /// assert_eq!(reader.range(1..3), - /// EndianReader::new(&buf[1..3], LittleEndian)); - /// # } - /// ``` - /// - /// # Panics - /// - /// Panics if the range is out of bounds. - pub fn range(&self, idx: Range<usize>) -> EndianReader<Endian, T> { - let mut r = self.clone(); - r.range.skip(idx.start); - r.range.truncate(idx.len()); - r - } - - /// Take the given `start..` range of the underlying buffer and return a new - /// `EndianReader`. - /// - /// ``` - /// # #[cfg(feature = "std")] { - /// use gimli::{EndianReader, LittleEndian}; - /// use std::sync::Arc; - /// - /// let buf = Arc::<[u8]>::from(&[0x01, 0x02, 0x03, 0x04][..]); - /// let reader = EndianReader::new(buf.clone(), LittleEndian); - /// assert_eq!(reader.range_from(2..), - /// EndianReader::new(&buf[2..], LittleEndian)); - /// # } - /// ``` - /// - /// # Panics - /// - /// Panics if the range is out of bounds. - pub fn range_from(&self, idx: RangeFrom<usize>) -> EndianReader<Endian, T> { - let mut r = self.clone(); - r.range.skip(idx.start); - r - } - - /// Take the given `..end` range of the underlying buffer and return a new - /// `EndianReader`. - /// - /// ``` - /// # #[cfg(feature = "std")] { - /// use gimli::{EndianReader, LittleEndian}; - /// use std::sync::Arc; - /// - /// let buf = Arc::<[u8]>::from(&[0x01, 0x02, 0x03, 0x04][..]); - /// let reader = EndianReader::new(buf.clone(), LittleEndian); - /// assert_eq!(reader.range_to(..3), - /// EndianReader::new(&buf[..3], LittleEndian)); - /// # } - /// ``` - /// - /// # Panics - /// - /// Panics if the range is out of bounds. - pub fn range_to(&self, idx: RangeTo<usize>) -> EndianReader<Endian, T> { - let mut r = self.clone(); - r.range.truncate(idx.end); - r - } -} - -impl<Endian, T> Index<usize> for EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - type Output = u8; - fn index(&self, idx: usize) -> &Self::Output { - &self.bytes()[idx] - } -} - -impl<Endian, T> Index<RangeFrom<usize>> for EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - type Output = [u8]; - fn index(&self, idx: RangeFrom<usize>) -> &Self::Output { - &self.bytes()[idx] - } -} - -impl<Endian, T> Deref for EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - type Target = [u8]; - fn deref(&self) -> &Self::Target { - self.bytes() - } -} - -impl<Endian, T> Reader for EndianReader<Endian, T> -where - Endian: Endianity, - T: CloneStableDeref<Target = [u8]> + Debug, -{ - type Endian = Endian; - type Offset = usize; - - #[inline] - fn endian(&self) -> Endian { - self.endian - } - - #[inline] - fn len(&self) -> usize { - self.range.len() - } - - #[inline] - fn empty(&mut self) { - self.range.truncate(0); - } - - #[inline] - fn truncate(&mut self, len: usize) -> Result<()> { - if self.len() < len { - Err(Error::UnexpectedEof(self.offset_id())) - } else { - self.range.truncate(len); - Ok(()) - } - } - - #[inline] - fn offset_from(&self, base: &EndianReader<Endian, T>) -> usize { - let base_ptr = base.bytes().as_ptr() as *const u8 as usize; - let ptr = self.bytes().as_ptr() as *const u8 as usize; - debug_assert!(base_ptr <= ptr); - debug_assert!(ptr + self.bytes().len() <= base_ptr + base.bytes().len()); - ptr - base_ptr - } - - #[inline] - fn offset_id(&self) -> ReaderOffsetId { - ReaderOffsetId(self.bytes().as_ptr() as u64) - } - - #[inline] - fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset> { - let id = id.0; - let self_id = self.bytes().as_ptr() as u64; - let self_len = self.bytes().len() as u64; - if id >= self_id && id <= self_id + self_len { - Some((id - self_id) as usize) - } else { - None - } - } - - #[inline] - fn find(&self, byte: u8) -> Result<usize> { - self.bytes() - .iter() - .position(|x| *x == byte) - .ok_or_else(|| Error::UnexpectedEof(self.offset_id())) - } - - #[inline] - fn skip(&mut self, len: usize) -> Result<()> { - if self.len() < len { - Err(Error::UnexpectedEof(self.offset_id())) - } else { - self.range.skip(len); - Ok(()) - } - } - - #[inline] - fn split(&mut self, len: usize) -> Result<Self> { - if self.len() < len { - Err(Error::UnexpectedEof(self.offset_id())) - } else { - let mut r = self.clone(); - r.range.truncate(len); - self.range.skip(len); - Ok(r) - } - } - - #[inline] - fn to_slice(&self) -> Result<Cow<[u8]>> { - Ok(self.bytes().into()) - } - - #[inline] - fn to_string(&self) -> Result<Cow<str>> { - match str::from_utf8(self.bytes()) { - Ok(s) => Ok(s.into()), - _ => Err(Error::BadUtf8), - } - } - - #[inline] - fn to_string_lossy(&self) -> Result<Cow<str>> { - Ok(String::from_utf8_lossy(self.bytes())) - } - - #[inline] - fn read_slice(&mut self, buf: &mut [u8]) -> Result<()> { - match self.range.read_slice(buf.len()) { - Some(slice) => { - buf.copy_from_slice(slice); - Ok(()) - } - None => Err(Error::UnexpectedEof(self.offset_id())), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::endianity::NativeEndian; - use crate::read::Reader; - - fn native_reader<T: CloneStableDeref<Target = [u8]> + Debug>( - bytes: T, - ) -> EndianReader<NativeEndian, T> { - EndianReader::new(bytes, NativeEndian) - } - - const BUF: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; - - #[test] - fn test_reader_split() { - let mut reader = native_reader(BUF); - let left = reader.split(3).unwrap(); - assert_eq!(left, native_reader(&BUF[..3])); - assert_eq!(reader, native_reader(&BUF[3..])); - } - - #[test] - fn test_reader_split_out_of_bounds() { - let mut reader = native_reader(BUF); - assert!(reader.split(30).is_err()); - } - - #[test] - fn bytes_and_len_and_range_and_eq() { - let reader = native_reader(BUF); - assert_eq!(reader.len(), BUF.len()); - assert_eq!(reader.bytes(), BUF); - assert_eq!(reader, native_reader(BUF)); - - let range = reader.range(2..8); - let buf_range = &BUF[2..8]; - assert_eq!(range.len(), buf_range.len()); - assert_eq!(range.bytes(), buf_range); - assert_ne!(range, native_reader(BUF)); - assert_eq!(range, native_reader(buf_range)); - - let range_from = range.range_from(1..); - let buf_range_from = &buf_range[1..]; - assert_eq!(range_from.len(), buf_range_from.len()); - assert_eq!(range_from.bytes(), buf_range_from); - assert_ne!(range_from, native_reader(BUF)); - assert_eq!(range_from, native_reader(buf_range_from)); - - let range_to = range_from.range_to(..4); - let buf_range_to = &buf_range_from[..4]; - assert_eq!(range_to.len(), buf_range_to.len()); - assert_eq!(range_to.bytes(), buf_range_to); - assert_ne!(range_to, native_reader(BUF)); - assert_eq!(range_to, native_reader(buf_range_to)); - } - - #[test] - fn find() { - let mut reader = native_reader(BUF); - reader.skip(2).unwrap(); - assert_eq!( - reader.find(5), - Ok(BUF[2..].iter().position(|x| *x == 5).unwrap()) - ); - } - - #[test] - fn indexing() { - let mut reader = native_reader(BUF); - reader.skip(2).unwrap(); - assert_eq!(reader[0], BUF[2]); - } - - #[test] - #[should_panic] - fn indexing_out_of_bounds() { - let mut reader = native_reader(BUF); - reader.skip(2).unwrap(); - let _ = reader[900]; - } - - #[test] - fn endian() { - let reader = native_reader(BUF); - assert_eq!(reader.endian(), NativeEndian); - } - - #[test] - fn empty() { - let mut reader = native_reader(BUF); - assert!(!reader.is_empty()); - reader.empty(); - assert!(reader.is_empty()); - assert!(reader.bytes().is_empty()); - } - - #[test] - fn truncate() { - let reader = native_reader(BUF); - let mut reader = reader.range(2..8); - reader.truncate(2).unwrap(); - assert_eq!(reader.bytes(), &BUF[2..4]); - } - - #[test] - fn offset_from() { - let reader = native_reader(BUF); - let sub = reader.range(2..8); - assert_eq!(sub.offset_from(&reader), 2); - } - - #[test] - fn skip() { - let mut reader = native_reader(BUF); - reader.skip(2).unwrap(); - assert_eq!(reader.bytes(), &BUF[2..]); - } - - #[test] - fn to_slice() { - assert_eq!( - native_reader(BUF).range(2..5).to_slice(), - Ok(Cow::from(&BUF[2..5])) - ); - } - - #[test] - fn to_string_ok() { - let buf = b"hello, world!"; - let reader = native_reader(&buf[..]); - let reader = reader.range_from(7..); - assert_eq!(reader.to_string(), Ok(Cow::from("world!"))); - } - - // The rocket emoji (🚀 = [0xf0, 0x9f, 0x9a, 0x80]) but rotated left by one - // to make it invalid UTF-8. - const BAD_UTF8: &[u8] = &[0x9f, 0x9a, 0x80, 0xf0]; - - #[test] - fn to_string_err() { - let reader = native_reader(BAD_UTF8); - assert!(reader.to_string().is_err()); - } - - #[test] - fn to_string_lossy() { - let reader = native_reader(BAD_UTF8); - assert_eq!(reader.to_string_lossy(), Ok(Cow::from("����"))); - } - - #[test] - fn read_u8_array() { - let mut reader = native_reader(BAD_UTF8); - reader.skip(1).unwrap(); - let arr: [u8; 2] = reader.read_u8_array().unwrap(); - assert_eq!(arr, &BAD_UTF8[1..3]); - assert_eq!(reader.bytes(), &BAD_UTF8[3..]); - } -} |