fix(format): read enum and bool datasets through their base integer type

read_i64/read_u64/read_i32/read_f64/read_f32 refused enumeration
datatypes, including h5py's bool (an enum of int8), with a type
mismatch. Read them as their base type's integer values, the way array
datatypes already read through theirs.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-25 21:08:37 -05:00
co-authored by Claude Opus 5.5
parent 417c9516ca
commit c8c2930fc0
2 changed files with 53 additions and 7 deletions
+15 -7
View File
@@ -888,9 +888,9 @@ fn native_le_to_vec<T: Copy>(raw: &[u8], count: usize) -> Vec<T> {
/// Convert raw bytes to `f64` values.
pub fn read_as_f64(raw: &[u8], datatype: &Datatype) -> Result<Vec<f64>, FormatError> {
// Array datatypes (e.g. an array-typed compound member) are read as a flat
// sequence of their base elements.
if let Datatype::Array { base_type, .. } = datatype {
// Array datatypes read as a flat sequence of their base elements, and
// enumerations (h5py's bool among them) as their integer values.
if let Datatype::Array { base_type, .. } | Datatype::Enumeration { base_type, .. } = datatype {
return read_as_f64(raw, base_type);
}
ensure_numeric(datatype, "FloatingPoint or FixedPoint")?;
@@ -1030,7 +1030,9 @@ fn decode_scalar(
/// unsigned is 0), and floating-point data is truncated toward zero and
/// saturated, with NaN read as 0.
pub fn read_as_i64(raw: &[u8], datatype: &Datatype) -> Result<Vec<i64>, FormatError> {
if let Datatype::Array { base_type, .. } = datatype {
// Array datatypes read as a flat sequence of their base elements, and
// enumerations (h5py's bool among them) as their integer values.
if let Datatype::Array { base_type, .. } | Datatype::Enumeration { base_type, .. } = datatype {
return read_as_i64(raw, base_type);
}
ensure_numeric(datatype, "FixedPoint (signed)")?;
@@ -1075,7 +1077,9 @@ pub fn read_as_i64(raw: &[u8], datatype: &Datatype) -> Result<Vec<i64>, FormatEr
/// unsigned is 0), and floating-point data is truncated toward zero and
/// saturated, with NaN read as 0.
pub fn read_as_u64(raw: &[u8], datatype: &Datatype) -> Result<Vec<u64>, FormatError> {
if let Datatype::Array { base_type, .. } = datatype {
// Array datatypes read as a flat sequence of their base elements, and
// enumerations (h5py's bool among them) as their integer values.
if let Datatype::Array { base_type, .. } | Datatype::Enumeration { base_type, .. } = datatype {
return read_as_u64(raw, base_type);
}
ensure_numeric(datatype, "FixedPoint (unsigned)")?;
@@ -1098,7 +1102,9 @@ pub fn read_as_u64(raw: &[u8], datatype: &Datatype) -> Result<Vec<u64>, FormatEr
/// Convert raw bytes to `f32` values.
pub fn read_as_f32(raw: &[u8], datatype: &Datatype) -> Result<Vec<f32>, FormatError> {
if let Datatype::Array { base_type, .. } = datatype {
// Array datatypes read as a flat sequence of their base elements, and
// enumerations (h5py's bool among them) as their integer values.
if let Datatype::Array { base_type, .. } | Datatype::Enumeration { base_type, .. } = datatype {
return read_as_f32(raw, base_type);
}
ensure_numeric(datatype, "FloatingPoint")?;
@@ -1183,7 +1189,9 @@ pub fn read_as_f32(raw: &[u8], datatype: &Datatype) -> Result<Vec<f32>, FormatEr
/// unsigned is 0), and floating-point data is truncated toward zero and
/// saturated, with NaN read as 0.
pub fn read_as_i32(raw: &[u8], datatype: &Datatype) -> Result<Vec<i32>, FormatError> {
if let Datatype::Array { base_type, .. } = datatype {
// Array datatypes read as a flat sequence of their base elements, and
// enumerations (h5py's bool among them) as their integer values.
if let Datatype::Array { base_type, .. } | Datatype::Enumeration { base_type, .. } = datatype {
return read_as_i32(raw, base_type);
}
ensure_numeric(datatype, "FixedPoint")?;