c++hdf5hdfql

Read Value of Attribute in HDFql


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!


Solution

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