summaryrefslogtreecommitdiffstats
path: root/src/H5Gstab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Gstab.c')
-rw-r--r--src/H5Gstab.c623
1 files changed, 476 insertions, 147 deletions
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index b63e1cd..926ff7f 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -26,87 +26,170 @@
#include "H5Fpkg.h" /* File access */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+/* Private typedefs */
+/* User data for finding a name in the link messages */
+typedef struct {
+ /* downward */
+ H5F_t *f; /* Pointer to file for insertion */
+ const char *name; /* Name to search for */
+
+ /* upward */
+ H5G_entry_t *ent; /* Entry to update when match found */
+} H5G_stab_ud1_t;
+
+/* User data for finding object info from B-tree */
+typedef struct {
+ /* downward */
+ H5O_loc_t *grp_oloc; /* Object location of group */
+ hid_t dxpl_id; /* DXPL during operation */
+ haddr_t heap_addr; /* Local heap address for group */
+
+ /* upward */
+ H5G_stat_t *statbuf; /* Caller's statbuf */
+} H5G_stab_fnd_ud1_t;
+
+/* User data for finding link information from B-tree */
+typedef struct {
+ /* downward */
+ H5F_t *file; /* Pointer to file for query */
+ hid_t dxpl_id; /* DXPL during operation */
+ const char *name; /* Name to search for */
+ haddr_t heap_addr; /* Local heap address for group */
+
+ /* upward */
+ H5O_link_t *lnk; /* Caller's link location */
+} H5G_stab_fnd_ud2_t;
+
+/* User data for finding object location from B-tree */
+typedef struct {
+ /* downward */
+ H5F_t *file; /* Pointer to file for query */
+ size_t size; /* Buffer size for link value */
+ haddr_t heap_addr; /* Local heap address for group */
+ hid_t dxpl_id; /* DXPL during operation */
+
+ /* upward */
+ char *buf; /* Buffer to fill with link value */
+} H5G_stab_fnd_ud3_t;
+
/* Private prototypes */
/*-------------------------------------------------------------------------
- * Function: H5G_stab_create
+ * Function: H5G_stab_create_components
*
- * Purpose: Creates a new empty symbol table (object header, name heap,
+ * Purpose: Creates the components for a new, empty, symbol table (name heap
* and B-tree). The caller can specify an initial size for the
- * name heap. The object header of the group is opened for
- * write access.
+ * name heap.
*
* In order for the B-tree to operate correctly, the first
* item in the heap is the empty string, and must appear at
* heap offset zero.
*
- * Errors:
- *
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Nov 7 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_create(H5F_t *f, hid_t dxpl_id, size_t init, H5G_entry_t *self/*out*/)
+H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id)
{
- size_t name; /*offset of "" name */
- H5O_stab_t stab; /*symbol table message */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t name_offset; /* Offset of "" name */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_stab_create, FAIL)
+ FUNC_ENTER_NOAPI(H5G_stab_create_components, FAIL)
/*
* Check arguments.
*/
HDassert(f);
- HDassert(self);
- init = MAX(init, H5HL_SIZEOF_FREE(f) + 2);
+ HDassert(stab);
+ HDassert(size_hint > 0);
+
+ /* Create the B-tree */
+ if(H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab->btree_addr)/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
/* Create symbol table private heap */
- if (H5HL_create(f, dxpl_id, init, &(stab.heap_addr)/*out*/)<0)
+ if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
- name = H5HL_insert(f, dxpl_id, stab.heap_addr, 1, "");
- if ((size_t)(-1)==name)
+ name_offset = H5HL_insert(f, dxpl_id, stab->heap_addr, 1, "");
+ if((size_t)(-1) == name_offset)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
/*
* B-tree's won't work if the first name isn't at the beginning
* of the heap.
*/
- assert(0 == name);
+ HDassert(0 == name_offset);
- /* Create the B-tree */
- if (H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab.btree_addr)/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_create_components() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_create
+ *
+ * Purpose: Creates a new empty symbol table (object header, name heap,
+ * and B-tree). The caller can specify an initial size for the
+ * name heap. The object header of the group is opened for
+ * write access.
+ *
+ * In order for the B-tree to operate correctly, the first
+ * item in the heap is the empty string, and must appear at
+ * heap offset zero.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_create(H5O_loc_t *grp_oloc, H5O_stab_t *stab, hid_t dxpl_id)
+{
+ H5O_ginfo_t ginfo; /* Group info message */
+ size_t heap_hint; /* Local heap size hint */
+ size_t size_hint; /* Local heap size hint */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_create, FAIL)
/*
- * Create symbol table object header. It has a zero link count
- * since nothing refers to it yet. The link count will be
- * incremented if the object is added to the group directed graph.
+ * Check arguments.
*/
- if (H5O_create(f, dxpl_id, 4 + 2 * H5F_SIZEOF_ADDR(f), self/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header")
+ HDassert(grp_oloc);
+ HDassert(stab);
+
+ /* Get the group info */
+ if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* Adjust the size hint, if necessary */
+ if(ginfo.lheap_size_hint == 0)
+ heap_hint = ginfo.est_num_entries * (ginfo.est_name_len + 1);
+ else
+ heap_hint = ginfo.lheap_size_hint;
+ size_hint = MAX(heap_hint, H5HL_SIZEOF_FREE(grp_oloc->file) + 2);
+
+ if(H5G_stab_create_components(grp_oloc->file, stab, size_hint, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create symbol table components")
/*
* Insert the symbol table message into the object header and the symbol
* table entry.
*/
- if (H5O_modify(self, H5O_STAB_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, &stab, dxpl_id)<0) {
- H5O_close(self);
+ if(H5O_modify(grp_oloc, H5O_STAB_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, stab, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
- }
- self->cache.stab.btree_addr = stab.btree_addr;
- self->cache.stab.heap_addr = stab.heap_addr;
- self->type = H5G_CACHED_STAB;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -114,62 +197,47 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_stab_find
- *
- * Purpose: Finds a symbol named NAME in the symbol table whose
- * description is stored in GRP_ENT in file F and returns its
- * symbol table entry through OBJ_ENT (which is optional).
+ * Function: H5G_stab_insert_real
*
- * Errors:
+ * Purpose: Insert a new symbol into a table.
+ * The name of the new symbol is NAME and its symbol
+ * table entry is OBJ_LNK.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- * Added a deep copy of the symbol table entry
+ * Programmer: Quincey Koziol
+ * koziol@uiuc.edu
+ * Nov 7 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
- H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id)
+H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name,
+ H5O_link_t *obj_lnk, hid_t dxpl_id)
{
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
- H5O_stab_t stab; /*symbol table message */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_bt_ud1_t udata; /* Data to pass through B-tree */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_stab_find, FAIL)
+ FUNC_ENTER_NOAPI(H5G_stab_insert_real, FAIL)
- /* Check arguments */
- assert(grp_ent);
- assert(grp_ent->file);
- assert(obj_ent);
- assert(name && *name);
+ /* check arguments */
+ HDassert(f);
+ HDassert(stab);
+ HDassert(name && *name);
+ HDassert(obj_lnk);
- /* set up the udata */
- if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
+ /* Initialize data to pass through B-tree */
udata.common.name = name;
- udata.common.heap_addr = stab.heap_addr;
- udata.ent = obj_ent;
-
- /* search the B-tree */
- if (H5B_find(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
+ udata.common.heap_addr = stab->heap_addr;
+ udata.lnk = obj_lnk;
- /* Set the name for the symbol entry OBJ_ENT */
- if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
+ /* Insert into symbol table */
+ if(H5B_insert(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_stab_find() */
+} /* end H5G_stab_insert_real() */
/*-------------------------------------------------------------------------
@@ -188,46 +256,29 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent,
- hbool_t inc_link, hid_t dxpl_id)
+H5G_stab_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
+ hid_t dxpl_id)
{
- H5O_stab_t stab; /*symbol table message */
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5O_stab_t stab; /* Symbol table message */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_insert, FAIL)
/* check arguments */
- assert(grp_ent && grp_ent->file);
- assert(name && *name);
- assert(obj_ent && obj_ent->file);
- if (grp_ent->file->shared != obj_ent->file->shared)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed")
-
- /* Set the name for the symbol entry OBJ_ENT */
- if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+ HDassert(obj_lnk);
- /* initialize data to pass through B-tree */
- if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+ /* Retrieve symbol table message */
+ if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
- udata.common.name = name;
- udata.common.heap_addr = stab.heap_addr;
- udata.ent = obj_ent;
-
- /* insert */
- if (H5B_insert(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
-
- /* Increment link count on object, if appropriate */
- if(inc_link)
- if (H5O_link(obj_ent, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count")
+ if(H5G_stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5B_ITER_ERROR, "unable to insert the name")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_insert() */
/*-------------------------------------------------------------------------
@@ -240,36 +291,37 @@ done:
* Programmer: Robb Matzke
* Thursday, September 17, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id)
+H5G_stab_remove(H5O_loc_t *loc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id)
{
H5O_stab_t stab; /*symbol table message */
H5G_bt_ud2_t udata; /*data to pass through B-tree */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL)
- assert(grp_ent && grp_ent->file);
- assert(name && *name);
+ HDassert(loc && loc->file);
+ HDassert(name && *name);
- /* initialize data to pass through B-tree */
- if (NULL==H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+ /* Read in symbol table message */
+ if(NULL == H5O_read(loc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+
+ /* Initialize data to pass through B-tree */
udata.common.name = name;
udata.common.heap_addr = stab.heap_addr;
udata.adj_link = TRUE;
+ udata.obj_type = obj_type;
- /* remove */
- if (H5B_remove(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
+ /* Remove from symbol table */
+ if(H5B_remove(loc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5G_stab_remove() */
/*-------------------------------------------------------------------------
@@ -318,47 +370,324 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_stab_copy_tmp
+ * Function: H5G_stab_iterate
+ *
+ * Purpose: Iterate over the objects in a group
*
- * Purpose: copy a group symbol table and memeber objects from SRC file to DST file.
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 3, 2005
*
- * Return: Non-negative on success
- * Negative on failure.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_iterate(H5O_loc_t *oloc, hid_t gid, int skip, int *last_obj,
+ H5G_iterate_t op, void *op_data, hid_t dxpl_id)
+{
+ H5G_bt_it_ud1_t udata; /* User data to pass to B-tree callback */
+ H5O_stab_t stab; /* Info about symbol table */
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5G_stab_iterate, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(H5I_GROUP == H5I_get_type(gid));
+ HDassert(last_obj);
+ HDassert(op);
+
+ /* Get the B-tree info */
+ 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")
+
+ /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
+ udata.group_id = gid;
+ udata.skip = skip;
+ udata.heap_addr = stab.heap_addr;
+ udata.op = op;
+ udata.op_data = op_data;
+ udata.final_ent = last_obj;
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, H5AC_dxpl_id, H5B_SNODE,
+ H5G_node_iterate, stab.btree_addr, &udata))<0)
+ HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_count
*
- * Programmer: Peter Cao
- * September 10, 2005
+ * Purpose: Count the # of objects in a group
*
- * Note: This routine should be replaced with proper call to "real"
- * stab creation routine after the "big group revision" checkin
- * occurs. -QAK
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 6, 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst, hid_t dxpl_id)
+H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about symbol table */
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5G_stab_count, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(num_objs);
+
+ /* Reset the number of objects in the group */
+ *num_objs = 0;
+
+ /* Get the B-tree info */
+ 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")
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs)) < 0)
+ HERROR(H5E_SYM, H5E_CANTINIT, "iteration operator failed");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_get_name_by_idx
+ *
+ * Purpose: Returns the name of objects in the group by giving index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name,
+ size_t size, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about local heap & B-tree */
+ H5G_bt_it_ud2_t udata; /* Iteration information */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_get_name_by_idx, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Get the B-tree & local heap info */
+ 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")
+
+ /* Set iteration information */
+ udata.idx = idx;
+ udata.num_objs = 0;
+ udata.heap_addr = stab.heap_addr;
+ udata.name = NULL;
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_name, stab.btree_addr, &udata))<0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
+
+ /* If we don't know the name now, we almost certainly went out of bounds */
+ if(udata.name==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound")
+
+ /* Get the length of the name */
+ ret_value = (ssize_t)HDstrlen(udata.name);
+
+ /* Copy the name into the user's buffer, if given */
+ if(name) {
+ HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size));
+ if((size_t)ret_value >= size)
+ name[size-1]='\0';
+ } /* end if */
+
+done:
+ /* Free the duplicated name */
+ if(udata.name!=NULL)
+ H5MM_xfree(udata.name);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_get_name_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_get_objtype_by_idx
+ *
+ * Purpose: Private function for H5Gget_objtype_by_idx.
+ * Returns the type of objects in the group by giving index.
+ *
+ * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3)
+ *
+ * Failure: UNKNOWN
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about local heap & B-tree */
+ H5G_bt_it_ud3_t udata; /* User data for B-tree callback */
+ H5G_obj_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_get_type_by_idx, H5G_UNKNOWN)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Get the B-tree & local heap info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to determine local heap address")
+
+ /* Set iteration information */
+ udata.idx = idx;
+ udata.num_objs = 0;
+ udata.type = H5G_UNKNOWN;
+
+ /* Iterate over the group members */
+ if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_type, stab.btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed")
+
+ /* If we don't know the type now, we almost certainly went out of bounds */
+ if(udata.type == H5G_UNKNOWN)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
+
+ /* Set the return value */
+ ret_value = udata.type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_get_type_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_lookup_cb
+ *
+ * Purpose: B-tree 'find' callback to retrieve location for an object
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 20, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata)
{
- size_t size_init, name_offset;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5G_stab_fnd_ud2_t *udata = (H5G_stab_fnd_ud2_t *)_udata; /* 'User data' passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_cb)
+
+ /* Set link info */
+ if(udata->lnk) {
+ /* Set (default) common info for link */
+ udata->lnk->cset = H5T_CSET_ASCII;
+ udata->lnk->ctime = 0;
+ udata->lnk->name = H5MM_xstrdup(udata->name);
+
+ /* Object is a symbolic link */
+ if(H5G_CACHED_SLINK == ent->type) {
+ const char *s; /* Pointer to link value */
+ const H5HL_t *heap; /* Pointer to local heap for group */
+
+ /* Lock the local heap */
+ if(NULL == (heap = H5HL_protect(udata->file, udata->dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
- FUNC_ENTER_NOAPI(H5G_stab_copy_tmp, FAIL)
+ s = H5HL_offset_into(udata->file, heap, ent->cache.slink.lval_offset);
- HDassert(f_dst);
- HDassert(stab_dst);
+ /* Copy the link value */
+ udata->lnk->u.soft.name = H5MM_xstrdup(s);
- /* create B-tree private heap */
- size_init = MAX(H5G_SIZE_HINT, H5HL_SIZEOF_FREE(f_dst) + 2);
- if (H5HL_create(f_dst, dxpl_id, size_init, &(stab_dst->heap_addr))<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
+ /* Release the local heap */
+ if(H5HL_unprotect(udata->file, udata->dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
- name_offset = H5HL_insert(f_dst, dxpl_id, stab_dst->heap_addr, 1, "");
- if ((size_t)(-1)==name_offset)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
- assert(0 == name_offset);
-
- /* create the B-tree */
- if (H5B_create(f_dst, dxpl_id, H5B_SNODE, NULL, &(stab_dst->btree_addr)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
+ /* Set link type */
+ udata->lnk->type = H5G_LINK_SOFT;
+ } /* end if */
+ else {
+ /* Set address of object */
+ udata->lnk->u.hard.addr = ent->header;
+
+ /* Set link type */
+ udata->lnk->type = H5G_LINK_HARD;
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_lookup_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_lookup
+ *
+ * Purpose: Look up an object relative to a group, using symbol table
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
+ hid_t dxpl_id)
+{
+ H5G_bt_ud3_t bt_udata; /* Data to pass through B-tree */
+ H5G_stab_fnd_ud2_t udata; /* 'User data' to give to callback */
+ H5O_stab_t stab; /* Symbol table message */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_lookup, FAIL)
+
+ /* check arguments */
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+ HDassert(lnk);
+
+ /* Set up user data to pass to 'find' operation callback */
+ udata.file = grp_oloc->file;
+ udata.dxpl_id = dxpl_id;
+ udata.name = name;
+ udata.lnk = lnk;
+
+ /* Set up the user data for actual B-tree find operation */
+ if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
+ bt_udata.common.name = name;
+ bt_udata.common.heap_addr = stab.heap_addr;
+ bt_udata.op = H5G_stab_lookup_cb;
+ bt_udata.op_data = &udata;
+
+ /* Finish up user data to pass to 'find' operation callback */
+ udata.heap_addr = stab.heap_addr;
+
+ /* Search the B-tree */
+ if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_stab_copy_tmp() */
+} /* end H5G_stab_lookup() */
+