When reading a compound data type, I first call H5TBget_filed_info(). This gives me arrays for names, sizes and offsets. Maybe I’m mistaking the meaning of the help text:
char *field_names[]
OUT: An array containing the names of the fields.
size_t *field_sizes
OUT: An array containing the size of the fields.
size_t *field_offsets
OUT: An array containing the offsets of the fields.
I was thinking that the field_offsets would be the offset for a given field in the compound data table. This doesn’t always seem to be the case. For example, I have a compound with the four fields char[16], uint_8, double, and double. Below are the sizes and offsets returned:
Size Offset
16 0
1 16
8 24
8 32
Which I would be okay with except that the total size of the chunked data is 36. What this tells me is that the data offset for the two doubles is off by 4. The data read from these locations for the two doubles comes out wrong. The data sets that I’m reading are unknown to me (see previous posts “Reading data from an unknown source” and …“Take 2”).
The above is the struct that I see from reading the data programmatically which agrees with HDF5View. A call to H5Tget_size() returns 208 – which is the CHUCK size reported in HDF5View for this compound.
The odd part is the following read by H5TBget_filed_info():
Offset Size
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 8
How do these sizes equate to 208? More importantly: How do I read these compounds in the correct locations? Is there a function for reading field values that I’m missing somewhere? My approach for getting the data from a compound is:
int fields = 0;
int num = 0;
int size = 0;
vector<char *> names;
vector<size_t> sizes;
vector<size_t> offsets;
hid_t did = H5Dopen(parent, name);
hid_t tdid = H5Dget_type(did);
H5T_class_t tclass = H5Tget_class(tdid);
switch (tclass){
case H5T_COMPOUND:
H5TBget_table_info(parent, name, &fields, &num);
sizes.resize(fields);
names.resize(fields);
offsets.resize(fields);
H5TBget_field_info(parent, name, &names[0], &sizes[0], &offsets[0], &size);
size_t chunk = H5Tget_size(tdid);
char *buf = calloc(fields, chunk);
H5Dread(did, tdid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
// From here, I parse the dataset using the offsets. This seems invalid.
std::vector<sn::example::Record> vec = h5::utils::get_test_data<sn::example::Record>(20);
h5::write(fd, "orm/partial/vector one_shot", vec ); // it will do the right thing!!!
H5CPP doesn’t per-se have a table API instead it comes with LLVM based compiler assisted reflection, you are free to code away with arbitrary complex POD structs, the descriptors are generated for you. You might also want to check out the h5::append operator, which provides throughput near the underlying filesystem.