use core::iter::FusedIterator;
use core::mem;
use core::ops::Range;
use zerocopy::{FromBytes, LayoutVerified, LittleEndian, Unaligned, U32};
#[allow(dead_code)]
#[derive(Debug, FromBytes, Unaligned)]
#[repr(packed)]
pub(crate) struct ApiSetHashEntryHeader {
hash: U32<LittleEndian>,
index: U32<LittleEndian>,
}
#[derive(Clone, Debug)]
pub struct ApiSetHashEntries<'a> {
section_bytes: &'a [u8],
range: Range<usize>,
}
impl<'a> ApiSetHashEntries<'a> {
pub(crate) const fn new(section_bytes: &'a [u8], range: Range<usize>) -> Self {
Self {
section_bytes,
range,
}
}
}
impl<'a> Iterator for ApiSetHashEntries<'a> {
type Item = ApiSetHashEntry<'a>;
fn next(&mut self) -> Option<Self::Item> {
let (header, _) = LayoutVerified::<_, ApiSetHashEntryHeader>::new_unaligned_from_prefix(
self.section_bytes.get(self.range.clone())?,
)?;
let entry = ApiSetHashEntry { header };
self.range.start += mem::size_of::<ApiSetHashEntryHeader>();
Some(entry)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.range.len() / mem::size_of::<ApiSetHashEntryHeader>();
(size, Some(size))
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let bytes_to_skip = n.checked_mul(mem::size_of::<ApiSetHashEntryHeader>())?;
self.range.start = self.range.start.checked_add(bytes_to_skip)?;
self.next()
}
}
impl<'a> ExactSizeIterator for ApiSetHashEntries<'a> {}
impl<'a> FusedIterator for ApiSetHashEntries<'a> {}
#[derive(Debug)]
pub struct ApiSetHashEntry<'a> {
header: LayoutVerified<&'a [u8], ApiSetHashEntryHeader>,
}
impl<'a> ApiSetHashEntry<'a> {
pub fn hash(&self) -> u32 {
self.header.hash.get()
}
pub fn index(&self) -> u32 {
self.header.index.get()
}
}