From 1482d3e9cbc0796803e8cea47178b9878ef7a633 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 17 Nov 2006 10:48:41 -0500 Subject: [svn-r12932] Description: Basic support for H5Literate() routine. Still needs to be fleshed out and refactored to simplify. Also, needs tests. :-) Tested on: FreeBSD/32 4.11 (sleipnir) Linux/32 2.4 (heping) Linux/64 2.4 (mir) AIX/32 5.? (copper) Mac OS X/32 10.4.8 (amazon) --- src/H5Dpkg.h | 2 +- src/H5G.c | 19 ++++--- src/H5Gcompact.c | 70 ++++++++++++++----------- src/H5Gdense.c | 85 ++++++++++++++++++++++--------- src/H5Gent.c | 12 ++--- src/H5Glink.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/H5Gname.c | 13 +++-- src/H5Gnode.c | 55 +++++++++++++------- src/H5Gobj.c | 26 +++++----- src/H5Gpkg.h | 50 ++++++++++-------- src/H5Gstab.c | 21 ++++---- src/H5L.c | 147 ++++++++++++++++++++++++++--------------------------- src/H5Lexternal.c | 12 ++--- src/H5Lpublic.h | 15 ++++-- src/H5O.c | 2 +- src/H5Olinfo.c | 5 +- test/links.c | 20 ++++---- test/objcopy.c | 2 +- tools/h5ls/h5ls.c | 6 +-- tools/lib/h5diff.c | 18 +++---- 20 files changed, 473 insertions(+), 253 deletions(-) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 70c8c7a..71b944c 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -34,8 +34,8 @@ #include "H5Gprivate.h" /* Groups */ #include "H5Oprivate.h" /* Object headers */ #include "H5Sprivate.h" /* Dataspaces */ -#include "H5Tprivate.h" /* Datatype functions */ #include "H5SLprivate.h" /* Skip lists */ +#include "H5Tprivate.h" /* Datatypes */ /**************************/ /* Package Private Macros */ diff --git a/src/H5G.c b/src/H5G.c index 995498b..824c917 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -577,8 +577,9 @@ herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { - int last_obj; /* Index of last object looked at */ - int idx; /* Internal location to hold index */ + H5G_link_iterate_t lnk_op; /* Link operator */ + hsize_t last_obj; /* Index of last object looked at */ + hsize_t idx; /* Internal location to hold index */ herr_t ret_value; FUNC_ENTER_API(H5Giterate, FAIL) @@ -587,17 +588,21 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, /* Check args */ if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - idx = (idx_p == NULL ? 0 : *idx_p); - if(idx < 0) + if(idx_p && *idx_p < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified") if(!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") /* Set number of objects looked at to zero */ last_obj = 0; + idx = (hsize_t)(idx_p == NULL ? 0 : *idx_p); + + /* Build link operator info */ + lnk_op.op_type = H5G_LINK_OP_OLD; + lnk_op.u.old_op = op; /* Call private function. */ - if((ret_value = H5G_obj_iterate(loc_id, name, H5_ITER_INC, idx, &last_obj, op, op_data, H5AC_ind_dxpl_id)) < 0) + if((ret_value = H5G_obj_iterate(loc_id, name, H5L_INDEX_NAME, H5_ITER_INC, idx, &last_obj, &lnk_op, op_data, H5AC_ind_dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed") /* Check for too high of a starting index (ex post facto :-) */ @@ -607,7 +612,7 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, /* Set the index we stopped at */ if(idx_p) - *idx_p = last_obj; + *idx_p = (int)last_obj; done: FUNC_LEAVE_API(ret_value) @@ -1715,7 +1720,7 @@ H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, if(ret >=0 && linfo.type != H5L_TYPE_HARD) { - statbuf->linklen = linfo.u.link_size; + statbuf->linklen = linfo.u.val_size; if(linfo.type == H5L_TYPE_SOFT) statbuf->type = H5G_LINK; else /* UD link. H5L_get_info checked for invalid link classes */ diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c index b894224..cebae1e 100644 --- a/src/H5Gcompact.c +++ b/src/H5Gcompact.c @@ -29,7 +29,6 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ -#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ @@ -263,10 +262,8 @@ H5G_compact_get_name_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, done: /* Release link table */ - if(ltable.lnks) - /* Free link table information */ - if(H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + if(ltable.lnks && H5G_link_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_compact_get_name_by_idx() */ @@ -326,10 +323,8 @@ H5G_compact_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *l done: /* Release link table */ - if(ltable.lnks) - /* Free link table information */ - if(H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") + if(ltable.lnks && H5G_link_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_compact_get_type_by_idx() */ @@ -462,9 +457,8 @@ H5G_compact_remove_by_idx(const H5O_loc_t *oloc, hid_t dxpl_id, done: /* Release link table */ - if(ltable.lnks) - if(H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + if(ltable.lnks && H5G_link_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_compact_remove_by_idx() */ @@ -484,8 +478,8 @@ done: */ herr_t H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, - H5_iter_order_t order, hid_t gid, hbool_t lib_internal, int skip, - int *last_obj, H5G_link_iterate_t op, void *op_data) + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_obj, + hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data) { H5G_link_table_t ltable = {0, NULL}; /* Link table */ size_t u; /* Local index variable */ @@ -495,23 +489,42 @@ H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, /* Sanity check */ HDassert(oloc); - HDassert(lib_internal || H5I_GROUP == H5I_get_type(gid)); - HDassert(op.lib_op); + HDassert(linfo); + HDassert(lnk_op && lnk_op->u.lib_op); /* Build table of all link messages */ - if(H5G_compact_build_table(oloc, dxpl_id, linfo, H5L_INDEX_NAME, order, <able) < 0) + if(H5G_compact_build_table(oloc, dxpl_id, linfo, idx_type, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table") /* Iterate over link messages */ - for(u = 0, ret_value = H5B_ITER_CONT; u < ltable.nlinks && !ret_value; u++) { + for(u = 0, ret_value = H5O_ITER_CONT; u < ltable.nlinks && !ret_value; u++) { if(skip > 0) --skip; else { - /* Check for internal callback with link info */ - if(lib_internal) - ret_value = (op.lib_op)(&(ltable.lnks[u]), op_data); - else - ret_value = (op.app_op)(gid, ltable.lnks[u].name, op_data); + /* Check which kind of callback to make */ + switch(lnk_op->op_type) { + case H5G_LINK_OP_OLD: + /* Make the old-type application callback */ + ret_value = (lnk_op->u.old_op)(gid, ltable.lnks[u].name, op_data); + break; + + case H5G_LINK_OP_APP: + { + H5L_info_t info; /* Link info */ + + /* Retrieve the info for the link */ + if(H5G_link_to_info(&(ltable.lnks[u]), &info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B2_ITER_ERROR, "unable to get info for link") + + /* Make the application callback */ + ret_value = (lnk_op->u.app_op)(gid, ltable.lnks[u].name, &info, op_data); + } + break; + + case H5G_LINK_OP_LIB: + /* Call the library's callback */ + ret_value = (lnk_op->u.lib_op)(&(ltable.lnks[u]), op_data); + } /* end switch */ } /* end else */ /* Increment the number of entries passed through */ @@ -525,10 +538,8 @@ H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, done: /* Release link table */ - if(ltable.lnks) - /* Free link table information */ - if(H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + if(ltable.lnks && H5G_link_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_compact_iterate() */ @@ -667,9 +678,8 @@ H5G_compact_lookup_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *lin done: /* Release link table */ - if(ltable.lnks) - if(H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + if(ltable.lnks && H5G_link_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_compact_lookup_by_idx() */ diff --git a/src/H5Gdense.c b/src/H5Gdense.c index eb7a884..17a5d68 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -86,14 +86,13 @@ typedef struct { H5F_t *f; /* Pointer to file that fractal heap is in */ hid_t dxpl_id; /* DXPL for operation */ H5HF_t *fheap; /* Fractal heap handle */ - hbool_t lib_internal; /* Callback is library internal */ /* downward (from application) */ hid_t gid; /* Group ID for application callback */ - H5G_link_iterate_t op; /* Callback for each link */ + hsize_t skip; /* Number of links to skip */ + hsize_t *last_lnk; /* Pointer to the last link operated on */ + H5G_link_iterate_t *lnk_op; /* Callback for each link */ void *op_data; /* Callback data for each link */ - int skip; /* Number of links to skip */ - int *last_lnk; /* Pointer to the last link operated on */ /* upward */ int op_ret; /* Return value from callback */ @@ -821,10 +820,11 @@ H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.curr_lnk = 0; /* Build iterator operator */ - lnk_op.lib_op = H5G_dense_build_table_cb; + lnk_op.op_type = H5G_LINK_OP_LIB; + lnk_op.u.lib_op = H5G_dense_build_table_cb; /* Iterate over the links in the group, building a table of the link messages */ - if(H5G_dense_iterate(f, dxpl_id, H5_ITER_NATIVE, 0, linfo, TRUE, 0, NULL, lnk_op, &udata) < 0) + if(H5G_dense_iterate(f, dxpl_id, linfo, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") /* Sort link table in correct iteration order */ @@ -929,13 +929,30 @@ H5G_dense_iterate_bt2_cb(const void *_record, void *_bt2_udata) H5G_dense_iterate_fh_cb, &fh_udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPERATE, H5B2_ITER_ERROR, "link found callback failed") - /* Check for internal callback with link info */ - if(bt2_udata->lib_internal) - /* Call the library's callback */ - ret_value = (bt2_udata->op.lib_op)(fh_udata.lnk, bt2_udata->op_data); - else - /* Make the application's callback */ - ret_value = (bt2_udata->op.app_op)(bt2_udata->gid, fh_udata.lnk->name, bt2_udata->op_data); + /* Check which type of callback to make */ + switch(bt2_udata->lnk_op->op_type) { + case H5G_LINK_OP_OLD: + /* Make the old-type application callback */ + ret_value = (bt2_udata->lnk_op->u.old_op)(bt2_udata->gid, fh_udata.lnk->name, bt2_udata->op_data); + break; + + case H5G_LINK_OP_APP: + { + H5L_info_t info; /* Link info */ + + /* Retrieve the info for the link */ + if(H5G_link_to_info(fh_udata.lnk, &info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B2_ITER_ERROR, "unable to get info for link") + + /* Make the application callback */ + ret_value = (bt2_udata->lnk_op->u.app_op)(bt2_udata->gid, fh_udata.lnk->name, &info, bt2_udata->op_data); + } + break; + + case H5G_LINK_OP_LIB: + /* Call the library's callback */ + ret_value = (bt2_udata->lnk_op->u.lib_op)(fh_udata.lnk, bt2_udata->op_data); + } /* end switch */ /* Release the space allocated for the link */ H5O_free(H5O_LINK_ID, fh_udata.lnk); @@ -969,9 +986,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, - const H5O_linfo_t *linfo, hbool_t lib_internal, int skip, int *last_lnk, - H5G_link_iterate_t op, void *op_data) +H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, + hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data) { H5G_bt2_ud_it_t udata; /* User data for iterator callback */ H5HF_t *fheap = NULL; /* Fractal heap handle */ @@ -985,7 +1002,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, */ HDassert(f); HDassert(linfo); - HDassert(op.lib_op); + HDassert(lnk_op && lnk_op->u.lib_op); /* Open the fractal heap */ if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->link_fheap_addr))) @@ -998,11 +1015,10 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, udata.f = f; udata.dxpl_id = dxpl_id; udata.fheap = fheap; - udata.lib_internal = lib_internal; udata.gid = gid; udata.skip = skip; udata.last_lnk = last_lnk; - udata.op = op; + udata.lnk_op = lnk_op; udata.op_data = op_data; /* Iterate over the records in the v2 B-tree's "native" order */ @@ -1015,7 +1031,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, size_t u; /* Local index variable */ /* Build the table of links for this group */ - if(H5G_dense_build_table(f, dxpl_id, linfo, H5L_INDEX_NAME, order, <able) < 0) + if(H5G_dense_build_table(f, dxpl_id, linfo, idx_type, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "error building table of links") /* Iterate over link messages */ @@ -1023,11 +1039,30 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, if(skip > 0) --skip; else { - /* Check for internal callback with link info */ - if(lib_internal) - ret_value = (op.lib_op)(&(ltable.lnks[u]), op_data); - else - ret_value = (op.app_op)(gid, ltable.lnks[u].name, op_data); + /* Check which kind of callback to make */ + switch(lnk_op->op_type) { + case H5G_LINK_OP_OLD: + /* Make the old-type application callback */ + ret_value = (lnk_op->u.old_op)(gid, ltable.lnks[u].name, op_data); + break; + + case H5G_LINK_OP_APP: + { + H5L_info_t info; /* Link info */ + + /* Retrieve the info for the link */ + if(H5G_link_to_info(&(ltable.lnks[u]), &info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B2_ITER_ERROR, "unable to get info for link") + + /* Make the application callback */ + ret_value = (lnk_op->u.app_op)(gid, ltable.lnks[u].name, &info, op_data); + } + break; + + case H5G_LINK_OP_LIB: + /* Call the library's callback */ + ret_value = (lnk_op->u.lib_op)(&(ltable.lnks[u]), op_data); + } /* end switch */ } /* end else */ /* Increment the number of entries passed through */ diff --git a/src/H5Gent.c b/src/H5Gent.c index 412a2f6..e011a05 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -445,7 +445,7 @@ done: */ herr_t H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * stream, - int indent, int fwidth, haddr_t heap) + int indent, int fwidth, haddr_t heap_addr) { const char *lval = NULL; int nested_indent, nested_fwidth; @@ -492,15 +492,15 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str HDfprintf(stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, "Link value offset:", (unsigned long)(ent->cache.slink.lval_offset)); - if(heap > 0 && H5F_addr_defined(heap)) { - const H5HL_t *heap_ptr; + if(heap_addr > 0 && H5F_addr_defined(heap_addr)) { + H5HL_t *heap; - heap_ptr = H5HL_protect(ent->file, dxpl_id, heap); - lval = H5HL_offset_into(ent->file, heap_ptr, ent->cache.slink.lval_offset); + heap = H5HL_protect(ent->file, dxpl_id, heap_addr); + lval = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset); HDfprintf(stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth, "Link value:", lval); - H5HL_unprotect(ent->file, dxpl_id, heap_ptr, heap, H5AC__NO_FLAGS_SET); + H5HL_unprotect(ent->file, dxpl_id, heap, heap_addr, H5AC__NO_FLAGS_SET); } /* end if */ else HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!"); diff --git a/src/H5Glink.c b/src/H5Glink.c index 0bcf5b9..0a379d1 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -203,7 +203,7 @@ H5G_link_cmp_corder_dec(const void *lnk1, const void *lnk2) /*------------------------------------------------------------------------- - * Function: H5G_link_convert + * Function: H5G_ent_to_link * * Purpose: Convert a symbol table entry to a link * @@ -216,12 +216,12 @@ H5G_link_cmp_corder_dec(const void *lnk1, const void *lnk2) *------------------------------------------------------------------------- */ herr_t -H5G_link_convert(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, +H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, const H5G_entry_t *ent, const char *name) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_link_convert, FAIL) + FUNC_ENTER_NOAPI(H5G_ent_to_link, FAIL) /* check arguments */ HDassert(f); @@ -265,7 +265,145 @@ H5G_link_convert(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link_convert() */ +} /* end H5G_ent_to_link() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_ent_to_info + * + * Purpose: Make link info for a symbol table entry + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 16 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, haddr_t lheap_addr, + const H5G_entry_t *ent) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_ent_to_info, FAIL) + + /* check arguments */ + HDassert(f); + HDassert(info); + HDassert(ent); + + /* Set (default) common info for info */ + info->cset = H5F_DEFAULT_CSET; + info->corder = 0; + info->corder_valid = FALSE; /* Creation order not valid for this link */ + + /* Object is a symbolic or hard link */ + if(ent->type == H5G_CACHED_SLINK) { + const char *s; /* Pointer to link value */ + H5HL_t *heap; /* Pointer to local heap for group */ + + /* Lock the local heap */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, lheap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect local heap") + + s = H5HL_offset_into(f, heap, ent->cache.slink.lval_offset); + + /* Get the link value size */ + info->u.val_size = HDstrlen(s) + 1; + + /* Release the local heap */ + if(H5HL_unprotect(f, dxpl_id, heap, lheap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to unprotect local heap") + + /* Set link type */ + info->type = H5L_TYPE_SOFT; + } /* end if */ + else { + /* Set address of object */ + info->u.address = ent->header; + + /* Set link type */ + info->type = H5L_TYPE_HARD; + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_ent_to_link() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_link_to_info + * + * Purpose: Retrieve information from a link object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, November 7 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_link_to_info, FAIL) + + /* Sanity check */ + HDassert(lnk); + + /* Get information from the link */ + if(info) { + info->cset = lnk->cset; + info->corder = lnk->corder; + info->corder_valid = lnk->corder_valid; + info->type = lnk->type; + + switch(lnk->type) { + case H5L_TYPE_HARD: + info->u.address = lnk->u.hard.addr; + break; + + case H5L_TYPE_SOFT: + info->u.val_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ + break; + + default: + { + const H5L_class_t *link_class; /* User-defined link class */ + + if(lnk->type < H5L_TYPE_UD_MIN || lnk->type > H5L_TYPE_MAX) + HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unknown link class") + + /* User-defined link; call its query function to get the link udata size. */ + /* Get the link class for this type of link. It's okay if the class + * isn't registered, though--we just can't give any more information + * about it + */ + link_class = H5L_find_class(lnk->type); + + if(link_class != NULL && link_class->query_func != NULL) { + ssize_t cb_ret; /* Return value from UD callback */ + + /* Call the link's query routine to retrieve the user-defined link's value size */ + /* (in case the query routine packs/unpacks the link value in some way that changes its size) */ + if((cb_ret = (link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, NULL, (size_t)0)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure") + + info->u.val_size = cb_ret; + } /* end if */ + else + info->u.val_size = 0; + } /* end case */ + } /* end switch */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_link_to_info() */ /*------------------------------------------------------------------------- diff --git a/src/H5Gname.c b/src/H5Gname.c index 9200241..56df3d6 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -1060,7 +1060,7 @@ H5G_refname_iterator(hid_t group, const char *name, void *_udata) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") /* Get information for object in group */ - if(H5G_get_objinfo(&loc, name, 0, &sb, udata->dxpl_id) < 0) + if(H5G_get_objinfo(&loc, name, FALSE, &sb, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object") #if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG objno = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long))); @@ -1111,8 +1111,9 @@ H5G_refname_iterator(hid_t group, const char *name, void *_udata) /* If it's a group, we recurse into it */ if(sb.type == H5G_GROUP) { - int last_obj; - size_t len_needed; /* Length of container string needed */ + H5G_link_iterate_t lnk_op; /* Link operator */ + hsize_t last_obj; + size_t len_needed; /* Length of container string needed */ size_t len; /* Build full path name of group to recurse into */ @@ -1129,7 +1130,11 @@ H5G_refname_iterator(hid_t group, const char *name, void *_udata) udata->is_root_group = FALSE; HDstrcat(udata->container, "/"); - ret_value = H5G_obj_iterate(udata->file, udata->container, H5_ITER_INC, 0, &last_obj, H5G_refname_iterator, udata, udata->dxpl_id); + /* Build iterator operator */ + lnk_op.op_type = H5G_LINK_OP_OLD; + lnk_op.u.old_op = H5G_refname_iterator; + + ret_value = H5G_obj_iterate(udata->file, udata->container, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->dxpl_id); /* If we didn't find the object, truncate the name to not include group name anymore */ if(!ret_value) diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 5eb3660..f05fb90 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1483,24 +1483,43 @@ H5G_node_iterate(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t ad HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name") heap = NULL; name = NULL; - /* Check for internal callback with link info */ - if(udata->lib_internal) { - H5O_link_t lnk; /* Link for entry */ - - /* Convert the entry to a link */ - if(H5G_link_convert(f, dxpl_id, &lnk, udata->heap_addr, &ents[u], s) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_ITER_ERROR, "unable to convert symbol table entry to link") - - /* Call the library's callback */ - ret_value = (udata->op.lib_op)(&lnk, udata->op_data); - - /* Release memory for link object */ - if(H5O_reset(H5O_LINK_ID, &lnk) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, H5B_ITER_ERROR, "unable to release link message") - } /* end if */ - else - /* Make the application's callback */ - ret_value = (udata->op.app_op)(udata->group_id, s, udata->op_data); + /* Check which type of callback to make */ + switch(udata->lnk_op->op_type) { + case H5G_LINK_OP_OLD: + /* Make the old-type application callback */ + ret_value = (udata->lnk_op->u.old_op)(udata->group_id, s, udata->op_data); + break; + + case H5G_LINK_OP_APP: + { + H5L_info_t info; /* Link info for entry */ + + /* Make a link info for an entry */ + if(H5G_ent_to_info(f, dxpl_id, &info, udata->heap_addr, &ents[u]) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_ITER_ERROR, "unable to get info for symbol table entry") + + /* Make the application callback */ + ret_value = (udata->lnk_op->u.app_op)(udata->group_id, s, &info, udata->op_data); + } /* end if */ + break; + + case H5G_LINK_OP_LIB: + /* Call the library's callback */ + { + H5O_link_t lnk; /* Link for entry */ + + /* Convert the entry to a link */ + if(H5G_ent_to_link(f, dxpl_id, &lnk, udata->heap_addr, &ents[u], s) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_ITER_ERROR, "unable to convert symbol table entry to link") + + /* Call the library's callback */ + ret_value = (udata->lnk_op->u.lib_op)(&lnk, udata->op_data); + + /* Release memory for link object */ + if(H5O_reset(H5O_LINK_ID, &lnk) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, H5B_ITER_ERROR, "unable to release link message") + } /* end if */ + } /* end switch */ /* Free the memory for the name, if we used a dynamically allocated buffer */ if(s != buf) diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 3e0310c..11b9f3d 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -494,10 +494,11 @@ H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, udata.dxpl_id = dxpl_id; /* Build iterator operator */ - lnk_op.lib_op = H5G_obj_stab_to_new_cb; + lnk_op.op_type = H5G_LINK_OP_LIB; + lnk_op.u.lib_op = H5G_obj_stab_to_new_cb; /* Iterate through all links in "old format" group and insert them into new format */ - if(H5G_stab_iterate(grp_oloc, H5_ITER_NATIVE, 0, TRUE, 0, NULL, lnk_op, &udata, dxpl_id) < 0) + if(H5G_stab_iterate(grp_oloc, dxpl_id, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over old format links") /* Remove the symbol table message from the group */ @@ -579,11 +580,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_obj_iterate(hid_t loc_id, const char *name, H5_iter_order_t order, - int skip, int *last_lnk, H5G_iterate_t op, void *op_data, hid_t dxpl_id) +H5G_obj_iterate(hid_t loc_id, const char *group_name, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, + H5G_link_iterate_t *lnk_op, void *op_data, hid_t dxpl_id) { H5O_linfo_t linfo; /* Link info message */ - H5G_link_iterate_t lnk_op; /* Link operator */ hid_t gid = -1; /* ID of group to iterate over */ H5G_t *grp; /* Pointer to group data structure to iterate over */ herr_t ret_value; /* Return value */ @@ -591,22 +592,19 @@ H5G_obj_iterate(hid_t loc_id, const char *name, H5_iter_order_t order, FUNC_ENTER_NOAPI(H5G_obj_iterate, FAIL) /* Sanity check */ - HDassert(name); + HDassert(group_name); HDassert(last_lnk); - HDassert(op); + HDassert(lnk_op && lnk_op->u.lib_op); /* * Open the group on which to operate. We also create a group ID which * we can pass to the application-defined operator. */ - if((gid = H5Gopen(loc_id, name)) < 0) + if((gid = H5Gopen(loc_id, group_name)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") if((grp = H5I_object(gid)) == NULL) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "bad group ID") - /* Set up link operator */ - lnk_op.app_op = op; - /* Attempt to get the link info for this group */ if(H5O_read(&(grp->oloc), H5O_LINFO_ID, 0, &linfo, dxpl_id)) { /* Check for going out of bounds */ @@ -615,12 +613,12 @@ H5G_obj_iterate(hid_t loc_id, const char *name, H5_iter_order_t order, if(H5F_addr_defined(linfo.link_fheap_addr)) { /* Iterate over the links in the group, building a table of the link messages */ - if((ret_value = H5G_dense_iterate(grp->oloc.file, dxpl_id, order, gid, &linfo, FALSE, skip, last_lnk, lnk_op, op_data)) < 0) + if((ret_value = H5G_dense_iterate(grp->oloc.file, dxpl_id, &linfo, idx_type, order, skip, last_lnk, gid, lnk_op, op_data)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") } /* end if */ else { /* Get the object's name from the link messages */ - if((ret_value = H5G_compact_iterate(&(grp->oloc), dxpl_id, &linfo, order, gid, FALSE, skip, last_lnk, lnk_op, op_data)) < 0) + if((ret_value = H5G_compact_iterate(&(grp->oloc), dxpl_id, &linfo, idx_type, order, skip, last_lnk, gid, lnk_op, op_data)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over links") } /* end else */ } /* end if */ @@ -629,7 +627,7 @@ H5G_obj_iterate(hid_t loc_id, const char *name, H5_iter_order_t order, H5E_clear_stack(NULL); /* Iterate over symbol table */ - if((ret_value = H5G_stab_iterate(&(grp->oloc), order, gid, FALSE, skip, last_lnk, lnk_op, op_data, dxpl_id)) < 0) + if((ret_value = H5G_stab_iterate(&(grp->oloc), dxpl_id, order, skip, last_lnk, gid, lnk_op, op_data)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over symbol table") } /* end else */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 9faf46d..0d57137 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -128,10 +128,18 @@ struct H5G_t { /* Link iteration operator for internal library callbacks */ typedef herr_t (*H5G_lib_iterate_t)(const H5O_link_t *lnk, void *op_data); -/* Some syntactic sugar to make the compiler happy with two different kinds of iterator callbacks */ -typedef union { - H5G_iterate_t app_op; /* Application callback for each link */ - H5G_lib_iterate_t lib_op; /* Library internal callback for each link */ +/* Describe kind of callback to make for each link */ +typedef struct { + enum { + H5G_LINK_OP_OLD, /* Old application callback */ + H5G_LINK_OP_APP, /* Application callback */ + H5G_LINK_OP_LIB /* Library internal callback */ + } op_type; + union { + H5G_iterate_t old_op; /* Old application callback for each link */ + H5L_iterate_t app_op; /* Application callback for each link */ + H5G_lib_iterate_t lib_op; /* Library internal callback for each link */ + } u; } H5G_link_iterate_t; /* @@ -201,13 +209,12 @@ typedef struct H5G_bt_it_ud1_t { /* downward */ hid_t group_id; /*group id to pass to iteration operator */ haddr_t heap_addr; /*symbol table heap address */ - H5G_link_iterate_t op; /*iteration operator */ + hsize_t skip; /*initial entries to skip */ + H5G_link_iterate_t *lnk_op; /*iteration operator */ void *op_data; /*user-defined operator data */ - int skip; /*initial entries to skip */ - hbool_t lib_internal; /* Callback is library internal */ /* upward */ - int *final_ent; /*final entry looked at */ + hsize_t *final_ent; /*final entry looked at */ } H5G_bt_it_ud1_t; /* Data passed through B-tree iteration for copying copy symbol table content */ @@ -369,9 +376,9 @@ H5_DLL herr_t H5G_stab_insert(H5O_loc_t *grp_oloc, const char *name, H5_DLL herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, H5O_link_t *obj_lnk, hid_t dxpl_id); H5_DLL herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, hbool_t adj_link); -H5_DLL herr_t H5G_stab_iterate(H5O_loc_t *oloc, H5_iter_order_t order, - hid_t gid, hbool_t lib_internal, int skip, int *last_obj, - H5G_link_iterate_t op, void *op_data, hid_t dxpl_id); +H5_DLL herr_t H5G_stab_iterate(H5O_loc_t *oloc, hid_t dxpl_id, + H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, hid_t gid, + H5G_link_iterate_t *lnk_op, void *op_data); H5_DLL herr_t H5G_stab_count(struct H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id); H5_DLL ssize_t H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id); @@ -417,8 +424,11 @@ H5_DLL int H5G_link_cmp_name_inc(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_name_dec(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_corder_inc(const void *lnk1, const void *lnk2); H5_DLL int H5G_link_cmp_corder_dec(const void *lnk1, const void *lnk2); -H5_DLL herr_t H5G_link_convert(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, +H5_DLL herr_t H5G_ent_to_link(H5F_t *f, hid_t dxpl_id, H5O_link_t *lnk, haddr_t lheap_addr, const H5G_entry_t *ent, const char *name); +H5_DLL herr_t H5G_ent_to_info(H5F_t *f, hid_t dxpl_id, H5L_info_t *info, + haddr_t lheap_addr, const H5G_entry_t *ent); +H5_DLL herr_t H5G_link_to_info(const H5O_link_t *lnk, H5L_info_t *linfo); H5_DLL herr_t H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); @@ -441,8 +451,8 @@ H5_DLL herr_t H5G_compact_remove_by_idx(const H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n); H5_DLL herr_t H5G_compact_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, - H5_iter_order_t order, hid_t gid, hbool_t lib_internal, int skip, - int *last_obj, H5G_link_iterate_t op, void *op_data); + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_obj, + hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data); H5_DLL herr_t H5G_compact_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id); H5_DLL herr_t H5G_compact_lookup_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, @@ -460,9 +470,9 @@ H5_DLL herr_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, H5_DLL herr_t H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); -H5_DLL herr_t H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, - hid_t gid, const H5O_linfo_t *linfo, hbool_t lib_internal, int skip, - int *last_lnk, H5G_link_iterate_t op, void *op_data); +H5_DLL herr_t H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, + hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data); H5_DLL ssize_t H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name, size_t size); @@ -481,9 +491,9 @@ H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, const H5O_linfo_t *linfo, H5O_loc_t *oloc/*out*/); H5_DLL herr_t H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id); -H5_DLL herr_t H5G_obj_iterate(hid_t loc_id, const char *name, - H5_iter_order_t order, int skip, int *last_obj, H5G_iterate_t op, - void *op_data, hid_t dxpl_id); +H5_DLL herr_t H5G_obj_iterate(hid_t loc_id, const char *group_name, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_obj, + H5G_link_iterate_t *lnk_op, void *op_data, hid_t dxpl_id); H5_DLL herr_t H5G_obj_count(struct H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id); H5_DLL ssize_t H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5L_index_t idx_type, diff --git a/src/H5Gstab.c b/src/H5Gstab.c index f87294b..a4939f1 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -26,7 +26,6 @@ #include "H5Fpkg.h" /* File access */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ -#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ @@ -436,9 +435,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_stab_iterate(H5O_loc_t *oloc, H5_iter_order_t order, hid_t gid, - hbool_t lib_internal, int skip, int *last_lnk, H5G_link_iterate_t op, - void *op_data, hid_t dxpl_id) +H5G_stab_iterate(H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, + hsize_t skip, hsize_t *last_lnk, hid_t gid, + H5G_link_iterate_t *lnk_op, void *op_data) { H5G_bt_it_ud1_t udata; /* User data to pass to B-tree callback */ H5O_stab_t stab; /* Info about symbol table */ @@ -448,8 +447,7 @@ H5G_stab_iterate(H5O_loc_t *oloc, H5_iter_order_t order, hid_t gid, /* Sanity check */ HDassert(oloc); - HDassert(lib_internal || H5I_GROUP == H5I_get_type(gid)); - HDassert(op.lib_op); + HDassert(lnk_op && lnk_op->u.old_op); /* Get the B-tree info */ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) @@ -460,12 +458,11 @@ H5G_stab_iterate(H5O_loc_t *oloc, H5_iter_order_t order, hid_t gid, if(order != H5_ITER_DEC) { /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ udata.group_id = gid; - udata.skip = skip; udata.heap_addr = stab.heap_addr; - udata.lib_internal = lib_internal; - udata.op = op; - udata.op_data = op_data; + udata.skip = skip; udata.final_ent = last_lnk; + udata.lnk_op = lnk_op; + udata.op_data = op_data; /* Iterate over the group members */ if((ret_value = H5B_iterate(oloc->file, H5AC_dxpl_id, H5B_SNODE, @@ -775,7 +772,7 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) /* Set link info */ if(udata->lnk) { /* Convert the entry to a link */ - if(H5G_link_convert(udata->file, udata->dxpl_id, udata->lnk, udata->heap_addr, + if(H5G_ent_to_link(udata->file, udata->dxpl_id, udata->lnk, udata->heap_addr, ent, udata->name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") } /* end if */ @@ -901,7 +898,7 @@ H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) heap = NULL; name = NULL; /* Convert the entry to a link */ - if(H5G_link_convert(udata->common.f, udata->common.dxpl_id, udata->lnk, udata->heap_addr, ent, s) < 0) + if(H5G_ent_to_link(udata->common.f, udata->common.dxpl_id, udata->lnk, udata->heap_addr, ent, s) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") udata->found = TRUE; diff --git a/src/H5L.c b/src/H5L.c index f5281ee..b09ab92 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -175,7 +175,6 @@ static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); -static herr_t H5L_get_info_real(const H5O_link_t *lnk, H5L_info_t *linfo); static herr_t H5L_get_info_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); @@ -1090,6 +1089,77 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_name_by_idx() */ + +/*------------------------------------------------------------------------- + * Function: H5Literate + * + * Purpose: Iterates over links in a group, with user callback routine, + * according to the order within an index. + * + * Same pattern of behavior as H5Giterate. + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * + * Programmer: Quincey Koziol + * Thursday, November 16, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Literate(hid_t loc_id, const char *group_name, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, + H5L_iterate_t op, void *op_data, hid_t lapl_id) +{ + H5G_link_iterate_t lnk_op; /* Link operator */ + hsize_t last_lnk; /* Index of last object looked at */ + hsize_t idx; /* Internal location to hold index */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Literate, FAIL) + + /* Check arguments */ + if(!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(idx_type <= H5L_INDEX_UNKNOWN || idx_type >= H5L_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") + + /* Set up iteration beginning/end info */ + idx = (idx_p == NULL ? 0 : *idx_p); + last_lnk = 0; + + /* Build link operator info */ + lnk_op.op_type = H5G_LINK_OP_APP; + lnk_op.u.app_op = op; + + /* Iterate over the links */ + if((ret_value = H5G_obj_iterate(loc_id, group_name, idx_type, order, idx, &last_lnk, &lnk_op, op_data, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") + + + /* Set the index we stopped at */ + if(idx_p) + *idx_p = last_lnk; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Literate() */ + /* *------------------------------------------------------------------------- *------------------------------------------------------------------------- @@ -2442,77 +2512,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5L_get_info_real - * - * Purpose: Retrieve information from a link object - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, November 7 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5L_get_info_real(const H5O_link_t *lnk, H5L_info_t *linfo) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5L_get_info_real) - - /* Sanity check */ - HDassert(lnk); - - /* Get information from the link */ - if(linfo) { - linfo->cset = lnk->cset; - linfo->corder = lnk->corder; - linfo->corder_valid = lnk->corder_valid; - linfo->type = lnk->type; - - switch(lnk->type) { - case H5L_TYPE_HARD: - linfo->u.address = lnk->u.hard.addr; - break; - - case H5L_TYPE_SOFT: - linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ - break; - - default: - { - const H5L_class_t *link_class; /* User-defined link class */ - - if(lnk->type < H5L_TYPE_UD_MIN || lnk->type > H5L_TYPE_MAX) - HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unknown link class") - - /* User-defined link; call its query function to get the link udata size. */ - /* Get the link class for this type of link. It's okay if the class - * isn't registered, though--we just can't give any more information - * about it - */ - link_class = H5L_find_class(lnk->type); - - if(link_class != NULL && link_class->query_func != NULL) { - ssize_t cb_ret; /* Return value from UD callback */ - - if((cb_ret = (link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, NULL, (size_t)0)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure") - - linfo->u.link_size = cb_ret; - } /* end if */ - else - linfo->u.link_size = 0; - } /* end case */ - } /* end switch */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_info_real() */ - - -/*------------------------------------------------------------------------- * Function: H5L_get_info_cb * * Purpose: Callback for retrieving a link's metadata @@ -2539,7 +2538,7 @@ H5L_get_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Get information from the link */ - if(H5L_get_info_real(lnk, udata->linfo) < 0) + if(H5G_link_to_info(lnk, udata->linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info") done: @@ -2620,7 +2619,7 @@ H5L_get_info_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, lnk_copied = TRUE; /* Get information from the link */ - if(H5L_get_info_real(&grp_lnk, udata->linfo) < 0) + if(H5G_link_to_info(&grp_lnk, udata->linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info") done: diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index c29889a..6594e32 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -182,21 +182,17 @@ static ssize_t H5L_extern_query(const char UNUSED * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size) { - size_t ret_value; - - /* If the buffer is NULL, skip writng anything in it and just return + /* If the buffer is NULL, skip writing anything in it and just return * the size needed */ if(buf) { if(udata_size < buf_size) buf_size = udata_size; - /* Copy the udata verbatim up to udata_size*/ - HDmemcpy(buf, udata, udata_size); + /* Copy the udata verbatim up to buf_size*/ + HDmemcpy(buf, udata, buf_size); } - ret_value = udata_size; - - return ret_value; + return udata_size; } diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index f003173..03ec81e 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -73,13 +73,13 @@ typedef enum { /* Buffer for user query function */ typedef struct { - H5T_cset_t cset; /* Character set of link name */ - int64_t corder; /* Creation order */ - hbool_t corder_valid; /* Indicate if creation order is valid */ H5L_type_t type; /* Type of link */ + hbool_t corder_valid; /* Indicate if creation order is valid */ + int64_t corder; /* Creation order */ + H5T_cset_t cset; /* Character set of link name */ union { haddr_t address; /* Address hard link points to */ - size_t link_size; /* Size of a soft link or UD link */ + size_t val_size; /* Size of a soft link or UD link value */ } u; } H5L_info_t; @@ -131,6 +131,10 @@ typedef enum H5L_index_t { H5L_INDEX_N /* Number of indices defined on links in groups */ } H5L_index_t; +/* Prototype for H5Literate() operator */ +typedef herr_t (*H5L_iterate_t)(hid_t group, const char *name, const H5L_info_t *info, + void *op_data); + /********************/ /* Public Variables */ @@ -167,6 +171,9 @@ H5_DLL herr_t H5Lget_info_by_idx(hid_t loc_id, const char *group_name, H5_DLL ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id); +H5_DLL herr_t H5Literate(hid_t loc_id, const char *group_name, + H5L_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate_t op, void *op_data, hid_t lapl_id); /* UD link functions */ H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, diff --git a/src/H5O.c b/src/H5O.c index 7cfa094..bb4b917 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -42,8 +42,8 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ -#include "H5Tprivate.h" #include "H5SMprivate.h" /* Shared object header messages */ +#include "H5Tprivate.h" /* Datatypes */ #ifdef H5_HAVE_GETTIMEOFDAY #include diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 668ea30..bedbcd1 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -524,10 +524,11 @@ H5O_linfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, udata.cpy_info = cpy_info; /* Build iterator operator */ - lnk_op.lib_op = H5O_linfo_post_copy_file_cb; + lnk_op.op_type = H5G_LINK_OP_LIB; + lnk_op.u.lib_op = H5O_linfo_post_copy_file_cb; /* Iterate over the links in the group, building a table of the link messages */ - if(H5G_dense_iterate(src_oloc->file, dxpl_id, H5_ITER_NATIVE, 0, linfo_src, TRUE, 0, NULL, lnk_op, &udata) < 0) + if(H5G_dense_iterate(src_oloc->file, dxpl_id, linfo_src, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, (hid_t)0, &lnk_op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") } /* end if */ diff --git a/test/links.c b/test/links.c index 52b70b3..277146f 100644 --- a/test/links.c +++ b/test/links.c @@ -2592,7 +2592,7 @@ external_link_query(hid_t fapl, hbool_t new_format) /* Get size of buffer for external link */ if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR + if(li.u.val_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR if (H5L_TYPE_EXTERNAL != li.type) { H5_FAILED(); puts(" Unexpected link class - should have been an external link"); @@ -2618,7 +2618,7 @@ external_link_query(hid_t fapl, hbool_t new_format) /* Get size of buffer for external link */ if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR + if(li.u.val_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR if (H5L_TYPE_EXTERNAL != li.type) { H5_FAILED(); puts(" Unexpected link class - should have been an external link"); @@ -2629,7 +2629,7 @@ external_link_query(hid_t fapl, hbool_t new_format) if(H5Lget_val(fid, "src", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR /* Extract the file and object names from the buffer */ - if(H5Lunpack_elink_val(query_buf, li.u.link_size, &file_name, &object_name) < 0) TEST_ERROR + if(H5Lunpack_elink_val(query_buf, li.u.val_size, &file_name, &object_name) < 0) TEST_ERROR /* Compare the file and object names */ if(strcmp(file_name, filename2)) TEST_ERROR @@ -2647,11 +2647,11 @@ external_link_query(hid_t fapl, hbool_t new_format) if(H5Fclose(fid) < 0) TEST_ERROR /* Make sure that passing in NULLs to H5Lunpack_elink_val works */ - if(H5Lunpack_elink_val(query_buf, li.u.link_size, NULL, NULL) < 0) TEST_ERROR + if(H5Lunpack_elink_val(query_buf, li.u.val_size, NULL, NULL) < 0) TEST_ERROR /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */ H5E_BEGIN_TRY { - if(H5Lunpack_elink_val(query_buf, li.u.link_size - 1, NULL, NULL) >= 0) TEST_ERROR + if(H5Lunpack_elink_val(query_buf, li.u.val_size - 1, NULL, NULL) >= 0) TEST_ERROR } H5E_END_TRY H5E_BEGIN_TRY { if(H5Lunpack_elink_val(query_buf, 0, NULL, NULL) >= 0) TEST_ERROR @@ -3841,7 +3841,7 @@ ud_hard_links(hid_t fapl) /* Check that H5Lget_objinfo works on the hard link */ if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR /* UD hard links have no query function, thus return a "link length" of 0 */ - if(li.u.link_size != 0) TEST_ERROR + if(li.u.val_size != 0) TEST_ERROR if(UD_HARD_TYPE != li.type) { H5_FAILED(); puts(" Unexpected link class - should have been a UD hard link"); @@ -4252,7 +4252,7 @@ ud_callbacks(hid_t fapl, hbool_t new_format) /* Query the link to test its query callback */ if (H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != 16) TEST_ERROR + if(li.u.val_size != 16) TEST_ERROR if (UD_CB_TYPE != li.type) { H5_FAILED(); puts(" Unexpected link class - should have been a UD hard link"); @@ -4301,7 +4301,7 @@ ud_callbacks(hid_t fapl, hbool_t new_format) /* The query callback should NOT fail, but should be unable to give a linklen */ if(H5Lget_info(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != 0) TEST_ERROR + if(li.u.val_size != 0) TEST_ERROR if(li.type != UD_CB_TYPE) TEST_ERROR if(H5Gget_objinfo(fid, UD_CB_LINK_NAME, FALSE, &sb) < 0) TEST_ERROR if(sb.type != H5G_UDLINK) TEST_ERROR @@ -4742,7 +4742,7 @@ ud_link_errors(hid_t fapl, hbool_t new_format) /* The query callback will succeed when we only want to get the size of the buffer... */ if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != 0) TEST_ERROR + if(li.u.val_size != 0) TEST_ERROR /* ...but fail when we try to write data to the buffer itself*/ H5E_BEGIN_TRY { if(H5Lget_val(fid, "ud_link", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) >=0) TEST_ERROR @@ -4753,7 +4753,7 @@ ud_link_errors(hid_t fapl, hbool_t new_format) /* Now querying should succeed */ if(H5Lget_info(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR - if(li.u.link_size != 8) TEST_ERROR + if(li.u.val_size != 8) TEST_ERROR if(H5Lget_val(fid, "ud_link", query_buf, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR diff --git a/test/objcopy.c b/test/objcopy.c index 3373bec..54d03d4 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -1246,7 +1246,7 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) /* Check that both links are the same type and the same size */ if(linfo.type != linfo2.type) TEST_ERROR - if(linfo.u.link_size != linfo2.u.link_size) TEST_ERROR + if(linfo.u.val_size != linfo2.u.val_size) TEST_ERROR /* Get link udata */ if(H5Lget_val(gid, objname, linkval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index d23f410..f8c0cad 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -1766,12 +1766,12 @@ udlink_open(hid_t location, const char *name) { /* For external links, try to display info for the object it points to */ case H5L_TYPE_EXTERNAL: - if((buf = HDmalloc(linfo.u.link_size)) == NULL) + if((buf = HDmalloc(linfo.u.val_size)) == NULL) goto error; - if(H5Lget_val(location, name, buf, sizeof(buf), H5P_DEFAULT) < 0) + if(H5Lget_val(location, name, buf, linfo.u.val_size, H5P_DEFAULT) < 0) goto error; - if(H5Lunpack_elink_val(buf, linfo.u.link_size, &filename, &path) < 0) goto error; + if(H5Lunpack_elink_val(buf, linfo.u.val_size, &filename, &path) < 0) goto error; HDfputs("file: ", stdout); HDfputs(filename, stdout); HDfputs(" path: ", stdout); diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index bc0f7cc..209406d 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -1087,34 +1087,34 @@ hsize_t diff (hid_t file1_id, /* Only external links will have a query function registered */ if(li1.type == H5L_TYPE_EXTERNAL && li2.type == H5L_TYPE_EXTERNAL) { - buf1 = HDmalloc (li1.u.link_size); - buf2 = HDmalloc (li2.u.link_size); + buf1 = HDmalloc (li1.u.val_size); + buf2 = HDmalloc (li2.u.val_size); - if(H5Lget_val(file1_id, path1, buf1, li1.u.link_size, H5P_DEFAULT) < 0) + if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0) { HDfree (buf1); HDfree (buf2); goto out; } - if(H5Lget_val(file2_id, path2, buf2, li2.u.link_size, H5P_DEFAULT) < 0) + if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0) { HDfree (buf1); HDfree (buf2); goto out; } /* If the buffers are the same size, compare them */ - if(li1.u.link_size == li2.u.link_size) + if(li1.u.val_size == li2.u.val_size) { - if(H5Lget_val(file1_id, path1, buf1, li1.u.link_size, H5P_DEFAULT) < 0) + if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0) { HDfree (buf1); HDfree (buf2); goto out; } - if(H5Lget_val(file2_id, path2, buf2, li2.u.link_size, H5P_DEFAULT) < 0) + if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0) { HDfree (buf1); HDfree (buf2); goto out; } - ret = HDmemcmp (buf1, buf2, li1.u.link_size); + ret = HDmemcmp (buf1, buf2, li1.u.val_size); } else ret = 1; @@ -1134,7 +1134,7 @@ hsize_t diff (hid_t file1_id, /* If the link classes or the buffer length are not the * same, the links are "different" */ - if((li1.type != li2.type) || (li1.u.link_size != li2.u.link_size)) + if((li1.type != li2.type) || (li1.u.val_size != li2.u.val_size)) nfound = 1; else nfound = 0; -- cgit v0.12