I am using HDFql to create an HDF5 file. I am creating a group and putting some data into it and that works fine. I then add an attribute to the file (which also seems to work, since it shows up when I inspect the HDF5 file with an HDF editor), but I can't figure out how to read the value of the attribute. Here is a minimal example:
#include <iostream.h>
#include <HDFql.hpp>
int main (int argc, const char * argv[]) {
char script[1024];
//Create the HDF5 file and the group "test"
HDFql::execute("CREATE TRUNCATE FILE /tmp/test.h5");
HDFql::execute("USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP test");
//Generate some arbitrary data and place it in test/data
int data_length = 1000;
int data[data_length];
for(int i=0; i<data_length; i++) {data[i] = i;}
sprintf(script, "CREATE DATASET test/data AS INT(%d) VALUES FROM MEMORY %d",
data_length, HDFql::variableTransientRegister(data));
HDFql::execute(script);
//Create an attribute called "channels" and give it an arbitrary value of 11
HDFql::execute("CREATE ATTRIBUTE test/data/channels AS INT VALUES(11)");
//Show the attribute
HDFql::execute("SHOW ATTRIBUTE test/data/channels");
//Try to move the cursor to the attribute
HDFql::cursorLast();
//If that worked, print the attribute contents
if(HDFql::cursorGetInt())
{
std::cout << "channels = " << *HDFql::cursorGetInt() << std::endl;
} else
{
std::cout << "Couldn't find attribute" << std::endl;
}
HDFql::execute("CLOSE FILE");
}
I would expect the output to the console to be channels = 11
, instead I am getting channels = 1953719668
. Curiously, if I call cursorGetChar
instead, the return value is "t", and if I say
std::cout << "channels = " << HDFql::cursorGetChar() << std::endl;
the output becomes channels = test/data/channels
.
So I think I have misunderstood how exactly HDFql cursors work. So my question is: what is wrong with my code? And why is my code wrong?
Many thanks!
When you do SHOW ATTRIBUTE test/data/channels
you are basically testing for the existence of an attribute named channels
stored in test/data
. Since this attribute exists, function HDFql::execute
returns HDFql::Success
and the cursor is populated with the string test/data/channels
. On the other hand, if the attribute didn't exist, function HDFql::execute
would have returned HDFql::ErrorNotFound
and the cursor would be empty.
To read the value stored in attribute test/data/channels
do the following instead:
HDFql::execute("SELECT FROM test/data/channels");
HDFql::cursorFirst();
std::cout << "channels = " << *HDFql::cursorGetInt() << std::endl;