I’m simply trying to read the objects in a group using H5Literate2 and an iterator callback. Below is a snippet of the iterator function. When I run the search on a group that I know has 4 groups in it, the name variable is correct, but loc_id is the same for all of them.
Here’s a screenshot of some debug output: I’m printing the ID, name (an IP Address in this case) and the type.
Please can someone point me in the right direction? Although it’s been fun coding this up, with structures to aggregate the results, am I missing a trick and there’s a simpler helper function to do this? I looked in the Lite API but didn’t find.
EDIT I’ve confirmed that the value of loc_id I’m getting is different to the id of the group I’m doing the search on
The output is expected. The, possibly empty, link destination in the callback is name relative to loc_id.
I think you’ve compounded two issues:
Since you are using H5Literate, the first thing to do in the callback is to call H5Lget_info. That will tell you what kind of link your are dealing with (hard, soft, external, user-defined), which dictates how aggressive you can be regarding link traversal. Anything but hard links (H5L_TYPE_HARD) needs to be handled with caution because the destination might be nirvana.
Once you are confident that the link is traversable (to an object), you can use H5Oget_info_by_name (not H5Oget_info!) to learn more about the object.
Thanks. I feel I’m not understanding the use of IDs, so if I can just work with the returned names and types (which is working fine) then I’m good. So if do this:
use my code to find the names and types of objects in a group (say they are more groups as in my screenshot above)
open a group using H5Gopen2 which takes the group name and returns the ID, which I can use in other functions…
It’s as simple as that? These IDs that appear in the iterator aren’t needed? By me anyway.
IDs are just ephemeral API handles. They exist only for the duration of an [create,open] - close cycle.
The situation can be illustrated as follows:
"g1" "l1"
o ------> o ------> o
id1 id2 id3
WHERE
o - object
id - API handle
-> - link
"g1", "l1" - link names
We can work with the object identified by handle id3 directly through the API. If a name were required, we’d pass “.” (dot). We can refer to the same object as (loc_id=id2, name="l1") or (loc_id=id1, name="g1/l1"). OK?
If you have an ID, close it eventually (or resource leaks will ensue). You can check if an identifier is valid (wasn’t closed) via H5Iis_valid.
Yes.
By ‘iterator’ you mean the callback function, right? Whether you need the loc_id, etc. in such a callback depends on what the callback is supposed to achieve. If you just want to print the name, no you don’t. But remember that name has meaning only relative to loc_id.
Thanks. I do get how the IDs work for the open/close cycle and the use of paths in general H5Gopen(), H5GClose() calls. That is all working fine for me.
I was confused about what loc_id meant in the callback (iterator) function. Now I can see that it means the (ephemeral) ID of the containing group. And so a call to H5Oget_info_by_name(loc_id, name) as you suggested gets me the info I want on each object in that group. Yes it works.
The reason I was confused is that I found some sample code that then made a call to H5G_get_info(loc_id,…) i.e. no name argument. Implying that loc_id is the ID of each object. I see now why that doesn’t work.