summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt29
-rw-r--r--src/H5G.c273
-rw-r--r--src/H5Gdense.c288
-rw-r--r--src/H5Gdeprec.c281
-rw-r--r--src/H5Glink.c31
-rw-r--r--src/H5Gobj.c32
-rw-r--r--src/H5Gpkg.h15
-rw-r--r--src/H5Gpublic.h9
-rw-r--r--src/H5Gstab.c22
-rw-r--r--src/H5L.c158
-rw-r--r--src/H5Lpublic.h3
-rw-r--r--src/H5private.h4
-rw-r--r--test/links.c204
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, &ltable) < 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, &ltable.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(&ltable) < 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(&ltable) < 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, &ltable) < 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(&ltable) < 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, &ltable) < 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(&ltable) < 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, &ltable) < 0)
+ if(H5G_link_build_table(oloc, dxpl_id, linfo, idx_type, order, &ltable) < 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(&ltable) < 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(&ltable) < 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(&ltable) < 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(&ltable) < 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 */