use crate::util::{read_i32_le, read_u16_le, read_u32_le};
pub struct ArrayDesc<'a> {
bytes: &'a [u8],
}
impl<'a> ArrayDesc<'a> {
pub(crate) fn new(bytes: &'a [u8]) -> Self {
Self { bytes }
}
#[inline]
pub fn element_type(&self) -> i32 {
read_i32_le(self.bytes, 0x00).unwrap_or(-1)
}
#[inline]
pub fn num_dims(&self) -> u16 {
read_u16_le(self.bytes, 0x04).unwrap_or(0)
}
#[inline]
pub fn flags(&self) -> u16 {
read_u16_le(self.bytes, 0x06).unwrap_or(0)
}
pub fn bound(&self, index: usize) -> Option<SafeArrayBound> {
if index >= self.num_dims() as usize {
return None;
}
let base = 0x08 + index * 8;
let c_elements = read_u32_le(self.bytes, base)?;
let l_lbound = read_i32_le(self.bytes, base + 4)?;
Some(SafeArrayBound {
c_elements,
l_lbound,
})
}
#[inline]
pub fn size(&self) -> usize {
0x08 + (self.num_dims() as usize) * 8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SafeArrayBound {
c_elements: u32,
l_lbound: i32,
}
impl SafeArrayBound {
#[inline]
pub fn count(&self) -> u32 {
self.c_elements
}
#[inline]
pub fn lower_bound(&self) -> i32 {
self.l_lbound
}
}