summaryrefslogtreecommitdiffstats
path: root/src/H5G.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5G.c')
-rw-r--r--src/H5G.c643
1 files changed, 585 insertions, 58 deletions
diff --git a/src/H5G.c b/src/H5G.c
index 458792b..45aada7 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -49,15 +49,570 @@ static intn interface_initialize_g = FALSE;
/*-------------------------------------------------------------------------
+ * Function: H5G_component
+ *
+ * Purpose: Returns the pointer to the first component of the
+ * specified name by skipping leading slashes. Returns
+ * the size in characters of the component through SIZE_P not
+ * counting leading slashes or the null terminator.
+ *
+ * Return: Success: Ptr into NAME.
+ *
+ * Failure: Ptr to the null terminator of NAME.
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static const char *
+H5G_component (const char *name, size_t *size_p)
+{
+ assert (name);
+
+ while ('/'==*name) name++;
+ if (size_p) *size_p = strcspn (name, "/");
+ return name;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_basename
+ *
+ * Purpose: Returns a pointer into NAME for the start of the last
+ * component of NAME. On return, the optional SIZE_P is
+ * initialized to point to the size of the base name not
+ * counting trailing slashes or the null character.
+ *
+ * Return: Success: Ptr to base name within NAME with SIZE_P
+ * pointing to the number of characters in the
+ * base name.
+ *
+ * Failure: Ptr to the null terminator of NAME.
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static const char *
+H5G_basename (const char *name, size_t *size_p)
+{
+ const char *s;
+
+ assert (name);
+
+ s = name + strlen(name);
+ while (s>name && '/'==s[-1]) --s; /*skip past trailing slashes*/
+ while (s>name && '/'!=s[-1]) --s; /*skip past base name*/
+
+ /*
+ * If the input was the name of the root directory `/' (or
+ * equivalent) then return the null string.
+ */
+ if ('/'==*s) {
+ if (size_p) *size_p = 0;
+ return s + strlen(s); /*null terminator*/
+ }
+
+ if (size_p) *size_p = strcspn (s, "/");
+ return s;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_namei
+ *
+ * Purpose: Given a name (absolute or relative) return the symbol table
+ * entry for that name and for the directory that contains the
+ * base name. These entries (DIR_ENT and BASE_ENT) are returned
+ * through memory passed into the function by the caller. Either
+ * or both pointers may be null. Absolute names are looked up
+ * relative to the root directory of file F while relative
+ * names are traversed beginning at the CWD argument.
+ *
+ * Consecutive slash characters are treated like single
+ * slash characters. Trailing slashes are ignored. The
+ * component `.' is recognized as the current directory
+ * during the traversal (initially CWD), but the component
+ * `..' is not internally recognized (it is recognized if
+ * such a name appears in the symbol table).
+ *
+ * As a special case, if the NAME is the string `/' (or
+ * equivalent) then DIR_ENT and BASE_ENT are both initialized
+ * to the contents of the root symbol table entry. However,
+ * the contents of the root symbol table entry may be
+ * uninitialized.
+ *
+ * If the name cannot be fully resolved, then REST will
+ * point to the part of NAME where the traversal failed
+ * (REST will always point to a relative name) and BASE_ENT
+ * will not be initialized. DIR_ENT will be initialized with
+ * information about the directory (or other object) at which
+ * the traversal failed. However, if the name can be fully
+ * resolved, then REST points to the null terminator of NAME.
+ *
+ * Return: Success: SUCCEED if the name can be fully
+ * resolved.
+ *
+ * Failure: FAIL if something bad happened (REST and
+ * DIR_ENT have undefined values).
+ *
+ * -2 if the name could not be fully resolved
+ * (REST and DIR_ENT are initialized).
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_namei (hdf5_file_t *f, H5G_entry_t *cwd, const char *name,
+ const char **rest, H5G_entry_t *dir_ent, H5G_entry_t *base_ent)
+{
+ H5G_entry_t ent[2];
+ H5G_entry_t *tmp, *dir, *base; /*ptrs to DIR and BASE entries */
+ size_t nchars; /*component name length */
+ char comp[1024]; /*component name buffer */
+
+ FUNC_ENTER (H5G_namei, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (f->root_sym);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
+
+ /* starting point */
+ dir = ent+0;
+ base = ent+1;
+ if ('/'==*name) {
+ ent[0] = ent[1] = *(f->root_sym);
+ } else {
+ ent[0] = ent[1] = *cwd;
+ }
+
+ /* traverse the name */
+ while ((name=H5G_component (name, &nchars)) && *name) {
+
+ /*
+ * The special name `.'.
+ */
+ if ('.'==name[0] && !name[1]) continue;
+
+ /*
+ * Advance.
+ */
+ tmp=dir; dir=base; base=tmp; /*swap*/
+ if (rest) *rest = name;
+
+ /*
+ * Copy the component name into a null-terminated buffer so
+ * we can pass it down to the other symbol table functions.
+ */
+ if (nchars+1 > sizeof(comp)) {
+ /* component name is too long */
+ if (dir_ent) *dir_ent = *dir;
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, -2);
+ }
+ HDmemcpy (comp, name, nchars);
+ comp[nchars] = '\0';
+
+ /*
+ * Look for the component in the current symbol table.
+ */
+ if (H5G_stab_find (f, dir, comp, base)<0) {
+ /* component not found */
+ if (dir_ent) *dir_ent = *dir;
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, -2);
+ }
+
+ /* next component */
+ name += nchars;
+ }
+
+ /* output parameters */
+ if (rest) *rest = name; /*final null*/
+ if (dir_ent) *dir_ent = *dir;
+ if (base_ent) *base_ent = *base;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_mkroot
+ *
+ * Purpose: Creates the root directory if it doesn't exist; otherwise
+ * nothing happens. If the root symbol table previously
+ * pointed to something other than a directory, then that
+ * object is made a member of the root directory and is
+ * given a name corresponding to the object name message.
+ * If the root object doesn't have an object name message
+ * then the name `Root Object' is used.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_mkroot (hdf5_file_t *f, size_t size_hint)
+{
+ H5O_stab_t stab; /*symbol table message */
+ H5O_name_t name; /*object name message */
+ H5G_entry_t root; /*old root entry */
+ const char *root_name=NULL; /*name of old root object */
+
+ FUNC_ENTER (H5G_mkroot, NULL, FAIL);
+
+ /*
+ * Is there already a root object that needs to move into the new
+ * root symbol table?
+ */
+ name.s = NULL;
+ if (f->root_sym->header>0) {
+ if (H5O_read (f, f->root_sym->header, f->root_sym, H5O_STAB, 0, &stab)) {
+ /* root directory already exists */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL);
+ } else if (H5O_read (f, f->root_sym->header, f->root_sym, H5O_NAME,
+ 0, &name)) {
+ root = *(f->root_sym);
+ root_name = name.s; /*dont reset name until root_name is done*/
+ } else {
+ root = *(f->root_sym);
+ root_name = "Root Object";
+ }
+ }
+
+ /*
+ * Create the root directory.
+ */
+ if (H5G_stab_new (f, f->root_sym, size_hint)<0) {
+ H5O_reset (H5O_NAME, &name);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't create dir*/
+ }
+
+ /*
+ * Insert the old root object.
+ */
+ if (root_name) {
+ if (H5G_stab_insert (f, f->root_sym, root_name, &root)) {
+ /* can't insert old root object in new root directory */
+ H5O_reset (H5O_NAME, &name);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ }
+ H5O_reset (H5O_NAME, &name);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_new
+ *
+ * Purpose: Creates a new empty directory with the specified name. The
+ * name is either an absolute name or is relative to the
+ * directory whose symbol table entry is CWD. On return, the
+ * optional DIR_ENT pointer is initialized with the symbol
+ * table entry for the new directory's parent and ENT will
+ * contain the symbol table entry for the new directory.
+ *
+ * Do not use this function to create the root symbol table
+ * since it is a special case. Use H5G_mkroot() instead.
+ * Creating `/' with this function will return failure.
+ *
+ * Return: Success: SUCCEED, if DIR_ENT is not the null pointer
+ * then it will be initialized with the
+ * symbol table entry for the new directory.
+ *
+ * Failure: FAIL, the memory pointed to by CWD is
+ * not modified.
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_new (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
+ const char *name, size_t size_hint, H5G_entry_t *ent)
+{
+ const char *rest=NULL;
+ H5G_entry_t _parent, _child;
+ herr_t status;
+ char _comp[1024];
+ size_t nchars;
+
+ FUNC_ENTER (H5G_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
+ if (!dir_ent) dir_ent = &_parent;
+ if (!ent) ent = &_child;
+
+ /* lookup name */
+ status = H5G_namei (f, cwd, name, &rest, dir_ent, NULL);
+ if (status<0 && !rest) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*lookup failed*/
+ } else if (0==status) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL); /*already exists*/
+ }
+ H5ECLEAR; /*it's OK that we didn't find it*/
+
+ /* should be one null-terminated component left */
+ rest = H5G_component (rest, &nchars);
+ assert (rest && *rest);
+ if (rest[nchars]) {
+ if (H5G_component (rest+nchars, NULL)) {
+ /* missing component */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL);
+ } else if (nchars+1 > sizeof _comp) {
+ /* component name is too long */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, FAIL);
+ } else {
+ /* null terminate */
+ memcpy (_comp, rest, nchars);
+ _comp[nchars] = '\0';
+ rest = _comp;
+ }
+ }
+
+ /* create directory */
+ if (H5G_stab_new (f, ent, size_hint)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't create dir*/
+ }
+
+ /* insert child name into parent */
+ if (H5G_stab_insert (f, dir_ent, rest, ent)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't insert*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_find
+ *
+ * Purpose: Finds an object with the specified NAME in file F. If the
+ * name is relative then it is interpretted relative to CWD,
+ * a symbol table entry for a symbol table. On successful return,
+ * DIR_ENT (if non-null) will be initialized with the symbol table
+ * information for the directory in which the object appears
+ * and ENT will be initialized with the symbol table entry for
+ * the object.
+ *
+ * ENT is optional when the caller is interested only in the
+ * existence of the object.
+ *
+ * Return: Success: SUCCEED with DIR_ENT and ENT initialized.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 12 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_find (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
+ const char *name, H5G_entry_t *ent)
+{
+ FUNC_ENTER (H5G_find, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
+
+ if (H5G_namei (f, cwd, name, NULL, dir_ent, ent)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_insert
+ *
+ * Purpose: Inserts symbol table ENT into the directory hierarchy
+ * giving it the specified NAME. If NAME is relative then
+ * it is interpreted with respect to the CWD pointer. If
+ * non-null, DIR_ENT will be initialized with the symbol table
+ * entry for the directory which contains the new ENT.
+ *
+ * NAME must not be the name of the root symbol table entry
+ * ('/') since that is a special case. If NAME is the root
+ * symbol table entry, then this function will return failure.
+ *
+ * Return: Success: SUCCEED with optional DIR_ENT initialized with
+ * the symbol table entry for the directory
+ * which contains the new ENT.
+ *
+ * Failure: FAIL (DIR_ENT is not modified).
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_insert (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
+ const char *name, H5G_entry_t *ent)
+{
+ herr_t status;
+ const char *rest=NULL;
+ H5G_entry_t _parent;
+ size_t nchars;
+ char _comp[1024];
+
+ FUNC_ENTER (H5G_insert, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
+ assert (ent);
+ if (!dir_ent) dir_ent = &_parent;
+
+ /* lookup name */
+ status = H5G_namei (f, cwd, name, &rest, dir_ent, NULL);
+ if (status<0 && !rest) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*lookup failed*/
+ } else if (0==status) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL); /*already exists*/
+ }
+ H5ECLEAR; /*it's OK that we didn't find it*/
+
+ /* should be one null-terminated component left */
+ rest = H5G_component (rest, &nchars);
+ assert (rest && *rest);
+ if (rest[nchars]) {
+ if (H5G_component (rest+nchars, NULL)) {
+ /* missing component */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL);
+ } else if (nchars+1 > sizeof _comp) {
+ /* component name is too long */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, FAIL);
+ } else {
+ /* null terminate */
+ memcpy (_comp, rest, nchars);
+ _comp[nchars] = '\0';
+ rest = _comp;
+ }
+ }
+
+ /* insert entry into parent */
+ if (H5G_stab_insert (f, dir_ent, rest, ent)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't insert*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_modify
+ *
+ * Purpose: Modifies the symbol table entry for the object with the
+ * specified NAME by copying the new symbol table entry ENT
+ * over the top of the old one. If NAME is relative then it
+ * is interpreted with respect to the CWD pointer. If non-null,
+ * DIR_ENT will be initialized with the symbol table entry for the
+ * directory which contains the new ENT.
+ *
+ * Do not use this function to change the entry for the root
+ * symbol since that's a special case. This function returns
+ * failure if that is attempted.
+ *
+ * Return: Success: SUCCEED with optional DIR_ENT initialized with
+ * the symbol table entry for the directory
+ * which contains the new ENT.
+ *
+ * Failure: FAIL (DIR_ENT is not modified).
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 11 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_modify (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
+ const char *name, H5G_entry_t *ent)
+{
+ const char *rest=NULL;
+ H5G_entry_t _parent;
+ size_t nchars;
+
+ FUNC_ENTER (H5G_modify, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
+ assert (ent);
+ if (!dir_ent) dir_ent = &_parent;
+
+ /* lookup name */
+ if (H5G_namei (f, cwd, name, &rest, dir_ent, NULL)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*entry not found*/
+ }
+
+ /* get the base name */
+ rest = H5G_basename (name, &nchars);
+
+ /* cannot modify the root symbol entry */
+ if (!*rest) HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL);
+
+ /* modify entry in parent */
+ if (H5G_stab_modify (f, dir_ent, rest, ent)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't modify*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_stab_new
*
* 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. If no size is specified then a default heap is
- * created when the first symbol is added to the table.
- *
- * The B-tree is created when the first symbol is added to
- * the table.
+ * 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
@@ -91,40 +646,39 @@ H5G_stab_new (hdf5_file_t *f, H5G_entry_t *self, size_t init)
* Check arguments.
*/
assert (f);
+ init = MAX(init, H5H_SIZEOF_FREE(f)+2);
/* Create symbol table private heap */
- if (init>0) {
- if ((stab.heap = H5H_new (f, H5H_LOCAL, init))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- if ((name = H5H_insert (f, stab.heap, 1, "")<0)) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- if (0!=name) {
- /*
- * B-tree's won't work if the first name isn't at the beginning
- * of the heap.
- */
- HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
- }
- } else {
- stab.heap = 0; /*we'll create it later*/
+ if ((stab.heap = H5H_new (f, H5H_LOCAL, init))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if ((name = H5H_insert (f, stab.heap, 1, "")<0)) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if (0!=name) {
+ /*
+ * B-tree's won't work if the first name isn't at the beginning
+ * of the heap.
+ */
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
}
- /* The B-tree is created on demand later */
- stab.btree = 0;
+ /* Create the B-tree */
+ if ((stab.btree = H5B_new (f, H5B_SNODE))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
/* Create symbol table object header with a single link */
if ((addr = H5O_new (f, 1, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
+
+ /* insert the symbol table message */
if (self) {
self->name_off = 0;
self->header = addr;
self->type = H5G_NOTHING_CACHED;
}
-
- /* insert the symbol table message */
if (H5O_modify(f, addr, self, NULL, H5O_STAB, H5O_NEW_MESG, &stab)<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
@@ -165,15 +719,11 @@ H5G_stab_find (hdf5_file_t *f, H5G_entry_t *self, const char *name,
assert (f);
assert (self && self->header>=0);
assert (name && *name);
- assert (ent);
/* set up the udata */
if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
}
- if (stab.btree<=0 || stab.heap<=0) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*empty symbol table*/
- }
udata.operation = H5G_OPER_FIND;
udata.name = name;
udata.heap = stab.heap;
@@ -228,9 +778,6 @@ H5G_stab_modify (hdf5_file_t *f, H5G_entry_t *self, const char *name,
if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
}
- if (stab.btree<=0 || stab.heap<=0) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*empty symbol table*/
- }
udata.operation = H5G_OPER_MODIFY;
udata.name = name;
udata.heap = stab.heap;
@@ -270,7 +817,6 @@ H5G_stab_insert (hdf5_file_t *f, H5G_entry_t *self, const char *name,
{
H5O_stab_t stab; /*symbol table message */
H5G_node_ud1_t udata; /*data to pass through B-tree */
- off_t offset; /*offset of name within heap */
FUNC_ENTER (H5G_stab_insert, NULL, FAIL);
@@ -280,34 +826,15 @@ H5G_stab_insert (hdf5_file_t *f, H5G_entry_t *self, const char *name,
assert (name && *name);
assert (ent);
- /* make sure we have a B-tree and a heap */
+ /* initialize data to pass through B-tree */
if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
}
- if (stab.btree<=0 || stab.heap<=0) {
- if (stab.btree<=0 &&
- (stab.btree = H5B_new (f, H5B_SNODE))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- if (stab.heap<=0) {
- stab.heap = H5H_new (f, H5H_LOCAL,
- MAX(strlen(name)+1, H5G_INIT_HEAP));
- if (stab.heap<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- if (0!=(offset = H5H_insert (f, stab.heap, 1, ""))) {
- HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
- }
- }
- if (H5O_modify (f, self->header, self, NULL, H5O_STAB, 0, &stab)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
- }
-
- /* initialize data to pass through B-tree */
udata.name = name;
udata.heap = stab.heap;
udata.entry = *ent;
+
+ /* insert */
if (H5B_insert (f, H5B_SNODE, stab.btree, &udata)<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
}
@@ -358,18 +885,18 @@ H5G_stab_list (hdf5_file_t *f, H5G_entry_t *self, intn maxentries,
assert (self && self->header>=0);
assert (maxentries>=0);
+ /* initialize data to pass through B-tree */
if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
}
- if (stab.btree<=0 || stab.heap<=0) HRETURN (0); /*empty directory*/
-
udata.entry = entries;
udata.name = names;
udata.heap = stab.heap;
udata.maxentries = maxentries;
udata.nsyms = 0;
-
if (names) HDmemset (names, 0, maxentries);
+
+ /* list */
if (H5B_list (f, H5B_SNODE, stab.btree, &udata)<0) {
if (names) {
for (i=0; i<maxentries; i++) H5MM_xfree (names[i]);