From 2355d25955756f689f68bc6d8681116e2a41a5a6 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 12 Nov 2006 06:56:10 -0500 Subject: [svn-r12894] Description: Add H5Lget_name_by_idx routine & tests Move more H5G routines to deprecated API file Tested on: FreeBSD/32 4.11 (sleipnir) w/threadsafe Linux/32 2.4 (heping) C++ & FORTRAN Linux/64 2.4 (mir) w/build-all & enable_compat1.6 AIX/32 5.? (copper) w/parallel & FORTRAN --- release_docs/RELEASE.txt | 29 +++-- src/H5G.c | 273 +++++--------------------------------------- src/H5Gdense.c | 288 ++++++++++++++++++++--------------------------- src/H5Gdeprec.c | 281 ++++++++++++++++++++++++++++++++++++++++++++- src/H5Glink.c | 31 +++-- src/H5Gobj.c | 32 ++++-- src/H5Gpkg.h | 15 ++- src/H5Gpublic.h | 9 +- src/H5Gstab.c | 22 +++- src/H5L.c | 158 +++++++++++++++++++++++++- src/H5Lpublic.h | 3 + src/H5private.h | 4 +- test/links.c | 204 +++++++++++++++++++++------------ 13 files changed, 804 insertions(+), 545 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 3575d3b..982d83f 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -63,21 +63,6 @@ New Features - Remove the flexible parallel code and the --enable-fphdf5 configure option, it was never up to production standards anyway. -QAK 2006/4/20 - - Added a --enable-group-revision option to configure, to enable - segregating the ongoing work on changing the file format. - - .-"""""-. - / \ - .-. | _ _ | .-. - (_. '._ | |_\ /_| | _.' ._) - '-._'-.(_ A _).-'_.-' - '-._| _____ |_.-' - jgs _.-'_\`"""""`/_'-._ - .-.-'_.-' `-----' '-._'-.-. - (,_.'` `'._,) - - DO NOT ENABLE THIS OPTION! It is strictly for internal library - development! -QAK 2006/4/14 - Added a macro hdf5_mpi_special_collective_io_works to filter out some mpi-io packages that don't support collective IO for no IO contributions in some processes. -KY 2006/2/16 @@ -175,6 +160,20 @@ New Features Library: -------- + - Added new H5Lget_name_by_idx() routine to query the name of a link + according to the order within an index. + - QAK - 2006/11/12 + - Added new H5Rget_name() routine to determine the name of the object + that a reference points to, as long as the object is still + reachable in the group hierarchy. + - QAK - 2006/11/10 + - Added new H5Lget_info_by_idx() routine to query the link information + according to the order within an index. + - QAK - 2006/11/10 + - Added feature to H5Iget_name to allow retrieving the name of any + object's ID, as long as the object is still reachable in the + group hierarchy. + - LA - 2006/11/01 - Added External and User-defined links. External links are links from one HDF5 file to another; they require both the name of the file and a path within that file. diff --git a/src/H5G.c b/src/H5G.c index bd20833..995498b 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -138,10 +138,6 @@ static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id); static herr_t H5G_get_objinfo_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 H5G_set_comment(H5G_loc_t *loc, const char *name, - const char *buf, hid_t dxpl_id); -static int H5G_get_comment(H5G_loc_t *loc, const char *name, - size_t bufsize, char *buf, hid_t dxpl_id); static herr_t H5G_insertion_loc_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*/); @@ -660,52 +656,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Gget_objname_by_idx - * - * Purpose: Returns the name of objects in the group by giving index. - * If `name' is non-NULL then write up to `size' bytes into that - * buffer and always return the length of the entry name. - * Otherwise `size' is ignored and the function does not store the name, - * just returning the number of characters required to store the name. - * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) - * is unchanged and the function returns a negative value. - * If a zero is returned for the name's length, then there is no name - * associated with the ID. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Raymond Lu - * Nov 20, 2002 - * - *------------------------------------------------------------------------- - */ -ssize_t -H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size) -{ - H5G_loc_t loc; /* Object location */ - ssize_t ret_value; - - FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL) - H5TRACE4("Zs","ihsz",loc_id,idx,name,size); - - /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") - if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") - - /* Call internal function*/ - if((ret_value = H5G_obj_get_name_by_idx(loc.oloc, idx, name, size, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object name") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gget_objname_by_idx() */ - - -/*------------------------------------------------------------------------- * Function: H5Gget_objtype_by_idx * * Purpose: Returns the type of objects in the group by giving index. @@ -785,88 +735,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Gset_comment - * - * Purpose: Gives the specified object a comment. The COMMENT string - * should be a null terminated string. An object can have only - * one comment at a time. Passing NULL for the COMMENT argument - * will remove the comment property from the object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, July 20, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gset_comment(hid_t loc_id, const char *name, const char *comment) -{ - H5G_loc_t loc; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gset_comment, FAIL) - H5TRACE3("e","iss",loc_id,name,comment); - - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - - if(H5G_set_comment(&loc, name, comment, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gset_comment() */ - - -/*------------------------------------------------------------------------- - * Function: H5Gget_comment - * - * Purpose: Return at most BUFSIZE characters of the comment for the - * specified object. If BUFSIZE is large enough to hold the - * entire comment then the comment string will be null - * terminated, otherwise it will not. If the object does not - * have a comment value then no bytes are copied to the BUF - * buffer. - * - * Return: Success: Number of characters in the comment counting - * the null terminator. The value returned may - * be larger than the BUFSIZE argument. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, July 20, 1998 - * - *------------------------------------------------------------------------- - */ -int -H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf) -{ - H5G_loc_t loc; - int ret_value; - - FUNC_ENTER_API(H5Gget_comment, FAIL) - H5TRACE4("Is","iszs",loc_id,name,bufsize,buf); - - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - if(bufsize > 0 && !buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified") - - if((ret_value = H5G_get_comment(&loc, name, bufsize, buf, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gget_comment() */ - - -/*------------------------------------------------------------------------- * Function: H5Gget_create_plist * * Purpose: Returns a copy of the group creation property list. @@ -960,6 +828,32 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, November 11, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_init, FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_init() */ + + +/*------------------------------------------------------------------------- * Function: H5G_init_interface * * Purpose: Initializes the H5G interface. @@ -1838,121 +1732,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_set_comment - * - * Purpose: (Re)sets the comment for an object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, July 20, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id) -{ - H5G_loc_t obj_loc; /* Object's location */ - H5G_name_t path; - H5O_loc_t oloc; - hbool_t loc_valid = FALSE; - H5O_name_t comment; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment) - - /* Get the symbol table entry for the object */ - obj_loc.path = &path; - obj_loc.oloc = &oloc; - H5G_loc_reset(&obj_loc); - if(H5G_loc_find(loc, name, &obj_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - loc_valid = TRUE; - - /* Remove the previous comment message if any */ - if(H5O_remove(obj_loc.oloc, H5O_NAME_ID, 0, TRUE, dxpl_id) < 0) - H5E_clear_stack(NULL); - - /* Add the new message */ - if(buf && *buf) { - /* Casting away const OK -QAK */ - comment.s = (char *)buf; - if(H5O_modify(obj_loc.oloc, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message") - } /* end if */ - -done: - /* Release obj_loc */ - if(loc_valid) { - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free location") - } - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_set_comment() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_get_comment - * - * Purpose: Get the comment value for an object. - * - * Return: Success: Number of bytes in the comment including the - * null terminator. Zero if the object has no - * comment. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, July 20, 1998 - * - *------------------------------------------------------------------------- - */ -static int -H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id) -{ - H5O_name_t comment; - H5G_loc_t obj_loc; /* Object's location */ - H5G_name_t path; - H5O_loc_t oloc; - hbool_t loc_valid = FALSE; - int ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment) - - /* Get the symbol table entry for the object */ - obj_loc.path = &path; - obj_loc.oloc = &oloc; - H5G_loc_reset(&obj_loc); - if(H5G_loc_find(loc, name, &obj_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - loc_valid = TRUE; - - /* Get the message */ - comment.s = NULL; - if(NULL == H5O_read(obj_loc.oloc, H5O_NAME_ID, 0, &comment, dxpl_id)) { - if(buf && bufsize > 0) - buf[0] = '\0'; - ret_value = 0; - } else { - if(buf && bufsize) - HDstrncpy(buf, comment.s, bufsize); - ret_value = (int)HDstrlen(comment.s); - H5O_reset(H5O_NAME_ID, &comment); - } /* end else */ - -done: - /* Release obj_loc */ - if(loc_valid) { - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free location") - } - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_get_comment() */ - - -/*------------------------------------------------------------------------- * Function: H5G_insertion_loc_cb * * Purpose: Callback for finding insertion location. This routine sets the diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 4bb9062..9e45f6a 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -181,33 +181,6 @@ typedef struct { /* * Data exchange structure to pass through the v2 B-tree layer for the - * H5B2_index function when retrieving the type of a link by index. - */ -typedef struct { - /* downward (internal) */ - H5F_t *f; /* Pointer to file that fractal heap is in */ - hid_t dxpl_id; /* DXPL for operation */ - H5HF_t *fheap; /* Fractal heap handle */ - - /* upward */ - H5G_obj_t type; /* Type of object */ -} H5G_bt2_gtbi_ud1_t; - -/* - * Data exchange structure to pass through the fractal heap layer for the - * H5HF_op function when retrieving the type of a link by index. - */ -typedef struct { - /* downward (internal) */ - H5F_t *f; /* Pointer to file that fractal heap is in */ - hid_t dxpl_id; /* DXPL for operation */ - - /* upward */ - H5G_obj_t type; /* Type of object */ -} H5G_fh_gtbi_ud1_t; - -/* - * Data exchange structure to pass through the v2 B-tree layer for the * H5B2_index function when retrieving a link by index. */ typedef struct { @@ -233,6 +206,7 @@ typedef struct { H5O_link_t *lnk; /* Pointer to link */ } H5G_fh_lbi_ud1_t; + /********************/ /* Package Typedefs */ /********************/ @@ -705,12 +679,14 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, udata.lnk = lnk; /* Find & copy the link in the appropriate index */ - if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0) + if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_lookup_by_idx_bt2_cb, &udata) < 0) { + H5HF_close(fheap, dxpl_id); HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in index") + } /* end if */ /* Close heap */ if(H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") } /* end if */ else { /* Otherwise, we need to build a table of the links and sort it */ H5G_link_table_t ltable; /* Table of links */ @@ -719,13 +695,17 @@ H5G_dense_lookup_by_idx(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, 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") + /* Check for going out of bounds */ + if(n >= ltable.nlinks) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") + /* Copy link information */ if(NULL == H5O_copy(H5O_LINK_ID, <able.lnks[n], lnk)) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5B2_ITER_ERROR, "can't copy link message") /* Free link table information */ if(H5G_obj_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") } /* end else */ done: @@ -1042,7 +1022,7 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, H5_iter_order_t order, hid_t gid, /* Free link table information */ if(H5G_obj_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") } /* end else */ done: @@ -1158,11 +1138,12 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, - hsize_t idx, char* name, size_t size) +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) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ - H5G_bt2_gnbi_ud1_t udata; /* User data for v2 B-tree callback */ + const H5B2_class_t *bt2_class = NULL; /* Class of v2 B-tree */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_dense_get_name_by_idx, FAIL) @@ -1173,130 +1154,89 @@ H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, HDassert(f); HDassert(linfo); - /* Open the fractal heap */ - if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->link_fheap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - - /* Set up the user data for the v2 B-tree 'record remove' callback */ - udata.f = f; - udata.dxpl_id = dxpl_id; - udata.fheap = fheap; - udata.name = name; - udata.name_size = size; - - /* Retrieve the name according to the v2 B-tree's index order */ -/* (XXX: using name index currently) */ - if(H5B2_index(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, H5_ITER_INC, idx, - H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") - - /* Set return value */ - ret_value = udata.name_len; - -done: - /* Release resources */ - if(fheap) - if(H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + /* Determine the address of the index to use */ + if(idx_type == H5L_INDEX_NAME) { + /* Check if "native" order is OK - since names are hashed, getting them + * in strictly increasing or decreasing order requires building a + * table and sorting it. + */ + if(order == H5_ITER_NATIVE) { + bt2_addr = linfo->name_bt2_addr; + bt2_class = H5G_BT2_NAME; + HDassert(H5F_addr_defined(bt2_addr)); + } /* end if */ + else + bt2_addr = HADDR_UNDEF; + } /* end if */ + else { + HDassert(idx_type == H5L_INDEX_CRT_ORDER); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_dense_get_name_by_idx() */ + /* This address may not be defined if creation order is tracked, but + * there's no index on it. If there's no v2 B-tree that indexes + * the links, a table will be built. + */ + bt2_addr = linfo->corder_bt2_addr; + bt2_class = H5G_BT2_CORDER; + } /* end else */ - -/*------------------------------------------------------------------------- - * Function: H5G_dense_get_type_by_idx_fh_cb - * - * Purpose: Callback for fractal heap operator, to retrieve type according - * to an index - * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Sep 19 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_dense_get_type_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) -{ - H5G_fh_gtbi_ud1_t *udata = (H5G_fh_gtbi_ud1_t *)_udata; /* User data for fractal heap 'op' callback */ - H5O_link_t *lnk; /* Pointer to link created from heap object */ - herr_t ret_value = SUCCEED; /* Return value */ + /* If there is an index defined for the field, use it */ + if(H5F_addr_defined(bt2_addr)) { + H5HF_t *fheap; /* Fractal heap handle */ + H5G_bt2_gnbi_ud1_t udata; /* User data for v2 B-tree callback */ - FUNC_ENTER_NOAPI_NOINIT(H5G_dense_get_type_by_idx_fh_cb) + /* Open the fractal heap */ + if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->link_fheap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - /* Decode link information */ - if(NULL == (lnk = H5O_decode(udata->f, udata->dxpl_id, obj, H5O_LINK_ID))) - HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link") + /* Set up the user data for the v2 B-tree 'record remove' callback */ + udata.f = f; + udata.dxpl_id = dxpl_id; + udata.fheap = fheap; + udata.name = name; + udata.name_size = size; - /* Get the type of the link */ - /* Determine type of object */ - if(lnk->type == H5L_TYPE_SOFT) - udata->type = H5G_LINK; - else if(lnk->type >= H5L_TYPE_UD_MIN) - udata->type = H5G_UDLINK; - else if(lnk->type == H5L_TYPE_HARD) { - H5O_loc_t tmp_oloc; /* Temporary object location */ + /* Retrieve the name according to the v2 B-tree's index order */ + if(H5B2_index(f, dxpl_id, bt2_class, bt2_addr, order, n, H5G_dense_get_name_by_idx_bt2_cb, &udata) < 0) { + H5HF_close(fheap, dxpl_id); + HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") + } /* end if */ - /* Build temporary object location */ - tmp_oloc.file = udata->f; - tmp_oloc.addr = lnk->u.hard.addr; + /* Close heap */ + if(H5HF_close(fheap, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - /* Get the type of the object */ - if((udata->type = H5O_obj_type(&tmp_oloc, udata->dxpl_id)) == H5G_UNKNOWN) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine object type") + /* Set return value */ + ret_value = udata.name_len; } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown link type") - - /* Release the space allocated for the link */ - H5O_free(H5O_LINK_ID, lnk); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_dense_get_type_by_idx_fh_cb() */ + else { /* Otherwise, we need to build a table of the links and sort it */ + H5G_link_table_t ltable; /* Table of links */ - -/*------------------------------------------------------------------------- - * Function: H5G_dense_get_type_by_idx_bt2_cb - * - * Purpose: v2 B-tree callback for dense link storage 'get type by idx' call - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Sep 19 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_dense_get_type_by_idx_bt2_cb(const void *_record, void *_bt2_udata) -{ - const H5G_dense_bt2_name_rec_t *record = (const H5G_dense_bt2_name_rec_t *)_record; - H5G_bt2_gtbi_ud1_t *bt2_udata = (H5G_bt2_gtbi_ud1_t *)_bt2_udata; /* User data for callback */ - H5G_fh_gtbi_ud1_t fh_udata; /* User data for fractal heap 'op' callback */ - herr_t ret_value = SUCCEED; /* Return value */ + /* Build the table of links for this group */ + 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") - FUNC_ENTER_NOAPI_NOINIT(H5G_dense_get_type_by_idx_bt2_cb) + /* Check for going out of bounds */ + if(n >= ltable.nlinks) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") - /* Prepare user data for callback */ - /* down */ - fh_udata.f = bt2_udata->f; - fh_udata.dxpl_id = bt2_udata->dxpl_id; + /* Get the length of the name */ + ret_value = (ssize_t)HDstrlen(ltable.lnks[n].name); - /* Call fractal heap 'op' routine, to perform user callback */ - if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id, - H5G_dense_get_type_by_idx_fh_cb, &fh_udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPERATE, FAIL, "link found callback failed") + /* Copy the name into the user's buffer, if given */ + if(name) { + HDstrncpy(name, ltable.lnks[n].name, MIN((size_t)(ret_value + 1), size)); + if((size_t)ret_value >= size) + name[size - 1]='\0'; + } /* end if */ - /* Set the link's type to return */ - bt2_udata->type = fh_udata.type; + /* Free link table information */ + if(H5G_obj_release_table(<able) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_dense_get_type_by_idx_bt2_cb() */ +} /* end H5G_dense_get_name_by_idx() */ /*------------------------------------------------------------------------- @@ -1304,7 +1244,13 @@ done: * * Purpose: Returns the type of objects in the group by giving index. * - * Return: Success: Non-negative, length of name + * Note: This routine assumes a lookup on the link name index in + * increasing order and isn't currently set up to be as + * flexible as other routines in this code module, because + * the H5Gget_objtype_by_idx that it's supporting is + * deprecated. + * + * Return: Success: Non-negative, object type * Failure: Negative * * Programmer: Quincey Koziol @@ -1314,14 +1260,13 @@ done: *------------------------------------------------------------------------- */ H5G_obj_t -H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, +H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hsize_t idx) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ - H5G_bt2_gtbi_ud1_t udata; /* User data for v2 B-tree callback */ + H5G_link_table_t ltable = {0, NULL}; /* Table of links */ H5G_obj_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5G_dense_get_type_by_idx, FAIL) + FUNC_ENTER_NOAPI(H5G_dense_get_type_by_idx, H5G_UNKNOWN) /* * Check arguments. @@ -1329,29 +1274,38 @@ H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, HDassert(f); HDassert(linfo); - /* Open the fractal heap */ - if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->link_fheap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Build the table of links for this group */ + if(H5G_dense_build_table(f, dxpl_id, linfo, H5L_INDEX_NAME, H5_ITER_INC, <able) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5G_UNKNOWN, "error building table of links") - /* Set up the user data for the v2 B-tree 'record remove' callback */ - udata.f = f; - udata.dxpl_id = dxpl_id; - udata.fheap = fheap; + /* Check for going out of bounds */ + if(idx >= ltable.nlinks) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "index out of bound") + + /* Determine type of object */ + if(ltable.lnks[idx].type == H5L_TYPE_SOFT) + ret_value = H5G_LINK; + else if(ltable.lnks[idx].type >= H5L_TYPE_UD_MIN) + ret_value = H5G_UDLINK; + else if(ltable.lnks[idx].type == H5L_TYPE_HARD){ + H5O_loc_t tmp_oloc; /* Temporary object location */ - /* Retrieve the name according to the v2 B-tree's index order */ -/* (XXX: using name index currently) */ - if(H5B2_index(f, dxpl_id, H5G_BT2_NAME, linfo->name_bt2_addr, H5_ITER_INC, idx, - H5G_dense_get_type_by_idx_bt2_cb, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") + /* Build temporary object location */ + tmp_oloc.file = f; + tmp_oloc.addr = ltable.lnks[idx].u.hard.addr; - /* Set return value */ - ret_value = udata.type; + /* Get the type of the object */ + if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type") + } else { + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type") + } /* end else */ done: - /* Release resources */ - if(fheap) - if(H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + /* Release link table */ + if(ltable.lnks) + if(H5G_obj_release_table(<able) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_dense_get_type_by_idx() */ @@ -1604,7 +1558,7 @@ H5G_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hbool_t adj_link) /* Close the fractal heap */ if(H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap") } /* end if */ else { /* Delete the name index, without adjusting the ref. count on the links */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 92570d2..af7982c 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -30,12 +30,18 @@ /* Module Setup */ /****************/ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5G_init_deprec_interface + /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Gpkg.h" /* Groups */ #include "H5Lprivate.h" /* Links */ @@ -62,6 +68,10 @@ static herr_t H5G_link_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name); static herr_t H5G_move(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name); +static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name, + const char *buf, hid_t dxpl_id); +static int H5G_get_comment(H5G_loc_t *loc, const char *name, + size_t bufsize, char *buf, hid_t dxpl_id); /*********************/ @@ -80,6 +90,27 @@ static herr_t H5G_move(hid_t src_loc_id, const char *src_name, +/*-------------------------------------------------------------------------- +NAME + H5G_init_deprec_interface -- Initialize interface-specific information +USAGE + herr_t H5G_init_deprec_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5G_init() currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5G_init_deprec_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_init_deprec_interface) + + FUNC_LEAVE_NOAPI(H5G_init()) +} /* H5G_init_deprec_interface() */ + + /*------------------------------------------------------------------------- * Function: H5Glink * @@ -339,7 +370,7 @@ done: /*------------------------------------------------------------------------- * Function: H5Gunlink * - * Purpose: Removes a link. The new API is H5Ldelete. + * Purpose: Removes a link. The new API is H5Ldelete/H5Ldelete_by_idx. * *------------------------------------------------------------------------- */ @@ -371,7 +402,7 @@ done: * Function: H5Gget_linkval * * Purpose: Retrieve's a soft link's data. The new API is - * H5Lget_val. + * H5Lget_val/H5Lget_val_by_idx. * *------------------------------------------------------------------------- */ @@ -398,3 +429,249 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_linkval() */ + +/*------------------------------------------------------------------------- + * Function: H5Gget_objname_by_idx + * + * Purpose: Returns the name of objects in the group by giving index. + * If `name' is non-NULL then write up to `size' bytes into that + * buffer and always return the length of the entry name. + * Otherwise `size' is ignored and the function does not store the name, + * just returning the number of characters required to store the name. + * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) + * is unchanged and the function returns a negative value. + * If a zero is returned for the name's length, then there is no name + * associated with the ID. + * + * Note: Deprecated in favor of H5Lget_name_by_idx + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Raymond Lu + * Nov 20, 2002 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size) +{ + H5G_loc_t loc; /* Object location */ + ssize_t ret_value; + + FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL) + H5TRACE4("Zs","ihsz",loc_id,idx,name,size); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") + if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + + /* Call internal function */ + if((ret_value = H5G_obj_get_name_by_idx(loc.oloc, H5L_INDEX_NAME, H5_ITER_INC, idx, name, size, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objname_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gset_comment + * + * Purpose: Gives the specified object a comment. The COMMENT string + * should be a null terminated string. An object can have only + * one comment at a time. Passing NULL for the COMMENT argument + * will remove the comment property from the object. + * + * Note: Deprecated in favor of using attributes on group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, July 20, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gset_comment(hid_t loc_id, const char *name, const char *comment) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Gset_comment, FAIL) + H5TRACE3("e","iss",loc_id,name,comment); + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + + if(H5G_set_comment(&loc, name, comment, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gset_comment() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gget_comment + * + * Purpose: Return at most BUFSIZE characters of the comment for the + * specified object. If BUFSIZE is large enough to hold the + * entire comment then the comment string will be null + * terminated, otherwise it will not. If the object does not + * have a comment value then no bytes are copied to the BUF + * buffer. + * + * Note: Deprecated in favor of using attributes on group + * + * Return: Success: Number of characters in the comment counting + * the null terminator. The value returned may + * be larger than the BUFSIZE argument. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, July 20, 1998 + * + *------------------------------------------------------------------------- + */ +int +H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf) +{ + H5G_loc_t loc; + int ret_value; + + FUNC_ENTER_API(H5Gget_comment, FAIL) + H5TRACE4("Is","iszs",loc_id,name,bufsize,buf); + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(bufsize > 0 && !buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified") + + if((ret_value = H5G_get_comment(&loc, name, bufsize, buf, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_comment() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_set_comment + * + * Purpose: (Re)sets the comment for an object. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, July 20, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id) +{ + H5G_loc_t obj_loc; /* Object's location */ + H5G_name_t path; + H5O_loc_t oloc; + hbool_t loc_valid = FALSE; + H5O_name_t comment; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment) + + /* Get the symbol table entry for the object */ + obj_loc.path = &path; + obj_loc.oloc = &oloc; + H5G_loc_reset(&obj_loc); + if(H5G_loc_find(loc, name, &obj_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_valid = TRUE; + + /* Remove the previous comment message if any */ + if(H5O_remove(obj_loc.oloc, H5O_NAME_ID, 0, TRUE, dxpl_id) < 0) + H5E_clear_stack(NULL); + + /* Add the new message */ + if(buf && *buf) { + /* Casting away const OK -QAK */ + comment.s = (char *)buf; + if(H5O_modify(obj_loc.oloc, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message") + } /* end if */ + +done: + /* Release obj_loc */ + if(loc_valid) + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_set_comment() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_get_comment + * + * Purpose: Get the comment value for an object. + * + * Return: Success: Number of bytes in the comment including the + * null terminator. Zero if the object has no + * comment. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, July 20, 1998 + * + *------------------------------------------------------------------------- + */ +static int +H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id) +{ + H5O_name_t comment; + H5G_loc_t obj_loc; /* Object's location */ + H5G_name_t path; + H5O_loc_t oloc; + hbool_t loc_valid = FALSE; + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment) + + /* Get the symbol table entry for the object */ + obj_loc.path = &path; + obj_loc.oloc = &oloc; + H5G_loc_reset(&obj_loc); + if(H5G_loc_find(loc, name, &obj_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_valid = TRUE; + + /* Get the message */ + comment.s = NULL; + if(NULL == H5O_read(obj_loc.oloc, H5O_NAME_ID, 0, &comment, dxpl_id)) { + if(buf && bufsize > 0) + buf[0] = '\0'; + ret_value = 0; + } else { + if(buf && bufsize) + HDstrncpy(buf, comment.s, bufsize); + ret_value = (int)HDstrlen(comment.s); + H5O_reset(H5O_NAME_ID, &comment); + } /* end else */ + +done: + /* Release obj_loc */ + if(loc_valid) + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_comment() */ + diff --git a/src/H5Glink.c b/src/H5Glink.c index 20c7476..17b8f0a 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -434,7 +434,8 @@ done: */ ssize_t H5G_link_get_name_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, - const H5O_linfo_t *linfo, hsize_t idx, char* name, size_t size) + const H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, + hsize_t idx, char* name, size_t size) { H5G_link_table_t ltable = {0, NULL}; /* Link table */ ssize_t ret_value; /* Return value */ @@ -445,30 +446,29 @@ H5G_link_get_name_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, HDassert(oloc); /* Build table of all link messages */ - if(H5G_link_build_table(oloc, dxpl_id, linfo, H5L_INDEX_NAME, H5_ITER_INC, <able) < 0) + if(H5G_link_build_table(oloc, dxpl_id, linfo, idx_type, order, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table") /* Check for going out of bounds */ if(idx >= ltable.nlinks) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") /* Get the length of the name */ ret_value = (ssize_t)HDstrlen(ltable.lnks[idx].name); /* Copy the name into the user's buffer, if given */ if(name) { - HDstrncpy(name, ltable.lnks[idx].name, MIN((size_t)(ret_value+1),size)); + HDstrncpy(name, ltable.lnks[idx].name, MIN((size_t)(ret_value + 1), size)); if((size_t)ret_value >= size) - name[size-1]='\0'; + name[size - 1]='\0'; } /* end if */ done: /* Release link table */ - if(ltable.lnks) { + if(ltable.lnks) /* Free link table information */ if(H5G_obj_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_get_name_by_idx() */ @@ -521,18 +521,17 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linf /* Get the type of the object */ if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type") - } else{ - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type") - }/* end else */ + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type") + } else { + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type") + } /* end else */ done: /* Release link table */ - if(ltable.lnks) { + if(ltable.lnks) /* Free link table information */ if(H5G_obj_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_get_type_by_idx() */ @@ -696,11 +695,10 @@ H5G_link_iterate(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, done: /* Release link table */ - if(ltable.lnks) { + if(ltable.lnks) /* Free link table information */ if(H5G_obj_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_iterate() */ @@ -839,11 +837,10 @@ H5G_link_lookup_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, done: /* Release link table */ - if(ltable.lnks) { + if(ltable.lnks) /* Free link table information */ if(H5G_obj_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_lookup_by_idx() */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index cc60366..2f51758 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -864,8 +864,8 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, - hid_t dxpl_id) +H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5L_index_t idx_type, + H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id) { H5O_linfo_t linfo; /* Link info message */ ssize_t ret_value; /* Return value */ @@ -873,18 +873,32 @@ H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, FUNC_ENTER_NOAPI(H5G_obj_get_name_by_idx, FAIL) /* Sanity check */ - HDassert(oloc); + HDassert(oloc && oloc->file); /* Attempt to get the link info for this group */ if(H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id)) { + /* Check for creation order tracking, if creation order index lookup requested */ + if(idx_type == H5L_INDEX_CRT_ORDER) { + H5O_ginfo_t ginfo; /* Group info message */ + + /* Get group info message, to see if creation order is tracked for links in this group */ + if(NULL == H5O_read(oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info message for group") + + /* Check if creation order is tracked */ + if(!ginfo.track_corder) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "creation order not tracked for links in group") + } /* end if */ + + /* Check for dense link storage */ if(H5F_addr_defined(linfo.link_fheap_addr)) { /* Get the object's name from the dense link storage */ - if((ret_value = H5G_dense_get_name_by_idx(oloc->file, dxpl_id, &linfo, idx, name, size)) < 0) + if((ret_value = H5G_dense_get_name_by_idx(oloc->file, dxpl_id, &linfo, idx_type, order, n, name, size)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end if */ else { /* Get the object's name from the link messages */ - if((ret_value = H5G_link_get_name_by_idx(oloc, dxpl_id, &linfo, idx, name, size)) < 0) + if((ret_value = H5G_link_get_name_by_idx(oloc, dxpl_id, &linfo, idx_type, order, n, name, size)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ } /* end if */ @@ -892,8 +906,12 @@ H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, /* Clear error stack from not finding the link info message */ H5E_clear_stack(NULL); + /* Can only perform name lookups on groups with symbol tables */ + if(idx_type != H5L_INDEX_NAME) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query") + /* Get the object's name from the symbol table */ - if((ret_value = H5G_stab_get_name_by_idx(oloc, idx, name, size, dxpl_id)) < 0) + if((ret_value = H5G_stab_get_name_by_idx(oloc, order, n, name, size, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ @@ -1146,7 +1164,7 @@ done: /*------------------------------------------------------------------------- * Function: H5G_obj_lookup_by_idx * - * Purpose: Look up a link in a group, according to an order within an + * Purpose: Look up link info in a group, according to an order within an * index. * * Return: Non-negative on success/Negative on failure diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 00118a2..91819f8 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -346,6 +346,7 @@ H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1]; /* * Utility functions */ +H5_DLL herr_t H5G_init(void); H5_DLL char * H5G_normalize(const char *name); H5_DLL const char * H5G_component(const char *name, size_t *size_p); H5_DLL herr_t H5G_traverse_term_interface(void); @@ -374,8 +375,8 @@ 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_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, hsize_t idx, char* name, - size_t size, 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); H5_DLL H5G_obj_t H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id); H5_DLL herr_t H5G_stab_remove(H5O_loc_t *oloc, const char *name, @@ -420,7 +421,8 @@ H5_DLL herr_t H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, H5_DLL herr_t H5G_link_insert(H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk, hid_t dxpl_id); H5_DLL ssize_t H5G_link_get_name_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, - const H5O_linfo_t *linfo, hsize_t idx, char* name, size_t size); + const H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, + hsize_t idx, char *name, size_t size); H5_DLL H5G_obj_t H5G_link_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo, hsize_t idx); H5_DLL herr_t H5G_link_remove(const H5O_loc_t *oloc, const char *name, @@ -449,7 +451,8 @@ 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 ssize_t H5G_dense_get_name_by_idx(H5F_t *f, hid_t dxpl_id, - H5O_linfo_t *linfo, hsize_t idx, char* name, size_t size); + H5O_linfo_t *linfo, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, + char *name, size_t size); H5_DLL H5G_obj_t H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, hsize_t idx); H5_DLL herr_t H5G_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, @@ -472,8 +475,8 @@ H5_DLL herr_t H5G_obj_iterate(hid_t loc_id, const char *name, 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, hsize_t idx, - char* name, size_t size, hid_t dxpl_id); +H5_DLL ssize_t H5G_obj_get_name_by_idx(H5O_loc_t *oloc, H5L_index_t idx_type, + H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id); H5_DLL H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id); H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name, diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 8048aee..9f57a85 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -108,13 +108,9 @@ 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 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 H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); -H5_DLL herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment); -H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, - char *buf); H5_DLL hid_t H5Gget_create_plist(hid_t group_id); /* Functions and variables defined for compatibility with previous versions @@ -133,6 +129,11 @@ H5_DLL herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5_DLL herr_t H5Gunlink(hid_t loc_id, const char *name); H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/); +H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char* name, + size_t size); +H5_DLL herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment); +H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, + char *buf); #ifdef __cplusplus } diff --git a/src/H5Gstab.c b/src/H5Gstab.c index b6796eb..4a0d46a 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -530,8 +530,8 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, - size_t size, hid_t dxpl_id) +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) { H5O_stab_t stab; /* Info about local heap & B-tree */ H5G_bt_it_idx1_t udata; /* Iteration information */ @@ -546,10 +546,22 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Remap index for decreasing iteration order */ + if(order == H5_ITER_DEC) { + hsize_t nlinks = 0; /* Number of links in group */ + + /* Iterate over the symbol table nodes, to count the links */ + if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, &nlinks) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed") + + /* Map decreasing iteration order index to increasing iteration order index */ + n = nlinks - (n + 1); + } /* end if */ + /* Set iteration information */ udata.common.f = oloc->file; udata.common.dxpl_id = dxpl_id; - udata.common.idx = idx; + udata.common.idx = n; udata.common.num_objs = 0; udata.common.op = H5G_stab_get_name_by_idx_cb; udata.heap_addr = stab.heap_addr; @@ -568,7 +580,7 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, /* Copy the name into the user's buffer, if given */ if(name) { - HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1),size)); + HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1), size)); if((size_t)ret_value >= size) name[size - 1]='\0'; } /* end if */ @@ -884,7 +896,7 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, /* Iterate over the symbol table nodes, to count the links */ if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, &nlinks) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed"); + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed") /* Map decreasing iteration order index to increasing iteration order index */ n = nlinks - (n + 1); diff --git a/src/H5L.c b/src/H5L.c index d61b0d8..0d2669f 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -104,6 +104,19 @@ typedef struct { H5L_info_t *linfo; /* Buffer to return to user */ } H5L_trav_ud7_t; +/* User data for path traversal routine for getting name by index */ +typedef struct { + /* In */ + H5L_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of name buffer */ + hid_t dxpl_id; /* dxpl to use in callback */ + + /* Out */ + char *name; /* Buffer to return name to user */ +} H5L_trav_ud8_t; + /********************/ /* Local Prototypes */ /********************/ @@ -131,12 +144,18 @@ 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 UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); -static herr_t H5L_get_info_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, - const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, +static herr_t H5L_get_info_by_idx_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_by_idx(const H5G_loc_t *loc, const char *group_name, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id); +static herr_t H5L_get_name_by_idx_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_name_by_idx(const H5G_loc_t *loc, 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, hid_t dxpl_id); /*********************/ /* Package Variables */ @@ -694,7 +713,7 @@ H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linkbuf /*out*/, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Get the creation time */ + /* Get the link information */ if(H5L_get_info(&loc, name, linkbuf, lapl_id, H5AC_ind_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") @@ -742,7 +761,7 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Get the creation time */ + /* Get the link information */ if(H5L_get_info_by_idx(&loc, group_name, idx_type, order, n, linkbuf, lapl_id, H5AC_ind_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") @@ -877,6 +896,56 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Lis_registered() */ + +/*------------------------------------------------------------------------- + * Function: H5Lget_name_by_idx + * + * Purpose: Gets name for a link, according to the order within an + * index. + * + * Same pattern of behavior as H5Iget_name. + * + * Return: Success: Non-negative with information in NAME buffer + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, November 11, 2006 + * + *------------------------------------------------------------------------- + */ +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) +{ + H5G_loc_t loc; /* Location of group */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Lget_name_by_idx, FAIL) + + /* Check arguments */ + if(H5G_loc(loc_id, &loc)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + 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(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") + + /* Get the link's name */ + if((ret_value = H5L_get_name_by_idx(&loc, group_name, idx_type, order, n, name, size, lapl_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link's name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_name_by_idx() */ + /* *------------------------------------------------------------------------- *------------------------------------------------------------------------- @@ -2306,3 +2375,84 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5L_get_default_lcpl */ + +/*------------------------------------------------------------------------- + * Function: H5L_get_name_by_idx_cb + * + * Purpose: Callback for retrieving a link's name according to an + * index's order. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 11 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_name_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5L_trav_ud8_t *udata = (H5L_trav_ud8_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_name_by_idx_cb) + + /* Check if the name of the group resolved to a valid object */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist") + + /* Query link */ + if(H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, + udata->n, udata->name, udata->size, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found") + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_name_by_idx_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_name_by_idx + * + * Purpose: Returns name of a link, according to an order within + * an index. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 11 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_name_by_idx(const H5G_loc_t *loc, 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, hid_t dxpl_id) +{ + H5L_trav_ud8_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_name_by_idx) + + /* Set up user data for callback */ + udata.idx_type = idx_type; + udata.order = order; + udata.n = n; + udata.dxpl_id = dxpl_id; + udata.name = name; + udata.size = size; + + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_name_by_idx_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L_get_name_by_idx() */ + diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index f206b94..77f03e6 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -159,6 +159,9 @@ H5_DLL herr_t H5Lget_info(hid_t loc_id, const char *name, H5_DLL herr_t H5Lget_info_by_idx(hid_t loc_id, const char *group_name, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info_t *linkbuf /*out*/, hid_t lapl_id); +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); /* UD link functions */ H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, diff --git a/src/H5private.h b/src/H5private.h index 5b35111..599b636 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1441,4 +1441,6 @@ H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t init /* Functions for debugging */ H5_DLL herr_t H5_buffer_dump(FILE *stream, int indent, uint8_t *buf, uint8_t *marker, size_t buf_offset, size_t buf_size); -#endif + +#endif /* _H5private_H */ + diff --git a/test/links.c b/test/links.c index e16b7ee..71d1e02 100644 --- a/test/links.c +++ b/test/links.c @@ -5903,9 +5903,9 @@ error: /*------------------------------------------------------------------------- - * Function: corder_info_check + * Function: link_info_by_idx_check * - * Purpose: Support routine for corder_info_by_idx, to verify the link + * Purpose: Support routine for link_info_by_idx, to verify the link * info is correct for a link * * Note: This routine assumes that the links have been inserted in the @@ -5920,72 +5920,87 @@ error: *------------------------------------------------------------------------- */ static int -corder_info_check(hid_t group_id, hsize_t n, hbool_t use_index) +link_info_by_idx_check(hid_t group_id, const char *linkname, hsize_t n, + hbool_t use_index) { + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ H5L_info_t linfo; /* Link info struct */ - /* Get the link information for new link, in increasing creation order */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for new link */ - if(linfo.corder != (int64_t)n) TEST_ERROR - - /* Get the link information for first link, in increasing creation order */ + /* Verify the link information for first link, in increasing creation order */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for first link */ if(linfo.corder != 0) TEST_ERROR - /* Get the link information for new link, in native creation order (which is increasing) */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for new link */ + /* Verify the link information for new link, in increasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR - /* Don't test "native" order if there is no index */ + /* Verify the name for new link, in increasing creation order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + /* Don't test "native" order if there is no creation order index, since + * there's not a good way to easily predict the link's order in the name + * index. + */ if(use_index) { - /* Get the link information for first link, in native creation order (which is increasing) */ + /* Verify the link information for first link, in native creation order (which is increasing) */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for first link */ if(linfo.corder != 0) TEST_ERROR + + /* Verify the link information for new link, in native creation order (which is increasing) */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != (int64_t)n) TEST_ERROR + + /* Verify the name for new link, in increasing creation order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_NATIVE, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR } /* end if */ - /* Get the link information for new link, in decreasing creation order */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + /* Verify the link information for first link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.corder != 0) TEST_ERROR - /* Verify the link information for new link */ + /* Verify the link information for new link, in decreasing creation order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != (int64_t)n) TEST_ERROR - /* Get the link information for first link, in decreasing creation order */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + /* Verify the name for new link, in decreasing creation order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + - /* Verify the link information for first link */ + /* Verify the link information for first link, in increasing link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR - /* Get the link information for new link, in increasing link name order */ + /* Verify the link information for new link, in increasing link name order */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for new link */ if(linfo.corder != (int64_t)n) TEST_ERROR - /* Get the link information for first link, in increasing link name order */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + /* Verify the name for new link, in increasing link name order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, n, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR + + /* Don't test "native" order queries on link name order, since there's not + * a good way to easily predict the order of the links in the name index. + */ - /* Verify the link information for first link */ + /* Verify the link information for first link, in decreasing link name order */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(linfo.corder != 0) TEST_ERROR - /* Get the link information for new link, in decreasing link name order */ + /* Verify the link information for new link, in decreasing link name order */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for new link */ if(linfo.corder != (int64_t)n) TEST_ERROR - /* Get the link information for first link, in decreasing link name order */ - if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, n, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - - /* Verify the link information for first link */ - if(linfo.corder != 0) TEST_ERROR + /* Verify the name for new link, in decreasing link name order */ + HDmemset(tmpname, 0, (size_t)NAME_BUF_SIZE); + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(linkname, tmpname)) TEST_ERROR /* Success */ return(0); @@ -5993,11 +6008,11 @@ corder_info_check(hid_t group_id, hsize_t n, hbool_t use_index) error: /* Failure */ return(-1); -} /* end corder_info_check() */ +} /* end link_info_by_idx_check() */ /*------------------------------------------------------------------------- - * Function: corder_info_by_idx + * Function: link_info_by_idx * * Purpose: Create a group with creation order indices and test querying * info by index. @@ -6011,7 +6026,7 @@ error: *------------------------------------------------------------------------- */ static int -corder_info_by_idx(hid_t fapl, hbool_t use_index) +link_info_by_idx(hid_t fapl, hbool_t use_index) { hid_t file_id = (-1); /* File ID */ hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ @@ -6021,6 +6036,7 @@ corder_info_by_idx(hid_t fapl, hbool_t use_index) H5L_info_t linfo; /* Link info struct */ char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE];/* File name */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ @@ -6049,17 +6065,30 @@ corder_info_by_idx(hid_t fapl, hbool_t use_index) /* Query the group creation properties */ if(H5Pget_link_phase_change(gcpl_id, &max_compact, &min_dense) < 0) TEST_ERROR + /* Check for query on empty group */ + H5E_BEGIN_TRY { + ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, &linfo, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR + /* Create several links, up to limit of compact form */ for(u = 0; u < max_compact; u++) { - sprintf(objname, "filler %u", u); + sprintf(objname, "filler %02u", u); if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR if(H5Gclose(group_id2) < 0) TEST_ERROR /* Verify link information for new link */ - if(corder_info_check(group_id, (hsize_t)u, use_index) < 0) TEST_ERROR + if(link_info_by_idx_check(group_id, objname, (hsize_t)u, use_index) < 0) TEST_ERROR } /* end for */ - /* Check for out of bound offset */ + /* Verify state of group */ + if(H5G_has_links_test(group_id, NULL) != TRUE) TEST_ERROR + + /* Check for out of bound offset queries */ H5E_BEGIN_TRY { ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; @@ -6068,17 +6097,23 @@ corder_info_by_idx(hid_t fapl, hbool_t use_index) ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR - /* Create another link, to push group into dense form */ - sprintf(objname, "filler %u", max_compact); - if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR - if(H5Gclose(group_id2) < 0) TEST_ERROR + /* Create more links, to push group into dense form */ + for(; u < (max_compact * 2); u++) { + sprintf(objname, "filler %02u", u); + if((group_id2 = H5Gcreate(group_id, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(group_id2) < 0) TEST_ERROR - /* Verify state of group */ - if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR + /* Verify state of group */ + if(H5G_is_new_dense_test(group_id) != TRUE) TEST_ERROR - /* Verify link information for new link */ - if(corder_info_check(group_id, (hsize_t)u, use_index) < 0) TEST_ERROR + /* Verify link information for new link */ + if(link_info_by_idx_check(group_id, objname, (hsize_t)u, use_index) < 0) TEST_ERROR + } /* end for */ /* Close the group */ if(H5Gclose(group_id) < 0) TEST_ERROR @@ -6099,11 +6134,11 @@ error: H5Fclose(file_id); } H5E_END_TRY; return -1; -} /* end corder_info_by_idx() */ +} /* end link_info_by_idx() */ /*------------------------------------------------------------------------- - * Function: corder_info_by_idx_old + * Function: link_info_by_idx_old * * Purpose: Create a old-format group and test querying * info by index. @@ -6117,7 +6152,7 @@ error: *------------------------------------------------------------------------- */ static int -corder_info_by_idx_old(hid_t fapl) +link_info_by_idx_old(hid_t fapl) { hid_t file_id = (-1); /* File ID */ hid_t group_id = (-1), group_id2 = (-1); /* Group IDs */ @@ -6125,6 +6160,7 @@ corder_info_by_idx_old(hid_t fapl) char objname[NAME_BUF_SIZE]; /* Object name */ char filename[NAME_BUF_SIZE];/* File name */ haddr_t objno[CORDER_NLINKS]; /* Addresses of the objects created */ + char tmpname[NAME_BUF_SIZE]; /* Temporary link name */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ @@ -6151,25 +6187,53 @@ corder_info_by_idx_old(hid_t fapl) objno[u] = (haddr_t)sb.objno[0]; #endif if(H5Gclose(group_id2) < 0) TEST_ERROR + } /* end for */ - /* Verify link information for new link (in increasing order) */ + /* Verify link information for created links */ for(u = 0; u < CORDER_NLINKS; u++) { + unsigned dec_u = CORDER_NLINKS - (u + 1); /* Decreasing mapped index */ + + /* Make link name for increasing/native order queries */ + sprintf(objname, "filler %02u", u); + + /* Verify link information (in increasing order) */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR - } /* end for */ - /* Verify link information for new link (in decreasing order) */ - for(u = 0; u < CORDER_NLINKS; u++) { + /* Verify link name (in increasing order) */ + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR + + /* Verify link information (in native order - native is increasing) */ + if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[u])) TEST_ERROR + + /* Verify link name (in native order - native is increasing) */ + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR + + /* Make link name for decreasing order queries */ + sprintf(objname, "filler %02u", dec_u); + + /* Verify link information (in decreasing order) */ if(H5Lget_info_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, &linfo, H5P_DEFAULT) < 0) TEST_ERROR - if(H5F_addr_ne(linfo.u.address, objno[CORDER_NLINKS - (u + 1)])) TEST_ERROR + if(H5F_addr_ne(linfo.u.address, objno[dec_u])) TEST_ERROR + + /* Verify link name (in decreasing order) */ + if(H5Lget_name_by_idx(group_id, ".", H5L_INDEX_NAME, H5_ITER_DEC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, tmpname)) TEST_ERROR } /* end for */ - /* Check for creation order index query */ + /* Check for creation order index queries */ H5E_BEGIN_TRY { ret = H5Lget_info_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, &linfo, H5P_DEFAULT); } H5E_END_TRY; if(ret >= 0) TEST_ERROR + H5E_BEGIN_TRY { + ret = H5Lget_name_by_idx(group_id, ".", H5L_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, tmpname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT); + } H5E_END_TRY; + if(ret >= 0) TEST_ERROR /* Verify state of group */ if(H5G_has_stab_test(group_id) != TRUE) TEST_ERROR @@ -6189,7 +6253,7 @@ error: H5Fclose(file_id); } H5E_END_TRY; return -1; -} /* end corder_info_by_idx_old() */ +} /* end link_info_by_idx_old() */ /*------------------------------------------------------------------------- @@ -6295,12 +6359,12 @@ main(void) nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; nerrors += corder_transition(fapl2) < 0 ? 1 : 0; nerrors += corder_delete(fapl2) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; + nerrors += link_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; + nerrors += link_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; } /* end if */ else { /* Test new API calls on old-style groups */ - nerrors += corder_info_by_idx_old(fapl) < 0 ? 1 : 0; + nerrors += link_info_by_idx_old(fapl) < 0 ? 1 : 0; } } /* end for */ #else /* QAK */ @@ -6313,11 +6377,11 @@ main(void) nerrors += corder_create_dense(fapl2) < 0 ? 1 : 0; nerrors += corder_transition(fapl2) < 0 ? 1 : 0; nerrors += corder_delete(fapl2) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; - nerrors += corder_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; + nerrors += link_info_by_idx(fapl2, TRUE) < 0 ? 1 : 0; + nerrors += link_info_by_idx(fapl2, FALSE) < 0 ? 1 : 0; /* Test new API calls on old-style groups */ - nerrors += corder_info_by_idx_old(fapl) < 0 ? 1 : 0; + nerrors += link_info_by_idx_old(fapl) < 0 ? 1 : 0; #endif /* QAK */ /* Close 2nd FAPL */ -- cgit v0.12