# HG changeset patch # User Daniel Davis # Date 1559613795 25200 # Node ID 9e5c1d343a2c58040f3065fe9730e4087c9d6d5b # Parent 30f53f7a7293184f38b832a6494901636f5f2015 Skip HDF5 elements which are unrecognized, but continue reading file (bug #32756). * ls-hdf5.cc (hdf5_make_range_type): New function. * ls-hdf5.cc (hdf5_read_next_data_internal): create a new range_type variable with hdf5_make_range_type(). When decoding element type, check whether element is a range with df5_types_compatible and range_type variable. If decode fails, issue a warning and continue. diff -r 30f53f7a7293 -r 9e5c1d343a2c libinterp/corefcn/ls-hdf5.cc --- a/libinterp/corefcn/ls-hdf5.cc Mon Jun 03 09:04:41 2019 -0700 +++ b/libinterp/corefcn/ls-hdf5.cc Mon Jun 03 19:03:15 2019 -0700 @@ -414,6 +414,24 @@ #if defined (HAVE_HDF5) +// The following subroutine creates an HDF5 representation of the way +// we will store Octave range types (triplets of floating-point numbers). +// NUM_TYPE is the HDF5 numeric type to use for storage +// (e.g., H5T_NATIVE_DOUBLE to save as 'double'). +// Note that any necessary conversions are handled automatically by HDF5. + +static hid_t +hdf5_make_range_type (hid_t num_type) +{ + hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3); + + H5Tinsert (type_id, "base", 0 * sizeof (double), num_type); + H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type); + H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type); + + return type_id; +} + // This function is designed to be passed to H5Giterate, which calls it // on each data item in an HDF5 file. For the item whose name is NAME in // the group GROUP_ID, this function sets dv->tc to an Octave representation @@ -686,6 +704,7 @@ else if (type_class_id == H5T_COMPOUND) { hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); + hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE); if (hdf5_types_compatible (type_id, complex_type)) { @@ -700,17 +719,25 @@ H5Sclose (space_id); } - else - // Assume that if its not complex its a range. - // If its not, it'll be rejected later in the range code. - d->tc = type_info.lookup_type ("range"); + else if (hdf5_types_compatible (type_id, range_type)) + { + // If it's not a complex, check if it's a range + d->tc = octave_value_typeinfo::lookup_type ("range"); + } + else // Otherwise, just ignore it with a warning. + { + warning ("load: can't read `%s' (unknown datatype)", name); + retval = 0; // unknown datatype; skip + return retval; + } + H5Tclose (range_type); H5Tclose (complex_type); } else { warning ("load: can't read '%s' (unknown datatype)", name); - retval = 0; // unknown datatype; skip + retval = 0; // unknown datatype; skip return retval; }