0

Is it possible to do this?

I have an array containing Nvl HDF5-variable-length-arrays already written to a hdf5 file. I can read in the entire data by (the following snippet is in c++, but answers using the C version of hdf5 API are equally welcome)

hvl_t vl[Nvl];
dset.read(vl, VarLenType(&PredType:NATIVE_INT));

However, if I only want to read the length of each variable-length object, i.e., vl[i].len (for i=0 to Nvl-1), how can I do it without reading in the data vl[].p as well?

Kambrian
  • 329
  • 2
  • 7
  • Yes, using both C and C++ tags is appropriate because the HDF5 C++ wrapper follows the reference C API very closely. – Simon Oct 12 '15 at 21:20
  • @Simon: That is not a good enough reason. Tag the language you're actually using. Not some other language, some other language that looks a bit the same, or some other language a library was written in. The language you're _actually using_. – Lightness Races in Orbit Oct 12 '15 at 21:48

2 Answers2

1

Yes it can be done even though there is no direct function call to get it. You have to resort to the equivalent of the classical array size macro in C: sizeof(x) / sizeof(x[0]).

If your variable length array has type vl_type, then you can get its size in bytes with vl_size = H5Dvlen_get_buf_size(vl_type). You then need to divide this size by the size in bytes of the type of the elements. This type can be found with elem_type = H5Tget_super(vl_type) and its size in bytes with elem_size = H5Tget_size(elem_type).

Finally you have the length of the variable length array: vl_size / elem_size.

PS: I have used the C API here because the documentation is better but it works the same in C++.

Simon
  • 31,675
  • 9
  • 80
  • 92
  • That is _not_ the recommended way to get an array's size in C++. It's error prone and dangerous. See why accurate language tags matter? That being said ... I'm not even sure how else you'd do it with VLAs. Mainly because VLAs don't exist in C++. See why accurate language tags matter? – Lightness Races in Orbit Oct 12 '15 at 21:49
  • @LightnessRacesinOrbit Then feel free to remove the C++ tag as well because the language is irrelevant to the question :D – Simon Oct 12 '15 at 21:51
  • @Si​​​​​​​​​​​​mon: Were that true, the question would be off-topic. – Lightness Races in Orbit Oct 12 '15 at 21:55
  • @Simon: Thank you! But `H5Dvlen_get_buf_size` appears to be returning the total size of the buffer. What I want is the size of each element (i.e., `vl[i].len, for i=0 to Nvl-1`). Maybe possible with `H5Diterate`? – Kambrian Oct 13 '15 at 01:19
  • Looping through the elements (with hyperslab selection) and then query the size of each selection does the job! Not sure if this is efficient though. I've posted a snippet in a separate answer because I cannot format the code block in this comment. – Kambrian Oct 13 '15 at 02:19
0

Following Simon's answer, looping through the elements using hyperslab and then query the size of each element does the job.

hsize_t dim[1];
VarLenType vl_t(PredType:NATIVE_INT);
DataSpace dspace=dset.getSpace();
dspace.getSimpleExtentDims(dim);
hsize_t count[]={1}, offset[]={0}, stride[]={1}, block[]={1};
for(offset[0]=0;offset[0]<dim[0];offset[0]++)
{
      dspace.selectHyperslab(H5S_SELECT_SET, count, offset, stride, block); 
      cout<<dset.getVlenBufSize(vl_t, dspace)/vl_t.getSuper().getSize()<<" ";
}
Kambrian
  • 329
  • 2
  • 7