I have to deal with hdf5 files that have some VL string attributes in the root level which might be created, but not set. Here is an example dump
HDF5 “Example” {
GROUP “/” {
ATTRIBUTE “Description” {
DATATYPE H5T_STRING {
STRSIZE H5T_VARIABLE;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SCALAR
DATA {
(0): “”
}
}
ATTRIBUTE “TimeStamp” {
DATATYPE H5T_STRING {
STRSIZE H5T_VARIABLE;
STRPAD H5T_STR_NULLTERM;
CSET H5T_CSET_ASCII;
CTYPE H5T_C_S1;
}
DATASPACE SCALAR
DATA {
(0): NULL
}
}
}
The TimeStamp attribute was created, but not set to a value. I use in general the c++ api to access those files.
Problem: Using c++ method Attribute::read(const DataType &mem_type, H5std_string &strg) in the H5Attribute.cpp will throw an unhandled exception because of method p_read_variable_len accessing those kind of attributes.
How can I use a workaround, e.g. using the h5 c api to check if a VL string attribute was only created but not set?
Thank you
Generally, you can call the C API directly in the application that uses the C++ API by passing the ID of an object into the C API. The ID can be obtained by <object>.getId().
I need to confirm whether the C++ API already has a wrapper to check for that and I’m going to check about the unhandled exception.
Thank you for your fast feedback.
Yes I know that, but then I have to read the attribute using H5Aread I guess (or are there any other methods?) to check whether the VL string attribute is set or not. And I have to use the same code in the c++ file to free again the allocated memory with free() in the case it was set.
How about to fix that in the c++ file H5Attribute.cpp by adding the following lines after line 536 in method p_read_variable_len. Either throwing an exception like
if (strg_C == NULL) {
throw AttributeIException("Attribute::read", "H5Aread string not set");
}
,or set the output parameter strg_C to an empty string:
if (strg_C == NULL) {
strg_C = "";
return;
}
Hi @stefan.judmann,
If you are not restricted to a particular library, you may want to have a look at HDFql, a high-level (declarative) language to solve the use-case you have posted. This use-case can easily be solved in C++ using HDFql as follows:
// include HDFql C++ header file (make sure it can be found by the C++ compiler)
#include <cstdlib>
#include <iostream>
#include "HDFql.hpp"
int main(int argc, char *argv[])
{
// declare variable "value" and initialize it to NULL
char *value = NULL;
// create an HDF5 file named "example.h5" and use (i.e. open) it
HDFql::execute("CREATE AND USE FILE example.h5");
// create an attribute named "Description" of data type varchar with an initial value "" (i.e. an empty string)
HDFql::execute("CREATE ATTRIBUTE Description AS VARCHAR VALUES(\"\")");
// create an attribute named "TimeStamp" of data type varchar without an initial value (i.e. it is NULL)
HDFql::execute("CREATE ATTRIBUTE TimeStamp AS VARCHAR");
// register variable "value" for subsequent use (by HDFql)
HDFql::variableRegister(&value);
// select (i.e. read) data from dataset "Description" and populate variable "value" with it
HDFql::execute("SELECT FROM Description INTO MEMORY 0");
// display value stored in variable "value"
if (value == NULL)
{
std::cout << "value is NULL" << std::endl;
}
else
{
std::cout << "value is " << value << std::endl; // this message should be displayed
}
// select (i.e. read) data from dataset "TimeStamp" and populate variable "value" with it
HDFql::execute("SELECT FROM TimeStamp INTO MEMORY 0");
// display value stored in variable "value"
if (value == NULL)
{
std::cout << "value is NULL" << std::endl; // this message should be displayed
}
else
{
std::cout << "value is " << value << std::endl;
}
// unregister variable "value" as it is no longer used (by HDFql)
HDFql::variableUnregister(&value);
// close file currently in use
HDFql::execute("CLOSE FILE");
return EXIT_SUCCESS;
}
Hope it helps!
Hello @contact ,
thank you for this information.
We have a .net application under windows that uses hdf5 a data storage solution. The code base uses a managed c++ wrapper using a build of static libs from the original unmanaged hdf5 sources.
So, our only hdf5 dependent library is that one and only managed c++ assembly, which has no other dependencies. Not sure if we can easily add HDFql as a static lib to our project.
Hi @stefan.judmann,
In the latest release of HDFql (version 2.5.0), we no longer include its static library. If you are interested, please use version 2.4.0 (or earlier) as it contains a static library of HDFql.
For your information, HDFql also supports C#, C, Java, Python, Fortran and R (besides C++).
Hope it helps!