Range reads M0/M1 (indexed lookups, Storage trait), ZFP, in-place editing #17

Merged
osobh merged 52 commits from feat/p3-range-zfp-edit into main 2026-09-26 20:42:22 +00:00
2 changed files with 60 additions and 0 deletions
Showing only changes of commit 6248b411f0 - Show all commits
+59
View File
@@ -0,0 +1,59 @@
//! File address and length → in-memory index conversion.
//!
//! HDF5 addresses and lengths are 64-bit; the file is parsed through a
//! `&[u8]` indexed by `usize`. On a 64-bit target every `u64` fits, but on a
//! 32-bit one (`wasm32`, `i686`, `thumbv7em`) an address past `usize::MAX`
//! used to be truncated by an `as usize` cast — silently pointing at another
//! part of the file — or to panic. [`to_usize`] is the one conversion the
//! parsers use instead: such an address is a clean
//! [`FormatError::Overflow`]. It cannot be inside the data anyway: no slice
//! is longer than `isize::MAX` bytes.
#[cfg(not(feature = "std"))]
use alloc::format;
use crate::error::FormatError;
/// A file address, offset or length from the file as a `usize` index.
///
/// Fails with [`FormatError::Overflow`] when the value does not fit this
/// platform's `usize` (only possible on targets narrower than 64 bits).
#[inline]
pub fn to_usize(value: u64) -> Result<usize, FormatError> {
usize::try_from(value).map_err(|_| too_large(value))
}
#[cold]
#[inline(never)]
fn too_large(value: u64) -> FormatError {
FormatError::Overflow(format!(
"file address or length {value:#x} exceeds this platform's address space"
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn values_that_fit_convert_exactly() {
assert_eq!(to_usize(0), Ok(0));
assert_eq!(to_usize(0x1234), Ok(0x1234));
assert_eq!(to_usize(usize::MAX as u64), Ok(usize::MAX));
}
#[test]
fn values_past_usize_max_are_an_error_not_truncated() {
// Only reachable where usize is narrower than u64; on a 64-bit host
// every u64 fits, which the first branch checks instead.
if let Some(past) = (usize::MAX as u64).checked_add(1) {
let err = to_usize(past).unwrap_err();
assert!(matches!(err, FormatError::Overflow(_)), "{err:?}");
// The value an `as usize` cast would have produced is not returned.
assert!(to_usize(u64::MAX).is_err());
assert!(to_usize(past + 0x10).is_err());
} else {
assert_eq!(to_usize(u64::MAX), Ok(u64::MAX as usize));
}
}
}
+1
View File
@@ -57,6 +57,7 @@
#[cfg(not(feature = "std"))]
extern crate alloc;
pub mod addr;
pub mod attribute;
pub mod attribute_info;
pub mod btree_v1;