COOLJAPAN
← All posts

OxiH5 0.2.0 Released — Superblock v1 Support, Full v2/v3 Extension Parsing, and an Object-Header Creation-Order Bug Fixed

OxiH5 0.2.0 adds superblock v1 parsing, v2/v3 superblock-extension decoding (B-tree K values, shared message table, file space info, driver info), and fixes a silent OCHK object-header creation-order misdecode. 494 tests passing across four crates — the sovereign scientific-data layer for the COOLJAPAN ecosystem.

release oxih5 pure-rust cooljapan noffi hdf5 scientific-data file-format io

Three ways a parser can fail quietly: reject a valid file, misreport its own metadata, and misdecode a message it thinks it understood. OxiH5 0.2.0 closes all three.

Today we released OxiH5 0.2.0 — a release that adds full support for HDF5 superblock version 1 (previously an outright parse failure), decodes the superblock extension block that versions 2 and 3 carry (B-tree ‘K’ values, shared message table, file space info, and driver info messages), fixes File::info() to report the real on-disk superblock version instead of a hardcoded 0, and fixes a creation-order-tracking bug that could silently misdecode object header messages spilled into a continuation block.

No libhdf5. No FFI. No -sys crates. OxiH5 parses the published HDF5 binary format — superblock, object headers, B-trees, heaps, filter pipelines, all eleven datatype classes — directly from bytes, using nothing but std. #![forbid(unsafe_code)] guards oxih5-core; the facade crate carries exactly one documented unsafe block, the mmap call behind open_mmap. It compiles to a single static binary, needs no system libraries and no C toolchain at build time, and stays WASM-friendly by construction.

Why OxiH5 0.2.0 is a game changer

Even a Pure-Rust HDF5 reader that handles the common case still has to get every corner of the binary format right — because the corners are exactly where real-world files diverge from the fixtures a test suite happens to cover:

OxiH5 0.2.0 ends all of that.

Technical Deep Dive: how superblock v1, extension parsing, and the OCHK fix fit together

  1. Superblock parsing — oxih5_format::superblock. parse() dispatches on the version byte read from the file; parse_v1 now sits alongside the existing v0/v2/v3 paths, accounting for the transitional format’s extra 4-byte insertion before decoding the Base Address and Root Group Symbol Table Entry.
  2. Extension decoding — read_superblock_extension + header::parse_messages. A v2/v3 superblock’s superblock_extension_address (when not the undefined-address sentinel) points at an ordinary object header; read_superblock_extension parses it through the same header::parse_messages path used everywhere else, then interprets the four message types it currently understands into a SuperblockExtension struct — unrecognized message types are ignored rather than rejected.
  3. Version/extension surfacing — File::info() / File::superblock_extension(). FileInfo now carries the real superblock_version and superblock_extension_address straight from the parsed Superblock, and the new File::superblock_extension() facade method calls read_superblock_extension on demand.
  4. Creation-order threading — parse_v2_blockparse_v2_ochk_block. The owning object header’s message flags (bit 2 = tracks creation order) now propagate into every OCHK continuation-block parse call, including continuations that themselves point at further continuations, so the per-message creation-order field is consistently skipped rather than only being handled correctly in the primary OHDR block.

Getting Started

cargo add oxih5
use oxih5::open;

let f = open("data.h5")?;

// New in 0.2.0: the real on-disk superblock version, not a hardcoded 0.
let info = f.info()?;
println!("superblock version: {}", info.superblock_version);

// New in 0.2.0: decode the v2/v3 superblock extension, if present.
if let Some(ext) = f.superblock_extension()? {
    if let Some(k) = ext.btree_k {
        println!(
            "B-tree K values: indexed_storage={}, group_internal={}, group_leaf={}",
            k.indexed_storage_internal_k, k.group_internal_k, k.group_leaf_k
        );
    }
    println!("file space info present: {}", ext.file_space_info_present);
}

// Superblock v1 files (the "transitional" format) now open like any other.
let ds = f.dataset("/temperature")?;
let values: Vec<f32> = ds.as_f32()?;

What’s New in 0.2.0

Tips

This is the foundation

OxiH5 belongs to NoFFI — the COOLJAPAN initiative retiring every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, Pure-Rust implementation. OxiH5’s assignment is hdf5-sys/hdf5 (and netcdf-sys on the read path); 0.2.0’s superblock v1 and extension support close two more gaps against real-world files that earlier versions couldn’t open or fully introspect.

It already has real consumers pinned at 0.2.0 across the workspace:

Repository: https://github.com/cool-japan/oxih5

Star the repo ⭐ if you want an HDF5 reader that gets superblock introspection right — the real version, the real extension contents — without libhdf5 anywhere in the build.

The era of a parser that either rejects a valid file or quietly hands back wrong metadata is over. Pure Rust HDF5 is here — and as of 0.2.0, it knows exactly which superblock it just read.

KitaSan at COOLJAPAN OÜ July 18, 2026

↑ Back to all posts