summaryrefslogtreecommitdiffstats
path: root/src/H5G.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5G.c')
-rw-r--r--src/H5G.c1126
1 files changed, 301 insertions, 825 deletions
diff --git a/src/H5G.c b/src/H5G.c
index 88c8576..0c38a00 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -47,11 +47,10 @@
#define H5G_INIT_HEAP 8192
#define PABLO_MASK H5G_mask
-static herr_t H5G_mkroot (hdf5_file_t *f, size_t size_hint);
-
/* Is the interface initialized? */
static hbool_t interface_initialize_g = FALSE;
+
/*-------------------------------------------------------------------------
* Function: H5G_component
@@ -315,6 +314,8 @@ H5G_namei (hdf5_file_t *f, H5G_entry_t *cwd, const char *name,
* is removed). If the root object doesn't have a name message
* then the name `Root Object' is used.
*
+ * Warning: This function has a few subtleties. Be warned!
+ *
* Errors:
* DIRECTORY CANTINIT Can't create root.
* DIRECTORY CANTINIT Can't insert old root object in
@@ -323,7 +324,9 @@ H5G_namei (hdf5_file_t *f, H5G_entry_t *cwd, const char *name,
*
* Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL. This function returns -2 if the
+ * failure is because a root directory already
+ * exists.
*
* Programmer: Robb Matzke
* robb@maya.nuance.com
@@ -336,104 +339,103 @@ H5G_namei (hdf5_file_t *f, H5G_entry_t *cwd, const char *name,
static herr_t
H5G_mkroot (hdf5_file_t *f, size_t size_hint)
{
+ H5G_entry_t *handle=NULL; /*handle to open object */
+ herr_t ret_value=FAIL; /*return value */
+ H5O_name_t name={NULL}; /*object name */
H5O_stab_t stab; /*symbol table message */
- H5O_name_t name={0}; /*object name message */
- H5G_entry_t root; /*old root entry */
- const char *root_name=NULL; /*name of old root object */
- intn nlinks; /*number of links */
- H5G_entry_t *handle; /*handle for open object */
+ H5G_entry_t *ent_ptr=NULL; /*pointer to a symbol table entry*/
+ const char *obj_name=NULL; /*name of old root object */
FUNC_ENTER (H5G_mkroot, NULL, FAIL);
/*
- * Make sure we have the latest info since someone might have the root
- * object open for modifications.
+ * Make sure that the file descriptor has the latest info -- someone might
+ * have the root object open.
*/
H5G_shadow_sync (f->root_sym);
/*
- * Is there already a root object that needs to move into the new
- * root symbol table? The root object is a symbol table if we can
- * read the H5O_STAB message.
+ * If we already have a root object, then open it and get it's name. The
+ * root object had better not already be a directory. Once the old root
+ * object is opened and we have a HANDLE, set the dirty bit on the handle.
+ * This causes the handle data to be written back into f->root_sym by
+ * H5G_close() if something goes wrong before the old root object is
+ * re-inserted back into the directory hierarchy. We might leak file
+ * memory, but at least we don't loose the original root object.
*/
if (f->root_sym->header>0) {
if (H5O_read (f, NO_ADDR, 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_name = name.s; /*dont reset name until root_name is done!*/
- root = *(f->root_sym);
-
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_EXISTS, -2);
+ } else if (NULL==(handle=H5G_shadow_open (f, NULL, f->root_sym))) {
+ /* can't open root object */
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ } else if (NULL==H5O_read (f, NO_ADDR, handle, H5O_NAME, 0, &name)) {
+ obj_name = "Root Object";
} else {
- root = *(f->root_sym);
- root_name = "Root Object";
+ obj_name = name.s; /*don't reset message until the end!*/
}
+ handle->dirty = TRUE;
}
/*
- * Create the root directory.
+ * Create the new root directory directly into the file descriptor. If
+ * something goes wrong at this step, closing the `handle' will rewrite
+ * info back into f->root_sym because we set the dirty bit.
*/
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 root*/
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*cant create root*/
+ }
+ if (1!=H5O_link (f, f->root_sym, 1)) {
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
}
/*
- * Increase the link count for the root symbol table!
- */
- nlinks = H5O_link (f, f->root_sym->header, f->root_sym, 1);
- assert (1==nlinks);
-
- /*
- * Insert the old root object. It should already have a link count
- * of 1.
+ * If there was a previous root object then insert it into the new root
+ * symbol table with the specified name. Inserting the object will update
+ * the handle to point to the new symbol table slot instead of f->root_sym.
*/
- if (root_name) {
-
-#ifndef NDEBUG
- nlinks = H5O_link (f, root.header, &root, 0);
- assert (1==nlinks);
-#endif
- if (H5G_stab_insert (f, f->root_sym, root_name, &root)<0) {
- /*
- * This should never happen. If it does and the root object is
- * open, then bad things are going to happen because we've just
- * deleted the symbol table entry for the open root object!
- */
-#ifndef NDEBUG
- abort ();
-#endif
-
- /* can't insert old root object in new root directory */
- H5O_reset (H5O_NAME, &name);
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ if (obj_name) {
+ if (1!=H5O_link (f, handle, 0)) {
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
}
-
- /* remove all name messages -- don't care if it fails */
- if ((handle = H5G_open (f, f->root_sym, root_name))) {
- H5O_remove (f, NO_ADDR, handle, H5O_NAME, H5O_ALL);
- H5G_shadow_close (f, handle);
- handle = NULL;
+ if (NULL==(ent_ptr=H5G_stab_insert (f, f->root_sym, obj_name,
+ handle))) {
+ HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
}
- H5ECLEAR;
+
+ /*
+ * Remove all `name' messages from the old root object. The only time
+ * a name message should ever appear is to give the root object a name,
+ * but the old root object is no longer the root object.
+ */
+ H5O_remove (f, NO_ADDR, handle, H5O_NAME, H5O_ALL);
+ H5ECLEAR; /*who really cares?*/
}
-
+
+ ret_value = SUCCEED;
+
+ done:
+ /*
+ * If the handle is closed before the H5G_stab_insert() call that
+ * reinserts the root object into the directory hierarchy, then
+ * H5G_close() will reset f->root_sym to point to the old root symbol and
+ * the new root directory (if it was created) will be unlinked from the
+ * directory hierarchy (and memory leaked).
+ */
+ if (handle) H5G_close (f, handle);
H5O_reset (H5O_NAME, &name);
- FUNC_LEAVE (SUCCEED);
+
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5G_new
+ * Function: H5G_mkdir
*
- * 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.
+ * Purpose: Creates a new empty directory with the specified name,
+ * opening it as an object. The name is either an absolute name
+ * or is relative to the current working directory.
*
* A root directory is created implicitly by this function
* when necessary. Calling this function with the name "/"
@@ -448,12 +450,10 @@ H5G_mkroot (hdf5_file_t *f, size_t size_hint)
* DIRECTORY EXISTS Already exists.
* DIRECTORY NOTFOUND Missing component.
*
- * 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.
+ * Return: Success: A handle to the open directory. Please call
+ * H5G_close() when you're done with it.
*
- * Failure: FAIL, the memory pointed to by CWD is
- * not modified.
+ * Failure: NULL
*
* Programmer: Robb Matzke
* robb@maya.nuance.com
@@ -463,31 +463,43 @@ H5G_mkroot (hdf5_file_t *f, size_t size_hint)
*
*-------------------------------------------------------------------------
*/
-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)
+H5G_entry_t *
+H5G_mkdir (hdf5_file_t *f, const char *name, size_t size_hint)
{
- const char *rest=NULL;
- H5G_entry_t _parent, _child;
- char _comp[1024];
- size_t nchars;
+ const char *rest=NULL; /*the base name */
+ H5G_entry_t *cwd=NULL; /*current working directory */
+ H5G_entry_t dir_ent; /*directory containing new dir */
+ H5G_entry_t ent; /*new directory entry */
+ H5G_entry_t *ent_ptr=NULL; /*ptr to new directory entry */
+ H5G_entry_t *ret_value=NULL; /*handle return value */
+ char _comp[1024]; /*name component */
+ size_t nchars; /*number of characters in compon*/
+ herr_t status; /*function return status */
- FUNC_ENTER (H5G_new, NULL, FAIL);
+ FUNC_ENTER (H5G_mkdir, NULL, NULL);
/* check args */
assert (f);
assert (name && *name);
+#ifndef LATER
+ /* Get current working directory */
+ H5G_shadow_sync (f->root_sym);
+ cwd = f->root_sym;
+#endif
assert (cwd || '/'==*name);
- if (!dir_ent) dir_ent = &_parent;
- if (!ent) ent = &_child;
- /* Create root directory if necessary */
- H5G_mkroot (f, H5G_SIZE_HINT);
+ /*
+ * Try to create the root directory. Ignore the error if this function
+ * fails because the root directory already exists.
+ */
+ if ((status=H5G_mkroot (f, H5G_SIZE_HINT))<0 && -2!=status) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ }
H5ECLEAR;
/* lookup name */
- if (H5G_namei (f, cwd, name, &rest, dir_ent)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL); /*already exists*/
+ if (H5G_namei (f, cwd, name, &rest, &dir_ent)) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
@@ -497,10 +509,10 @@ H5G_new (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* missing component */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, FAIL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -510,266 +522,165 @@ H5G_new (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
}
/* create directory */
- if (H5G_stab_new (f, ent, size_hint)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't create dir*/
+ if (H5G_stab_new (f, &ent, size_hint)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*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*/
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &dir_ent, rest, &ent))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
}
- FUNC_LEAVE (SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_open
- *
- * Purpose: Opens an object. That is, it prepares the object for
- * modification by returning a handle to the object
- * symbol table entry. Opening an object twice with the
- * same name (or more precisely, through the same final
- * symbol table entry) will return pointers to the same
- * H5G_entry_t struct. But opening an object through
- * different final H5G_entry_t structs (which implies
- * different names) returns pointers to different
- * structs. The structs that are returned should be
- * released by calling H5G_close().
- *
- * Return: Success: Ptr to a handle for the object.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Wednesday, September 17, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-H5G_entry_t *
-H5G_open (hdf5_file_t *f, H5G_entry_t *cwd, const char *name)
-{
- H5G_entry_t *ent=NULL;
- H5G_entry_t *handle=NULL;
- H5G_entry_t dir;
-
- FUNC_ENTER (H5G_open, NULL, NULL);
-
- /* check args */
- assert (f);
- assert (name && *name);
- assert (cwd || '/'==*name);
-
- if (f->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
- }
-
- if (NULL==(ent=H5G_namei (f, cwd, name, NULL, &dir))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
- }
-
- if (NULL==(handle=H5G_shadow_open (f, &dir, ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTOPENOBJ, NULL);
+ /* open the directory */
+ if (NULL==(ret_value=H5G_shadow_open (f, &dir_ent, ent_ptr))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open*/
}
- FUNC_LEAVE (handle);
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5G_close
+ * Function: H5G_pushd
*
- * Purpose: Closes an object that was open for modification.
+ * Purpose: Pushes a new current working directory onto the stack.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Thursday, September 18, 1997
+ * Friday, September 19, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_close (hdf5_file_t *f, H5G_entry_t *ent)
+H5G_pushd (hdf5_file_t *f, const char *name)
{
- FUNC_ENTER (H5G_close, NULL, FAIL);
+ FUNC_ENTER (H5G_pushd, NULL, FAIL);
- if (H5G_shadow_close (f, ent)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTFLUSH, FAIL);
+#ifndef LATER
+ /*
+ * Current working directories are not implemented yet.
+ */
+ if (strcmp (name, "/")) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
}
+#endif
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 (or all zero if
- * the returned object is the root object) 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).
+ * Function: H5G_popd
*
- * This function will fail if the root object is
- * requested and there is none.
- *
- * Errors:
- * DIRECTORY NOTFOUND Object not found.
+ * Purpose: Pops the top current working directory off the stack.
*
- * Return: Success: SUCCEED with DIR_ENT and ENT initialized. ENT
- * is intended for immediate read-only access.
- * If the object that ENT refers to is open
- * through the ENT entry (see H5G_open()) then
- * the returned ENT will contain the latest
- * information. However, subsequent changes to
- * the symbol table entry will not be reflected
- * in ENT since it is a copy of the symbol table.
+ * Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
- * Aug 12 1997
+ * Friday, September 19, 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)
+H5G_popd (hdf5_file_t *f)
{
- H5G_entry_t *ent_p = NULL;
- FUNC_ENTER (H5G_find, NULL, FAIL);
-
- /* check args */
- assert (f);
- assert (name && *name);
- assert (cwd || '/'==*name);
-
- if (f->root_sym->header<=0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
- }
+ FUNC_ENTER (H5G_popd, NULL, FAIL);
- if (NULL==(ent_p=H5G_namei (f, cwd, name, NULL, dir_ent))) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
- }
+#ifndef LATER
+ /* CWD is not implemented yet. */
+#endif
- if (ent) *ent = *ent_p;
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 (or all
- * zero if the new ENT is the root object).
- *
- * This function attempts to use a non-directory file if
- * the file contains just one object. The one object
- * will be the root object.
- *
- * Inserting an object entry into the symbol table increments
- * the link counter for that object.
+ * Function: H5G_create
*
- * Errors:
- * DIRECTORY CANTINIT Can't insert.
- * DIRECTORY CANTINIT Cannot add/change name message.
- * DIRECTORY CANTINIT Lookup failed.
- * DIRECTORY COMPLEN Component is too long.
- * DIRECTORY EXISTS Already exists.
- * DIRECTORY EXISTS Root exists.
- * DIRECTORY LINK Bad link count.
- * DIRECTORY LINK Link inc failure.
- * DIRECTORY NOTFOUND Component not found.
+ * Purpose: Creates a new empty object header, gives it a name, opens
+ * the object for modification, and returns a handle to the
+ * object. The initial size of the object header can be
+ * supplied with the OHDR_HINT argument.
*
- * Return: Success: SUCCEED with optional DIR_ENT initialized with
- * the symbol table entry for the directory
- * which contains the new ENT.
+ * Return: Success: A handle for the object. Be sure to
+ * eventually close it.
*
- * Failure: FAIL (DIR_ENT is not modified).
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
- * Aug 11 1997
+ * Friday, September 19, 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)
+H5G_entry_t *
+H5G_create (hdf5_file_t *f, const char *name, size_t ohdr_hint)
{
- const char *rest=NULL;
- H5G_entry_t _parent;
- size_t nchars;
- char _comp[1024];
- H5O_stab_t stab;
+ H5G_entry_t ent; /*entry data for the new object */
+ H5G_entry_t *ent_ptr; /*ptr into symbol node for entry*/
+ H5G_entry_t *cwd=NULL; /*ptr to CWD handle */
+ const char *rest = NULL; /*part of name not existing yet */
+ H5G_entry_t dir; /*entry for dir to contain obj */
+ H5G_entry_t *ret_value=NULL; /*the object handle */
+ size_t nchars; /*number of characters in name */
+ char _comp[1024]; /*name component */
- FUNC_ENTER (H5G_insert, NULL, FAIL);
+ FUNC_ENTER (H5G_create, NULL, NULL);
- /* check args */
+ /* Check args. */
assert (f);
assert (name && *name);
- assert (cwd || '/'==*name);
- assert (ent);
- assert (!ent->shadow);
- if (!dir_ent) dir_ent = &_parent;
-
+ HDmemset (&ent, 0, sizeof(H5G_entry_t));
+
/*
- * If there's already an object or if this object is a directory then
- * create a root directory. The object is a directory if we can read
- * the symbol table message from its header. H5G_mkroot() fails if
- * the root object is already a directory, but we don't care.
+ * Get the current working directory.
*/
- if (f->root_sym->header>0 ||
- H5O_read (f, ent->header, ent, H5O_STAB, 0, &stab)) {
- H5G_mkroot (f, H5G_SIZE_HINT);
- H5ECLEAR;
- }
+#ifndef LATER
+ H5G_shadow_sync (f->root_sym);
+ cwd = f->root_sym;
+#endif
/*
* Look up the name -- it shouldn't exist yet.
*/
- if (H5G_namei (f, cwd, name, &rest, dir_ent)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL); /*already exists*/
+ if (H5G_namei (f, cwd, name, &rest, &dir)) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
}
H5ECLEAR; /*it's OK that we didn't find it*/
-
- /*
- * The caller may be attempting to insert a root object that either
- * doesn't have a name or we shouldn't interfere with the name
- * it already has.
- */
rest = H5G_component (rest, &nchars);
+
if (!rest || !*rest) {
+ /*
+ * The caller is attempting to insert a root object that either
+ * doesn't have a name or we shouldn't interfere with the name
+ * it already has as a message.
+ */
if (f->root_sym->header>0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, FAIL); /*root exists*/
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*root exists*/
+ }
+ if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
+ /* can't create header */
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
}
- HDmemset (dir_ent, 0, sizeof(H5G_entry_t));
- if (1!=H5O_link (f, ent->header, ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL); /*bad link count*/
+ if (1!=H5O_link (f, &ent, 1)) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
}
- *(f->root_sym) = *ent;
- HRETURN (SUCCEED);
+ *(f->root_sym) = ent;
+ if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->root_sym))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ }
+ HRETURN (ret_value);
}
/*
@@ -779,10 +690,10 @@ H5G_insert (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
if (rest[nchars]) {
if (H5G_component (rest+nchars, NULL)) {
/* component not found */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
} else if (nchars+1 > sizeof _comp) {
/* component is too long */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, FAIL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
} else {
/* null terminate */
HDmemcpy (_comp, rest, nchars);
@@ -792,654 +703,219 @@ H5G_insert (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
}
/*
- * If this is the only object then insert it as the root object. Add
- * a name messaage to the object header (or modify the first one we
- * find). We don't have to worry about it being open.
+ * Create the object header.
*/
+ if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ }
+
+
if (f->root_sym->header<=0) {
+ /*
+ * This will be the only object in the file. Insert it as the root
+ * object and add a name messaage to the object header (or modify
+ * the first one we find). Although the header exists we can guarantee
+ * that it isn't open since it has no name.
+ */
H5O_name_t name_mesg;
name_mesg.s = rest;
- if (H5O_modify (f, NO_ADDR, ent, H5O_NAME, 0, &name_mesg)<0) {
+ if (H5O_modify (f, NO_ADDR, &ent, H5O_NAME, 0, &name_mesg)<0) {
/* cannot add/change name message */
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
}
- if (1!=H5O_link (f, ent->header, ent, 1)) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL); /*bad link count*/
+ if (1!=H5O_link (f, &ent, 1)) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
}
- *(f->root_sym) = *ent;
- HRETURN (SUCCEED);
- }
-
- /* increment the link count */
- if (H5O_link (f, ent->header, ent, 1)<0) {
- HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL); /*link inc failure*/
- }
-
- /* insert entry into parent */
- if (H5G_stab_insert (f, dir_ent, rest, ent)<0) {
- H5O_link (f, ent->header, ent, -1); /*don't care if it fails*/
- HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't insert*/
- }
-
- 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.
- *
- * 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:
- * INTERNAL CANTINIT B-tree's won't work if the first
- * name isn't at the beginning of the
- * heap.
- * SYM CANTINIT Can't create B-tree.
- * SYM CANTINIT Can't create header.
- * SYM CANTINIT Can't create heap.
- * SYM CANTINIT Can't create message.
- * SYM CANTINIT Can't initialize heap.
- *
- * Return: Success: Address of new symbol table header. If
- * the caller supplies a symbol table entry
- * SELF then it will be initialized to point to
- * this symbol table.
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5G_stab_new (hdf5_file_t *f, H5G_entry_t *self, size_t init)
-{
- off_t name; /*offset of "" name */
- haddr_t addr; /*object header address */
- H5O_stab_t stab; /*symbol table message */
-
- FUNC_ENTER (H5G_stab_new, NULL, FAIL);
-
- /*
- * Check arguments.
- */
- assert (f);
- init = MAX(init, H5H_SIZEOF_FREE(f)+2);
-
- /* Create symbol table private heap */
- if ((stab.heap_addr = H5H_new (f, H5H_LOCAL, init))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create heap*/
- }
- if ((name = H5H_insert (f, stab.heap_addr, 1, "")<0)) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't initialize heap*/
- }
- if (0!=name) {
+ *(f->root_sym) = ent;
+ if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->root_sym))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ }
+ HRETURN (ret_value);
+ } else {
/*
- * B-tree's won't work if the first name isn't at the beginning
- * of the heap.
+ * Make sure the root directory exists. Ignore the failure if it's
+ * because the directory already exists.
*/
- HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
- }
-
- /* Create the B-tree */
- if ((stab.btree_addr = H5B_new (f, H5B_SNODE))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create B-tree*/
+ hbool_t update_dir = (dir.header==f->root_sym->header);
+ herr_t status = H5G_mkroot (f, H5G_SIZE_HINT);
+ if (status<0 && -2!=status) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
+ }
+ H5ECLEAR;
+ if (update_dir) dir = *(f->root_sym);
}
-
+
/*
- * 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 directory hierarchy.
+ * This is the normal case. The object is just being inserted as a normal
+ * entry into a symbol table.
*/
- if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
+ if (H5O_link (f, &ent, 1)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*link inc failure*/
}
-
- /* insert the symbol table message */
- if (self) {
- memset (self, 0, sizeof(H5G_entry_t));
- self->header = addr;
+ if (NULL==(ent_ptr=H5G_stab_insert (f, &dir, rest, &ent))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
}
- if (H5O_modify(f, addr, self, H5O_STAB, H5O_NEW_MESG, &stab)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create message*/
+ if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent_ptr))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open object*/
}
-
- FUNC_LEAVE (addr);
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5G_stab_find
- *
- * Purpose: Finds a symbol named NAME in the symbol table whose
- * description is stored in SELF in file F and returns a
- * pointer to the symbol table entry. SELF is optional if the
- * symbol table address is supplied through ADDR.
+ * Function: H5G_open
*
- * Errors:
- * SYM BADMESG Can't read message.
- * SYM NOTFOUND Not found.
+ * Purpose: Opens an object. That is, it prepares the object for
+ * modification by returning a handle to the object
+ * symbol table entry. Opening an object twice with the
+ * same name (or more precisely, through the same final
+ * symbol table entry) will return pointers to the same
+ * H5G_entry_t struct. But opening an object through
+ * different final H5G_entry_t structs (which implies
+ * different names) returns pointers to different
+ * structs. The structs that are returned should be
+ * released by calling H5G_close().
*
- * Return: Success: Pointer to the symbol table entry.
- * The pointer is intended for immediate
- * read-only access since it points
- * directly to an entry in a cached
- * symbol table node. The pointer is
- * guaranteed to be valid only until the
- * next call to one of the H5AC functions.
+ * Return: Success: Ptr to a handle for the object.
*
* Failure: NULL
*
* Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
+ * Wednesday, September 17, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
H5G_entry_t *
-H5G_stab_find (hdf5_file_t *f, haddr_t addr, H5G_entry_t *self,
- const char *name)
+H5G_open (hdf5_file_t *f, const char *name)
{
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
- H5O_stab_t stab; /*symbol table message */
-
- FUNC_ENTER (H5G_stab_find, NULL, NULL);
+ H5G_entry_t *ent=NULL;
+ H5G_entry_t *ret_value=NULL;
+ H5G_entry_t dir;
+ H5G_entry_t *cwd=NULL;
+
+ FUNC_ENTER (H5G_open, NULL, NULL);
- /* Check arguments */
+ /* check args */
assert (f);
- if (addr<=0 && (!self || self->header<=0)) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
- }
if (!name || !*name) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_BADVALUE, NULL);
}
- if (addr<=0) addr = self->header;
- /* set up the udata */
- if (NULL==H5O_read (f, addr, self, H5O_STAB, 0, &stab)) {
- HRETURN_ERROR (H5E_SYM, H5E_BADMESG, NULL); /*can't read message*/
- }
- udata.operation = H5G_OPER_FIND;
- udata.name = name;
- udata.heap_addr = stab.heap_addr;
- udata.dir_addr = addr;
+ /* Get CWD */
+#ifndef LATER
+ H5G_shadow_sync (f->root_sym);
+ cwd = f->root_sym;
+#endif
+ assert (cwd || '/'==*name);
- /* search the B-tree */
- if (H5B_find (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*not found*/
+ if (f->root_sym->header<=0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
}
-
- /* return the result */
- FUNC_LEAVE (udata.entry_ptr);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_stab_insert
- *
- * Purpose: Insert a new symbol into the table described by SELF in
- * file F. The name of the new symbol is NAME and its symbol
- * table entry is ENT.
- *
- * Errors:
- * SYM BADMESG Can't read message.
- * SYM CANTINSERT Can't insert entry.
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
- *
- * Robb Matzke, 18 Sep 1997
- * If ENT has a shadow, then the shadow will be associated with the
- * entry when it is added to the symbol table.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_stab_insert (hdf5_file_t *f, H5G_entry_t *self, const char *name,
- H5G_entry_t *ent)
-{
- H5O_stab_t stab; /*symbol table message */
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
-
- FUNC_ENTER (H5G_stab_insert, NULL, FAIL);
-
- /* check arguments */
- assert (f);
- assert (self && self->header>=0);
- assert (name && *name);
- assert (ent);
-
- /* 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); /*can't read message*/
+ if (NULL==(ent=H5G_namei (f, cwd, name, NULL, &dir))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
}
-
- udata.operation = H5G_OPER_INSERT;
- udata.name = name;
- udata.heap_addr = stab.heap_addr;
- udata.dir_addr = self->header;
- udata.entry = *ent;
- udata.entry.name_off = -1;
-
- /* insert */
- if (H5B_insert (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL); /*can't insert entry*/
+ if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTOPENOBJ, NULL);
}
- /* update the name offset in the entry */
- ent->name_off = udata.entry.name_off;
- FUNC_LEAVE (SUCCEED);
+ FUNC_LEAVE (ret_value);
}
-
-/*-------------------------------------------------------------------------
- * Function: H5G_stab_list
- *
- * Purpose: Returns a list of all the symbols in a symbol table.
- * The caller allocates an array of pointers which this
- * function will fill in with malloc'd names. The caller
- * also allocates an array of symbol table entries which will
- * be filled in with data from the symbol table. Each of these
- * arrays should have at least MAXENTRIES elements.
- *
- * Errors:
- * SYM BADMESG Not a symbol table.
- * SYM CANTLIST B-tree list failure.
- *
- * Return: Success: The total number of symbols in the
- * symbol table. This may exceed MAXENTRIES,
- * but at most MAXENTRIES values are copied
- * into the NAMES and ENTRIES arrays.
- *
- * Failure: FAIL, the pointers in NAMES are undefined but
- * no memory is allocated. The values in
- * ENTRIES are undefined.
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-intn
-H5G_stab_list (hdf5_file_t *f, H5G_entry_t *self, intn maxentries,
- char *names[], H5G_entry_t entries[])
-{
- H5G_bt_ud2_t udata;
- H5O_stab_t stab;
- intn i;
-
- FUNC_ENTER (H5G_stab_list, NULL, FAIL);
-
- /* check args */
- assert (f);
- 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); /*not a symbol table*/
- }
- udata.entry = entries;
- udata.name = names;
- udata.dir_addr = self->header;
- udata.heap_addr = stab.heap_addr;
- udata.maxentries = maxentries;
- udata.nsyms = 0;
- if (names) HDmemset (names, 0, maxentries);
-
- /* list */
- if (H5B_list (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
- if (names) {
- for (i=0; i<maxentries; i++) H5MM_xfree (names[i]);
- }
- HRETURN_ERROR (H5E_SYM, H5E_CANTLIST, FAIL); /*B-tree list failure*/
- }
- FUNC_LEAVE (udata.nsyms);
-}
-
/*-------------------------------------------------------------------------
- * Function: H5G_decode_vec
- *
- * Purpose: Same as H5G_decode() except it does it for an array of
- * symbol table entries.
+ * Function: H5G_close
*
- * Errors:
- * SYM CANTDECODE Can't decode.
+ * Purpose: Closes an object that was open for modification.
*
- * Return: Success: SUCCEED, with *pp pointing to the first byte
- * after the last symbol.
+ * Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 18 1997
+ * Thursday, September 18, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_decode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
+H5G_close (hdf5_file_t *f, H5G_entry_t *ent)
{
- intn i;
-
- FUNC_ENTER (H5G_decode_vec, NULL, FAIL);
+ FUNC_ENTER (H5G_close, NULL, FAIL);
- /* check arguments */
assert (f);
- assert (pp);
- assert (ent);
- assert (n>=0);
- /* decode entries */
- for (i=0; i<n; i++) {
- if (H5G_decode (f, pp, ent+i)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTDECODE, FAIL); /*can't decode*/
- }
+ if (ent && H5G_shadow_close (f, ent)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTFLUSH, FAIL);
}
-
+
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5G_decode
- *
- * Purpose: Decodes a symbol table entry pointed to by `*pp'.
- *
- * Errors:
- *
- * Return: Success: SUCCEED with *pp pointing to the first byte
- * following the symbol table entry.
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 18 1997
- *
- * Modifications:
+ * Function: H5G_find
*
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
-{
- uint8 *p_ret = *pp;
-
- FUNC_ENTER (H5G_decode, NULL, FAIL);
-
- /* check arguments */
- assert (f);
- assert (pp);
- assert (ent);
-
- /* decode header */
- H5F_decode_offset (f, *pp, ent->name_off);
- H5F_decode_offset (f, *pp, ent->header);
- UINT32DECODE (*pp, ent->type);
-
- /* decode scratch-pad */
- switch (ent->type) {
- case H5G_NOTHING_CACHED:
- break;
-
- case H5G_CACHED_SDATA:
- ent->cache.sdata.nt.length= *(*pp)++;
- ent->cache.sdata.nt.arch= *(*pp)++;
- UINT16DECODE (*pp, ent->cache.sdata.nt.type);
- UINT32DECODE (*pp, ent->cache.sdata.ndim);
- UINT32DECODE (*pp, ent->cache.sdata.dim[0]);
- UINT32DECODE (*pp, ent->cache.sdata.dim[1]);
- UINT32DECODE (*pp, ent->cache.sdata.dim[2]);
- UINT32DECODE (*pp, ent->cache.sdata.dim[3]);
- break;
-
- case H5G_CACHED_STAB:
- UINT32DECODE (*pp, ent->cache.stab.btree_addr);
- UINT32DECODE (*pp, ent->cache.stab.heap_addr);
- break;
-
- default:
- HDabort();
- }
-
- *pp = p_ret + H5G_SIZEOF_ENTRY(f);
- FUNC_LEAVE (SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_encode_vec
+ * 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 (or all zero if
+ * the returned object is the root object) 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).
*
- * Purpose: Same as H5G_encode() except it does it for an array of
- * symbol table entries.
+ * This function will fail if the root object is
+ * requested and there is none.
*
* Errors:
- * SYM CANTENCODE Can't encode.
+ * DIRECTORY NOTFOUND Object not found.
*
- * Return: Success: SUCCEED, with *pp pointing to the first byte
- * after the last symbol.
+ * Return: Success: SUCCEED with DIR_ENT and ENT initialized. ENT
+ * is intended for immediate read-only access.
+ * If the object that ENT refers to is open
+ * through the ENT entry (see H5G_open()) then
+ * the returned ENT will contain the latest
+ * information. However, subsequent changes to
+ * the symbol table entry will not be reflected
+ * in ENT since it is a copy of the symbol table.
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 18 1997
+ * robb@maya.nuance.com
+ * Aug 12 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_encode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
+H5G_find (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
+ const char *name, H5G_entry_t *ent)
{
- intn i;
-
- FUNC_ENTER (H5G_encode_vec, NULL, FAIL);
+ H5G_entry_t *ent_p = NULL;
+ FUNC_ENTER (H5G_find, NULL, FAIL);
- /* check arguments */
+ /* check args */
assert (f);
- assert (pp);
- assert (ent);
- assert (n>=0);
+ assert (name && *name);
+ assert (cwd || '/'==*name);
- /* encode entries */
- for (i=0; i<n; i++) {
- if (H5G_encode (f, pp, ent+i)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTENCODE, FAIL); /*can't encode*/
- }
+ if (f->root_sym->header<=0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
}
- FUNC_LEAVE (SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_encode
- *
- * Purpose: Encodes the specified symbol table entry into the buffer
- * pointed to by *pp.
- *
- * Errors:
- *
- * Return: Success: SUCCEED, with *pp pointing to the first byte
- * after the symbol table entry.
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 18 1997
- *
- * Modifications:
- *
- * Robb Matzke, 8 Aug 1997
- * Writes zeros for the bytes that aren't used so the file doesn't
- * contain junk.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
-{
- uint8 *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
-
- FUNC_ENTER (H5G_encode, NULL, FAIL);
-
- /* check arguments */
- assert (f);
- assert (pp);
- assert (ent);
-
- /* encode header */
- H5F_encode_offset (f, *pp, ent->name_off);
- H5F_encode_offset (f, *pp, ent->header);
- UINT32ENCODE (*pp, ent->type);
-
- /* encode scratch-pad */
- switch (ent->type) {
- case H5G_NOTHING_CACHED:
- break;
-
- case H5G_CACHED_SDATA:
- *(*pp)++= ent->cache.sdata.nt.length;
- *(*pp)++= ent->cache.sdata.nt.arch;
- UINT16ENCODE (*pp, ent->cache.sdata.nt.type);
- UINT32ENCODE (*pp, ent->cache.sdata.ndim);
- UINT32ENCODE (*pp, ent->cache.sdata.dim[0]);
- UINT32ENCODE (*pp, ent->cache.sdata.dim[1]);
- UINT32ENCODE (*pp, ent->cache.sdata.dim[2]);
- UINT32ENCODE (*pp, ent->cache.sdata.dim[3]);
- break;
-
- case H5G_CACHED_STAB:
- UINT32ENCODE (*pp, ent->cache.stab.btree_addr);
- UINT32ENCODE (*pp, ent->cache.stab.heap_addr);
- break;
-
- default:
- HDabort();
+ if (NULL==(ent_p=H5G_namei (f, cwd, name, NULL, dir_ent))) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
}
- /* fill with zero */
- while (*pp<p_ret) *(*pp)++ = 0;
-
- *pp = p_ret;
+ if (ent) *ent = *ent_p;
FUNC_LEAVE (SUCCEED);
}
-
-/*-------------------------------------------------------------------------
- * Function: H5G_debug
- *
- * Purpose: Prints debugging information about a symbol table entry.
- *
- * Errors:
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * robb@maya.nuance.com
- * Aug 29 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_debug (hdf5_file_t *f, H5G_entry_t *ent, FILE *stream, intn indent,
- intn fwidth)
-{
- int i;
- char buf[64];
-
- FUNC_ENTER (H5G_debug, NULL, FAIL);
-
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Name offset into private heap:",
- (unsigned long)(ent->name_off));
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Object header address:",
- (unsigned long)(ent->header));
- fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Dirty:",
- ent->dirty ? "Yes" : "No");
- fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Has a shadow:",
- H5G_shadow_p (ent)?"This is a shadow!" :
- (ent->shadow ? "Yes" : "No"));
-
- fprintf (stream, "%*s%-*s ", indent, "", fwidth,
- "Symbol type:");
- switch (ent->type) {
- case H5G_NOTHING_CACHED:
- fprintf (stream, "Nothing Cached\n");
- break;
-
- case H5G_CACHED_SDATA:
- fprintf (stream, "S-data\n");
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type length:",
- (unsigned)(ent->cache.sdata.nt.length));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type architecture:",
- (unsigned)(ent->cache.sdata.nt.arch));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Number type type:",
- (unsigned)(ent->cache.sdata.nt.type));
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Dimensionality:",
- (unsigned)(ent->cache.sdata.ndim));
- for (i=0; i<ent->cache.sdata.ndim && i<4; i++) {
- sprintf (buf, "Dimension %d", i);
- fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- buf,
- (unsigned)(ent->cache.sdata.dim[i]));
- }
- break;
-
- case H5G_CACHED_STAB:
- fprintf (stream, "Symbol Table\n");
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "B-tree address:",
- (unsigned long)(ent->cache.stab.btree_addr));
- fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
- "Heap address:",
- (unsigned long)(ent->cache.stab.heap_addr));
- break;
-
- default:
- fprintf (stream, "*** Unknown symbol type %d\n", ent->type);
- break;
- }
-
- FUNC_LEAVE (SUCCEED);
-}