VL string attribute not set

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;
}

I’m looking into this.

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!