From 57993b61d374ae5cb9a956d9ee28bb7cdc7064ea Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 22 Aug 2003 08:50:01 -0500 Subject: [svn-r7391] Purpose: Bug fix Description: H5Gget_num_objs, H5Gget_objname_by_idx and H5Gget_objtype_by_idx were only accepting a group ID, instead of a location ID, as our documentation for them stated. Solution: Allow them to accept a location ID. Platforms tested: FreeBSD 4.8 (sleipnir) h5committest --- release_docs/RELEASE.txt | 3 ++ src/H5G.c | 113 +++++++++++++++++++++++++++++------------------ src/H5Gnode.c | 7 ++- src/H5Gpkg.h | 13 +++--- src/H5Gpublic.h | 4 +- test/titerate.c | 25 +++++++++++ 6 files changed, 110 insertions(+), 55 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 340c479..d9c50a2 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -73,6 +73,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - Corrected bugs in H5Gget_num_objs, H5Gget_objname_by_idx and + H5Gget_objtype_by_idx to allow them to accept location IDs, not just + group IDs. QAK - 2003/08/21 - Corrected bug when using scalar dataspace for memory selection and operating on chunked dataset. QAK - 2003/08/18 - Corrected bugs with multiple '/' characters in names for H5Glink diff --git a/src/H5G.c b/src/H5G.c index 6dc0ca7..375277f 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -180,9 +180,9 @@ static herr_t H5G_linkval(H5G_entry_t *loc, const char *name, size_t size, static herr_t H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc, const char *dst_name, hid_t dxpl_it); static herr_t H5G_unlink(H5G_entry_t *loc, const char *name, hid_t dxpl_id); -static herr_t H5G_get_num_objs(H5G_t *grp, hsize_t *num_objs, hid_t dxpl_id); -static ssize_t H5G_get_objname_by_idx(H5G_t *grp, hsize_t idx, char* name, size_t size, hid_t dxpl_id); -static H5G_obj_t H5G_get_objtype_by_idx(H5G_t *grp, hsize_t idx, hid_t dxpl_id); +static herr_t H5G_get_num_objs(H5G_entry_t *grp, hsize_t *num_objs, hid_t dxpl_id); +static ssize_t H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id); +static H5G_obj_t H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id); static int H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key); static herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/, H5G_entry_t *obj_ent/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id); @@ -381,6 +381,7 @@ H5Giterate(hid_t loc_id, const char *name, int *idx, int _idx = 0; H5G_bt_ud2_t udata; H5G_entry_t *loc = NULL; + H5G_t *grp = NULL; herr_t ret_value; FUNC_ENTER_API(H5Giterate, FAIL); @@ -402,15 +403,16 @@ H5Giterate(hid_t loc_id, const char *name, int *idx, * Open the group on which to operate. We also create a group ID which * we can pass to the application-defined operator. */ - if (NULL==(udata.group = H5G_open (loc, name, H5AC_dxpl_id))) + if (NULL==(grp = H5G_open (loc, name, H5AC_dxpl_id))) HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group"); - if ((udata.group_id=H5I_register (H5I_GROUP, udata.group))<0) { - H5G_close(udata.group); + if ((udata.group_id=H5I_register (H5I_GROUP, grp))<0) { + H5G_close(grp); HGOTO_ERROR (H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group"); } /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ udata.skip = *idx; + udata.ent = &(grp->ent); udata.op = op; udata.op_data = op_data; @@ -418,11 +420,11 @@ H5Giterate(hid_t loc_id, const char *name, int *idx, udata.final_ent = 0; /* Iterate over the group members */ - if ((ret_value = H5B_iterate (H5G_fileof(udata.group), H5AC_dxpl_id, H5B_SNODE, - H5G_node_iterate, udata.group->ent.cache.stab.btree_addr, &udata))<0) + if ((ret_value = H5B_iterate (H5G_fileof(grp), H5AC_dxpl_id, H5B_SNODE, + H5G_node_iterate, udata.ent->cache.stab.btree_addr, &udata))<0) HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); - H5I_dec_ref (udata.group_id); /*also closes udata.group*/ + H5I_dec_ref (udata.group_id); /*also closes 'grp'*/ /* Check for too high of a starting index (ex post facto :-) */ /* (Skipping exactly as many entries as are in the group is currently an error) */ @@ -455,22 +457,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Gget_num_objs(hid_t group_id, hsize_t *num_objs) +H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs) { - H5G_t *group = NULL; + H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ herr_t ret_value; FUNC_ENTER_API(H5Gget_num_objs, FAIL); - H5TRACE2("e","i*h",group_id,num_objs); + H5TRACE2("e","i*h",loc_id,num_objs); /* Check args */ - if (NULL==(group = H5I_object_verify(group_id,H5I_GROUP))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); + if (NULL==(loc=H5G_loc (loc_id))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID"); + if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); if (!num_objs) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "nil pointer"); /* Call private function. */ - ret_value = H5G_get_num_objs(group, num_objs, H5AC_ind_dxpl_id); + ret_value = H5G_get_num_objs(loc, num_objs, H5AC_ind_dxpl_id); done: FUNC_LEAVE_API(ret_value); @@ -502,28 +506,30 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Gget_objname_by_idx(hid_t group_id, hsize_t idx, char *name, size_t size) +H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size) { - H5G_t *group = NULL; + H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ hsize_t num_objs; ssize_t ret_value = FAIL; FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL); - H5TRACE4("Zs","ihsz",group_id,idx,name,size); + H5TRACE4("Zs","ihsz",loc_id,idx,name,size); /* Check args */ - if (NULL==(group = H5I_object_verify(group_id,H5I_GROUP))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); + if (NULL==(loc=H5G_loc (loc_id))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID"); + if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); if (!name) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "nil pointer for name"); - if (H5G_get_num_objs(group, &num_objs, H5AC_ind_dxpl_id)<0) + if (H5G_get_num_objs(loc, &num_objs, H5AC_ind_dxpl_id)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to retrieve number of members"); if(idx >= num_objs) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound"); /*call private function*/ - ret_value = H5G_get_objname_by_idx(group, idx, name, size, H5AC_ind_dxpl_id); + ret_value = H5G_get_objname_by_idx(loc, idx, name, size, H5AC_ind_dxpl_id); done: FUNC_LEAVE_API(ret_value); @@ -548,26 +554,28 @@ done: *------------------------------------------------------------------------- */ H5G_obj_t -H5Gget_objtype_by_idx(hid_t group_id, hsize_t idx) +H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) { - H5G_t *group = NULL; + H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ hsize_t num_objs; H5G_obj_t ret_value; FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN); - H5TRACE2("Is","ih",group_id,idx); + H5TRACE2("Is","ih",loc_id,idx); /* Check args */ - if (NULL==(group = H5I_object_verify(group_id,H5I_GROUP))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group"); + if (NULL==(loc=H5G_loc (loc_id))) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID"); + if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) + HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); - if (H5G_get_num_objs(group, &num_objs, H5AC_ind_dxpl_id)<0) + if (H5G_get_num_objs(loc, &num_objs, H5AC_ind_dxpl_id)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unable to retrieve number of members"); if(idx >= num_objs) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound"); /*call private function*/ - ret_value = H5G_get_objtype_by_idx(group, idx, H5AC_ind_dxpl_id); + ret_value = H5G_get_objtype_by_idx(loc, idx, H5AC_ind_dxpl_id); done: FUNC_LEAVE_API(ret_value); @@ -2562,16 +2570,23 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_get_num_objs(H5G_t *grp, hsize_t *num_objs, hid_t dxpl_id) +H5G_get_num_objs(H5G_entry_t *loc, hsize_t *num_objs, hid_t dxpl_id) { herr_t ret_value; FUNC_ENTER_NOAPI(H5G_get_num_objs, FAIL); + /* Sanity check */ + assert(loc); + assert(loc->type==H5G_CACHED_STAB); + assert(num_objs); + + /* Reset the number of objects in the group */ *num_objs = 0; + /* Iterate over the group members */ - if ((ret_value = H5B_iterate (H5G_fileof(grp), dxpl_id, H5B_SNODE, - H5G_node_sumup, grp->ent.cache.stab.btree_addr, num_objs))<0) + if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE, + H5G_node_sumup, loc->cache.stab.btree_addr, num_objs))<0) HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed"); done: @@ -2597,21 +2612,26 @@ done: *------------------------------------------------------------------------- */ static ssize_t -H5G_get_objname_by_idx(H5G_t *grp, hsize_t idx, char* name, size_t size, hid_t dxpl_id) +H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id) { - ssize_t ret_value; - H5G_bt_ud3_t udata; + H5G_bt_ud3_t udata; /* Iteration information */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_get_objname_by_idx, FAIL); + /* Sanity check */ + assert(loc); + assert(loc->type==H5G_CACHED_STAB); + + /* Set iteration information */ udata.idx = idx; udata.num_objs = 0; - udata.group = grp; + udata.ent = loc; udata.name = NULL; /* Iterate over the group members */ - if ((ret_value = H5B_iterate (H5G_fileof(grp), dxpl_id, H5B_SNODE, - H5G_node_name, grp->ent.cache.stab.btree_addr, &udata))<0) + if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE, + H5G_node_name, loc->cache.stab.btree_addr, &udata))<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed"); ret_value = (ssize_t)HDstrlen(udata.name); @@ -2647,20 +2667,25 @@ done: *------------------------------------------------------------------------- */ static H5G_obj_t -H5G_get_objtype_by_idx(H5G_t *grp, hsize_t idx, hid_t dxpl_id) +H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id) { - H5G_bt_ud3_t udata; /* User data for B-tree callback */ - H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */ + H5G_bt_ud3_t udata; /* User data for B-tree callback */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_get_objtype_by_idx, FAIL); + /* Sanity check */ + assert(loc); + assert(loc->type==H5G_CACHED_STAB); + + /* Set iteration information */ udata.idx = idx; udata.num_objs = 0; - udata.group = grp; + udata.ent = loc; /* Iterate over the group members */ - if (H5B_iterate (H5G_fileof(grp), dxpl_id, H5B_SNODE, - H5G_node_type, grp->ent.cache.stab.btree_addr, &udata)<0) + if (H5B_iterate (loc->file, dxpl_id, H5B_SNODE, + H5G_node_type, loc->cache.stab.btree_addr, &udata)<0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed"); ret_value = udata.type; diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 65c463e..3524159 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1294,7 +1294,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, if (bt_udata->skip>0) { --bt_udata->skip; } else { - name = H5HL_peek (f, dxpl_id, bt_udata->group->ent.cache.stab.heap_addr, name_off[i]); + name = H5HL_peek (f, dxpl_id, bt_udata->ent->cache.stab.heap_addr, name_off[i]); assert (name); n = HDstrlen (name); if (n+1>sizeof(buf)) { @@ -1304,8 +1304,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, s = buf; } HDstrcpy (s, name); - ret_value = (bt_udata->op)(bt_udata->group_id, s, - bt_udata->op_data); + ret_value = (bt_udata->op)(bt_udata->group_id, s, bt_udata->op_data); if (s!=buf) H5MM_xfree (s); } @@ -1409,7 +1408,7 @@ H5G_node_name(H5F_t *f, hid_t dxpl_id, void UNUSED *_lt_key, haddr_t addr, if(bt_udata->idx >= bt_udata->num_objs && bt_udata->idx < (bt_udata->num_objs+sn->nsyms)) { loc_idx = bt_udata->idx - bt_udata->num_objs; name_off = sn->entry[loc_idx].name_off; - name = H5HL_peek (f, dxpl_id, bt_udata->group->ent.cache.stab.heap_addr, name_off); + name = H5HL_peek (f, dxpl_id, bt_udata->ent->cache.stab.heap_addr, name_off); assert (name); bt_udata->name = H5MM_strdup (name); HGOTO_DONE(H5B_ITER_STOP); diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index f1cd427..e599905 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -89,13 +89,13 @@ typedef struct H5G_bt_ud1_t { typedef struct H5G_bt_ud2_t { /* downward */ hid_t group_id; /*group id to pass to iteration operator */ - struct H5G_t *group; /*the group to which group_id points */ + H5G_entry_t *ent; /*the entry to which group_id points */ int skip; /*initial entries to skip */ H5G_iterate_t op; /*iteration operator */ void *op_data; /*user-defined operator data */ /* upward */ - int final_ent; /*final entry looked at */ + int final_ent; /*final entry looked at */ } H5G_bt_ud2_t; @@ -104,10 +104,13 @@ typedef struct H5G_bt_ud2_t { * H5B_iterate function. */ typedef struct H5G_bt_ud3_t { - struct H5G_t *group; /*the group to which group_id points */ - hsize_t idx; /*index of group member to be querried */ - char *name; /*member name to be returned */ + /* downward */ + H5G_entry_t *ent; /*the entry of group being queried */ + hsize_t idx; /*index of group member to be queried */ hsize_t num_objs; /*the number of objects having been traversed*/ + + /* upward */ + char *name; /*member name to be returned */ H5G_obj_t type; /*member type to be returned */ } H5G_bt_ud3_t; diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 9526904..2a37fef 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -94,8 +94,8 @@ H5_DLL herr_t H5Gclose(hid_t group_id); H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5G_iterate_t op, void *op_data); H5_DLL herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs); -H5_DLL ssize_t H5Gget_objname_by_idx(hid_t group_id, hsize_t idx, char* name, size_t size); -H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t group_id, hsize_t idx); +H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char* name, size_t size); +H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); H5_DLL herr_t H5Gmove2(hid_t src_loc, const char *src, hid_t dst_loc, const char *dst); H5_DLL herr_t H5Glink2(hid_t src_loc, const char *cur_name, H5G_link_t type, diff --git a/test/titerate.c b/test/titerate.c index e8d0e3a..ee926ea 100644 --- a/test/titerate.c +++ b/test/titerate.c @@ -215,6 +215,31 @@ static void test_iter_group(void) CHECK(ret, FAIL, "H5Gclose"); } + /* These two functions, H5Gget_num_objs and H5Gget_objname_by_idx, actually + * iterate through B-tree for group members in internal library design. + * (Same as test above, but with the file ID instead of opening the root group) + */ + { + ret = H5Gget_num_objs(file, &num_membs); + CHECK(ret, FAIL, "H5Gget_num_objs"); + VERIFY(num_membs,NDATASETS+2,"H5Gget_num_objs"); + + for(i=0; i< (int)num_membs; i++) { + H5G_obj_t obj_type; /* Type of object in file */ + + ret = H5Gget_objname_by_idx(file, (hsize_t)i, dataset_name, 32); + CHECK(ret, FAIL, "H5Gget_objsname_by_idx"); + + obj_type = H5Gget_objtype_by_idx(file, (hsize_t)i); + CHECK(obj_type, H5G_UNKNOWN, "H5Gget_objsname_by_idx"); + } + + H5E_BEGIN_TRY { + ret = (herr_t)H5Gget_objname_by_idx(file, (hsize_t)(NDATASETS+3), dataset_name, 16); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Gget_objsname_by_idx"); + } + /* Test invalid indices for starting iteration */ info.command=RET_ZERO; idx=-1; -- cgit v0.12