reader: a one-element string array is a scalar

Masters exist that store sensor_material, description and the compression name as
shape (1,) rather than as true scalars - JUNGFRAU files from an early beamline
deployment do, and the application definition permits it. ReadString() required
rank 0 and threw on anything else, so the whole file was lost: the metadata parse
never finished and no image was ever examined.

Accept any shape holding exactly one element, and keep throwing for a string
dataset that genuinely holds several, which is a different quantity and cannot be
read into one std::string. The numeric path already worked this way
(HDF5DataSet_scalar_stored_rank1); this is the string half.

Measured: three long-wavelength rotation datasets that could not be opened at all
now process end to end.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
This commit is contained in:
2026-09-03 10:58:38 +02:00
co-authored by Claude Opus 5
parent 680c36c20d
commit c77ebe56c3
2 changed files with 33 additions and 2 deletions
+20
View File
@@ -137,6 +137,26 @@ TEST_CASE("HDF5DataSet_string", "[HDF5][Unit]") {
REQUIRE (H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
}
TEST_CASE("HDF5DataSet_string_stored_rank1", "[HDF5][Unit]") {
// Facilities write a one-element string array where the application definition allows a scalar -
// JUNGFRAU masters from an early beamline deployment store sensor_material and description that
// way - and the file is unreadable if that is refused, because the metadata parse never finishes.
{
HDF5File file("scratch2b.h5");
file.SaveVector("one", std::vector<std::string>{"Si"});
file.SaveVector("two", std::vector<std::string>{"Si", "CdTe"});
}
{
HDF5ReadOnlyFile file("scratch2b.h5");
HDF5DataSet one(file, "one");
CHECK(HDF5DataSpace(one).GetNumOfDimensions() == 1);
CHECK(one.ReadString() == "Si");
REQUIRE_THROWS(HDF5DataSet(file, "two").ReadString());
}
remove("scratch2b.h5");
REQUIRE (H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL) == 0);
}
TEST_CASE("HDF5DataSet_vector", "[HDF5][Unit]") {
std::vector<double> tmp_vector (16384);
tmp_vector[0] = 599.88;