COOLJAPAN
← All posts

OxiH5 0.1.4 Released — Virtual Dataset Support, Chunked Variable-Length Reads, and a Global-Heap Decode Bug Fixed

OxiH5 0.1.4, the COOLJAPAN Pure-Rust HDF5 reader, adds Virtual Dataset (VDS) resolution, chunked variable-length dataset reads, szip RAW-mode chunk decoding, and soft-link-to-external-link chains, plus a fix for a silently mis-decoded global-heap reference. 486 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

A parser that refuses to open a file is an inconvenience. A parser that opens it and quietly hands back the wrong values is a hazard — OxiH5 0.1.4 closes one of each.

Today we released OxiH5 0.1.4 — a release that closes five real gaps in the COOLJAPAN Pure-Rust HDF5 reader: Virtual Dataset (VDS) resolution, chunked variable-length dataset reads (with a new dataset_vlen_sequences API), szip RAW-mode chunk decoding, soft-link→external-link chain resolution, and a fix for a global-heap reference bug that was silently mis-decoding real-world variable-length data.

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.1.4 is a game changer

Even with a working Pure-Rust HDF5 reader in hand, a handful of real-world file patterns still forced a fallback to libhdf5 — or, worse, produced a wrong answer with no error at all:

OxiH5 0.1.4 ends all of that.

Technical Deep Dive: how VDS, chunked vlen, and the hardening fit together

  1. Virtual Dataset resolution — oxih5_format::vds + File. VdsMapping / VdsEntry / VdsSelection (None / All / Hyperslab) model the HDF5 spec’s global-heap VDS mapping block; parse_vds_mapping / parse_vds_block decode it, and selection_element_offsets turns a selection into concrete row-major element positions. Point-list (H5S_SEL_POINTS) selections inside a mapping are recognized and rejected with a named error rather than silently mishandled — the same “honest gap” discipline as the rest of OxiH5.
  2. Chunked vlen assembly — the chunked-read path in oxih5-format. The new on_disk_elem_footprint helper tells the chunk assembler how many bytes a vlen element actually occupies on disk (always 16, the global-heap reference width) versus its logical size, so chunk boundaries and hyperslab intersections compute correctly for vlen data for the first time.
  3. szip RAW mode — filters::apply_pipeline_sized. apply_pipeline is now a thin wrapper around apply_pipeline_sized(..., expected_out_len: None); only szip’s RAW mode ever needs Some(len), since it’s the one filter whose bitstream carries no self-describing length.
  4. Link resolution and hardening. Soft-link and external-link navigation moved out of oxih5/src/lib.rs into a new internal links.rs module — both to keep source files under the workspace’s 2000-line limit and to host the new soft→external chain logic. Independently, fractal_heap.rs‘s header parser now reads the “I/O Filters’ Encoded Length” field at its correct byte offset and width (it was reading the wrong single byte before), so a filtered fractal-heap root direct block is finally detected instead of silently rejected.

Getting Started

cargo add oxih5
use oxih5::open;

// Virtual Datasets (HDF5 layout class 3) now resolve transparently through
// the same read APIs — no code changes required, they simply stop
// returning `OxiH5Error::NotImplemented`.
let f = open("ensemble.h5")?;
let ds = f.dataset("/stitched_temperature")?;
let values: Vec<f32> = ds.as_f32()?;

// New in 0.1.4: decode a variable-length *sequence* dataset (datatype
// class 9), contiguous or chunked, in one call.
let sequences = f.dataset_vlen_sequences("/variable_length_records")?;
println!("{} sequences decoded", sequences.len());

// Chunked variable-length strings and sequences now support hyperslab
// slicing too.
let region = f.dataset_slice("/chunked_vlen_strings", &[0..10])?;

Reading szip RAW-mode chunks needs the new feature flag:

[dependencies]
oxih5 = { version = "0.1.4", features = ["szip"] }

What’s New in 0.1.4

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.1.4’s VDS and chunked-vlen support close two of the largest remaining gaps against that goal.

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

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

Star the repo ⭐ if you want HDF5’s trickiest read-path features — virtual datasets, chunked variable-length data, RAW-mode szip — working in Rust without libhdf5 anywhere in the build.

The era of a scientific-data parser choosing between “fail outright” and “succeed with a silently wrong answer” is over. Pure Rust HDF5 is here — and as of 0.1.4, more of it works correctly than ever.

KitaSan at COOLJAPAN OÜ July 17, 2026

↑ Back to all posts