use crate::ShadowError;
pub fn block_span<const TS: usize, const BS: usize, const BC: usize>(
addr: u16,
len: usize,
) -> Result<(usize, usize), ShadowError> {
let (offset, end) = range_span::<TS>(addr, len)?;
let sb = offset / BS;
let eb = (end - 1) / BS;
if eb >= BC {
return Err(ShadowError::OutOfBounds);
}
Ok((sb, eb))
}
pub fn range_span<const TS: usize>(addr: u16, len: usize) -> Result<(usize, usize), ShadowError> {
if len == 0 {
return Err(ShadowError::ZeroLength);
}
let offset = addr as usize;
let end = offset.checked_add(len).ok_or(ShadowError::OutOfBounds)?;
if end > TS {
return Err(ShadowError::OutOfBounds);
}
Ok((offset, end))
}
#[test]
fn block_span_edge_cases() {
assert_eq!(block_span::<16, 4, 4>(0, 0), Err(ShadowError::ZeroLength));
assert_eq!(block_span::<16, 4, 4>(15, 2), Err(ShadowError::OutOfBounds));
assert_eq!(block_span::<16, 4, 4>(4, 1), Ok((1, 1)));
assert_eq!(block_span::<16, 4, 4>(4, 4), Ok((1, 1)));
assert_eq!(block_span::<16, 4, 4>(0, 16), Ok((0, 3)));
assert_eq!(block_span::<16, 4, 4>(15, 1), Ok((3, 3)));
}