1997-07-31 05:17:56 +08:00
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Copyright (C) 1997 National Center for Supercomputing Applications.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Created: H5G.c
|
|
|
|
|
* Jul 18 1997
|
1997-08-08 03:23:00 +08:00
|
|
|
|
* Robb Matzke <matzke@llnl.gov>
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-08-10 00:45:59 +08:00
|
|
|
|
* Purpose: Symbol table functions. The functions that
|
|
|
|
|
* begin with `H5G_stab_' don't understand the
|
|
|
|
|
* directory hierarchy; they operate on a single
|
|
|
|
|
* symbol table at a time.
|
|
|
|
|
*
|
|
|
|
|
* The functions that begin with `H5G_node_' operate
|
|
|
|
|
* on the leaf nodes of a symbol table B-tree. They
|
|
|
|
|
* should be defined in the H5Gnode.c file.
|
|
|
|
|
*
|
|
|
|
|
* The remaining functions know about the directory
|
|
|
|
|
* hierarchy.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-08-08 03:23:00 +08:00
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
* Robb Matzke, 5 Aug 1997
|
|
|
|
|
* Added calls to H5E.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Robb Matzke, 30 Aug 1997
|
|
|
|
|
* Added `Errors:' field to function prologues.
|
|
|
|
|
*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Robb Matzke, 18 Sep 1997
|
|
|
|
|
* Added shadow entry support.
|
|
|
|
|
*
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
#define H5G_PACKAGE /*suppress error message about including H5Gpkg.h*/
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
|
1997-07-31 05:17:56 +08:00
|
|
|
|
/* Packages needed by this file... */
|
1997-08-16 00:51:34 +08:00
|
|
|
|
#include <H5private.h>
|
|
|
|
|
#include <H5Bprivate.h>
|
|
|
|
|
#include <H5Eprivate.h>
|
1997-09-20 00:36:59 +08:00
|
|
|
|
#include <H5Gpkg.h>
|
1997-08-16 00:51:34 +08:00
|
|
|
|
#include <H5Hprivate.h>
|
|
|
|
|
#include <H5MMprivate.h>
|
|
|
|
|
#include <H5Oprivate.h>
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1997-08-16 00:51:34 +08:00
|
|
|
|
#define H5G_INIT_HEAP 8192
|
1997-09-20 00:36:59 +08:00
|
|
|
|
#define PABLO_MASK H5G_mask
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
|
|
|
|
/* Is the interface initialized? */
|
1997-09-20 00:36:59 +08:00
|
|
|
|
static hbool_t interface_initialize_g = FALSE;
|
1997-07-31 05:17:56 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* 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++;
|
1997-09-02 23:38:26 +08:00
|
|
|
|
if (size_p) *size_p = HDstrcspn (name, "/");
|
1997-08-13 06:44:46 +08:00
|
|
|
|
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.
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* 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:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-08-30 00:58:58 +08:00
|
|
|
|
#if 0
|
1997-08-13 06:44:46 +08:00
|
|
|
|
static const char *
|
|
|
|
|
H5G_basename (const char *name, size_t *size_p)
|
|
|
|
|
{
|
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
|
|
assert (name);
|
|
|
|
|
|
1997-08-29 00:37:58 +08:00
|
|
|
|
s = name + HDstrlen(name);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
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;
|
1997-08-29 00:37:58 +08:00
|
|
|
|
return s + HDstrlen(s); /*null terminator*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
1997-09-02 23:38:26 +08:00
|
|
|
|
if (size_p) *size_p = HDstrcspn (s, "/");
|
1997-08-13 06:44:46 +08:00
|
|
|
|
return s;
|
|
|
|
|
}
|
1997-08-30 00:58:58 +08:00
|
|
|
|
#endif
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5G_namei
|
|
|
|
|
*
|
1997-08-29 00:37:58 +08:00
|
|
|
|
* Purpose: (Partially) translates a name to a symbol table entry.
|
|
|
|
|
*
|
|
|
|
|
* Given a name (absolute or relative) return the symbol table
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* 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).
|
|
|
|
|
*
|
|
|
|
|
* If the name cannot be fully resolved, then REST will
|
|
|
|
|
* point to the part of NAME where the traversal failed
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* (REST will always point to a relative name) and this
|
|
|
|
|
* function will return null. DIR_ENT will be initialized with
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* 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.
|
|
|
|
|
*
|
1997-08-29 00:37:58 +08:00
|
|
|
|
* As a special case, if the NAME is the name `/' (or
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* equivalent) then DIR_ENT is initialized to all zero
|
|
|
|
|
* and a pointer to the root symbol table entry is returned.
|
1997-08-29 00:37:58 +08:00
|
|
|
|
*
|
|
|
|
|
* As a special case, if the NAME is the string `/foo' (or
|
|
|
|
|
* equivalent) and the root symbol table entry points to a
|
|
|
|
|
* non-directory object with a name message with the value
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* `foo' then DIR_ENT is initialized to all zero and a pointer
|
|
|
|
|
* to the root symbol table entry is returned.
|
1997-08-29 00:37:58 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
* DIRECTORY COMPLEN Component is too long.
|
|
|
|
|
* DIRECTORY NOTFOUND Component not found.
|
|
|
|
|
* DIRECTORY NOTFOUND Root not found.
|
|
|
|
|
*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Return: Success: Pointer to a cached symbol table entry if the
|
|
|
|
|
* name can be fully resolved. The pointer is
|
|
|
|
|
* valid until one of the H5AC (cache) functions
|
|
|
|
|
* is called.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Failure: Null if the name could not be fully resolved.
|
|
|
|
|
* REST and DIR_ENT are initialized (possibly to
|
|
|
|
|
* zero if the failure occurred soon enough).
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* robb@maya.nuance.com
|
|
|
|
|
* Aug 11 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
static H5G_entry_t *
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_namei (H5F_t *f, H5G_entry_t *cwd, const char *name,
|
1997-09-20 00:36:59 +08:00
|
|
|
|
const char **rest, H5G_entry_t *dir_ent)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5G_entry_t dir; /*entry for current directory */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
size_t nchars; /*component name length */
|
|
|
|
|
char comp[1024]; /*component name buffer */
|
1997-08-29 00:37:58 +08:00
|
|
|
|
hbool_t aside = FALSE; /*did we look at a name message?*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5G_entry_t *ret_value=NULL; /*return value */
|
|
|
|
|
|
|
|
|
|
/* clear output args before FUNC_ENTER() in case it fails */
|
|
|
|
|
if (rest) *rest = name;
|
|
|
|
|
if (dir_ent) memset (dir_ent, 0, sizeof(H5G_entry_t));
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1997-09-20 00:36:59 +08:00
|
|
|
|
FUNC_ENTER (H5G_namei, NULL, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert (f);
|
1997-09-25 00:30:22 +08:00
|
|
|
|
assert (f->shared->root_sym);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
assert (name && *name);
|
|
|
|
|
assert (cwd || '/'==*name);
|
|
|
|
|
|
|
|
|
|
/* starting point */
|
|
|
|
|
if ('/'==*name) {
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header<=0) {
|
1997-09-20 00:36:59 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
|
|
|
|
|
}
|
1997-09-25 00:30:22 +08:00
|
|
|
|
ret_value = f->shared->root_sym;
|
|
|
|
|
dir = *(f->shared->root_sym);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else {
|
1997-09-20 00:36:59 +08:00
|
|
|
|
ret_value = cwd;
|
|
|
|
|
dir = *cwd;
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* traverse the name */
|
|
|
|
|
while ((name=H5G_component (name, &nchars)) && *name) {
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* The special name `.' is a no-op.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
|
|
|
|
if ('.'==name[0] && !name[1]) continue;
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Advance to the next component of the name.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
dir = *ret_value;
|
|
|
|
|
ret_value = NULL;
|
1997-08-13 06:44:46 +08:00
|
|
|
|
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)) {
|
1997-09-02 23:38:26 +08:00
|
|
|
|
/* component is too long */
|
1997-09-20 00:36:59 +08:00
|
|
|
|
if (dir_ent) *dir_ent = dir;
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
HDmemcpy (comp, name, nchars);
|
|
|
|
|
comp[nchars] = '\0';
|
|
|
|
|
|
1997-09-20 00:36:59 +08:00
|
|
|
|
if (NULL==(ret_value=H5G_stab_find (f, NO_ADDR, &dir, comp))) {
|
1997-08-29 00:37:58 +08:00
|
|
|
|
/*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Component was not found in the current symbol table, possibly
|
|
|
|
|
* because DIR isn't a symbol table. If it is the root symbol then
|
1997-08-29 00:37:58 +08:00
|
|
|
|
* see if it has the appropriate name field. The ASIDE variable
|
|
|
|
|
* prevents us from saying `/foo/foo' where the root object has
|
|
|
|
|
* the name `foo'.
|
|
|
|
|
*/
|
1997-09-17 04:07:12 +08:00
|
|
|
|
H5O_name_t mesg={0};
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (!aside && dir.header==f->shared->root_sym->header &&
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5O_read (f, dir.header, &dir, H5O_NAME, 0, &mesg) &&
|
|
|
|
|
!HDstrcmp (mesg.s, comp)) {
|
1997-08-29 00:37:58 +08:00
|
|
|
|
H5O_reset (H5O_NAME, &mesg);
|
1997-09-25 00:30:22 +08:00
|
|
|
|
ret_value = f->shared->root_sym;
|
1997-09-20 00:36:59 +08:00
|
|
|
|
aside = TRUE;
|
1997-08-30 00:58:58 +08:00
|
|
|
|
} else {
|
|
|
|
|
/* component not found */
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5O_reset (H5O_NAME, &mesg);
|
|
|
|
|
if (dir_ent) *dir_ent = dir;
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* next component */
|
|
|
|
|
name += nchars;
|
|
|
|
|
}
|
1997-08-29 00:37:58 +08:00
|
|
|
|
|
1997-08-13 06:44:46 +08:00
|
|
|
|
/* output parameters */
|
|
|
|
|
if (rest) *rest = name; /*final null*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
if (dir_ent) {
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (ret_value->header == f->shared->root_sym->header) {
|
1997-08-29 00:37:58 +08:00
|
|
|
|
HDmemset (dir_ent, 0, sizeof(H5G_entry_t)); /*root has no parent*/
|
|
|
|
|
} else {
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*dir_ent = dir;
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Perhaps the root object doesn't even exist! */
|
1997-09-20 00:36:59 +08:00
|
|
|
|
if (ret_value->header<=0) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*root not found*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1997-09-20 00:36:59 +08:00
|
|
|
|
FUNC_LEAVE (ret_value);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5G_mkroot
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Creates the root directory if it doesn't exist; otherwise
|
1997-08-29 00:37:58 +08:00
|
|
|
|
* nothing happens. If the root symbol table entry 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's name message (the name message
|
|
|
|
|
* is removed). If the root object doesn't have a name message
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* then the name `Root Object' is used.
|
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Warning: This function has a few subtleties. Be warned!
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
* DIRECTORY CANTINIT Can't create root.
|
|
|
|
|
* DIRECTORY CANTINIT Can't insert old root object in
|
|
|
|
|
* new root directory.
|
|
|
|
|
* DIRECTORY EXISTS Root directory already exists.
|
|
|
|
|
*
|
1997-08-13 06:44:46 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Failure: FAIL. This function returns -2 if the
|
|
|
|
|
* failure is because a root directory already
|
|
|
|
|
* exists.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* robb@maya.nuance.com
|
|
|
|
|
* Aug 11 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
static herr_t
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_mkroot (H5F_t *f, size_t size_hint)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
H5G_entry_t *handle=NULL; /*handle to open object */
|
|
|
|
|
herr_t ret_value=FAIL; /*return value */
|
|
|
|
|
H5O_name_t name={NULL}; /*object name */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
H5O_stab_t stab; /*symbol table message */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
H5G_entry_t *ent_ptr=NULL; /*pointer to a symbol table entry*/
|
|
|
|
|
const char *obj_name=NULL; /*name of old root object */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER (H5G_mkroot, NULL, FAIL);
|
|
|
|
|
|
1997-09-20 00:36:59 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Make sure that the file descriptor has the latest info -- someone might
|
|
|
|
|
* have the root object open.
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*/
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_shadow_sync (f->shared->root_sym);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
|
1997-08-13 06:44:46 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header>0) {
|
|
|
|
|
if (H5O_read (f, NO_ADDR, f->shared->root_sym, H5O_STAB, 0, &stab)) {
|
1997-08-13 06:44:46 +08:00
|
|
|
|
/* root directory already exists */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HGOTO_ERROR (H5E_DIRECTORY, H5E_EXISTS, -2);
|
1997-09-25 00:30:22 +08:00
|
|
|
|
} else if (NULL==(handle=H5G_shadow_open (f, NULL, f->shared->root_sym))) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* 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";
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
obj_name = name.s; /*don't reset message until the end!*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
handle->dirty = TRUE;
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (H5G_stab_new (f, f->shared->root_sym, size_hint)<0) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*cant create root*/
|
|
|
|
|
}
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (1!=H5O_link (f, f->shared->root_sym, 1)) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (obj_name) {
|
|
|
|
|
if (1!=H5O_link (f, handle, 0)) {
|
|
|
|
|
HGOTO_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (NULL==(ent_ptr=H5G_stab_insert (f, f->shared->root_sym, obj_name,
|
1997-09-22 10:08:54 +08:00
|
|
|
|
handle))) {
|
|
|
|
|
HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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?*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
|
|
|
|
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);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5O_reset (H5O_NAME, &name);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
|
|
|
|
FUNC_LEAVE (ret_value);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_mkdir
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-08-29 00:37:58 +08:00
|
|
|
|
* A root directory is created implicitly by this function
|
|
|
|
|
* when necessary. Calling this function with the name "/"
|
|
|
|
|
* (or any equivalent name) will result in an H5E_EXISTS
|
|
|
|
|
* failure.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
* DIRECTORY CANTINIT Can't create dir.
|
|
|
|
|
* DIRECTORY CANTINIT Can't insert.
|
|
|
|
|
* DIRECTORY CANTINIT Lookup failed.
|
|
|
|
|
* DIRECTORY COMPLEN Component is too long.
|
|
|
|
|
* DIRECTORY EXISTS Already exists.
|
|
|
|
|
* DIRECTORY NOTFOUND Missing component.
|
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Return: Success: A handle to the open directory. Please call
|
|
|
|
|
* H5G_close() when you're done with it.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Failure: NULL
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* robb@maya.nuance.com
|
|
|
|
|
* Aug 11 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
H5G_entry_t *
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_mkdir (H5F_t *f, const char *name, size_t size_hint)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
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 */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_ENTER (H5G_mkdir, NULL, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert (f);
|
|
|
|
|
assert (name && *name);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#ifndef LATER
|
|
|
|
|
/* Get current working directory */
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_shadow_sync (f->shared->root_sym);
|
|
|
|
|
cwd = f->shared->root_sym;
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#endif
|
1997-08-13 06:44:46 +08:00
|
|
|
|
assert (cwd || '/'==*name);
|
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/*
|
|
|
|
|
* 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);
|
|
|
|
|
}
|
1997-08-29 00:37:58 +08:00
|
|
|
|
H5ECLEAR;
|
|
|
|
|
|
1997-08-13 06:44:46 +08:00
|
|
|
|
/* lookup name */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (H5G_namei (f, cwd, name, &rest, &dir_ent)) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
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 */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else if (nchars+1 > sizeof _comp) {
|
1997-09-02 23:38:26 +08:00
|
|
|
|
/* component is too long */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else {
|
|
|
|
|
/* null terminate */
|
1997-08-29 00:37:58 +08:00
|
|
|
|
HDmemcpy (_comp, rest, nchars);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
_comp[nchars] = '\0';
|
|
|
|
|
rest = _comp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create directory */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (H5G_stab_new (f, &ent, size_hint)<0) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't create dir*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* insert child name into parent */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ent_ptr=H5G_stab_insert (f, &dir_ent, rest, &ent))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* 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*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_LEAVE (ret_value);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_pushd
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Purpose: Pushes a new current working directory onto the stack.
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
|
|
|
|
* Return: Success: SUCCEED
|
|
|
|
|
*
|
|
|
|
|
* Failure: FAIL
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Friday, September 19, 1997
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_pushd (H5F_t *f, const char *name)
|
1997-09-20 00:36:59 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_ENTER (H5G_pushd, NULL, FAIL);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#ifndef LATER
|
|
|
|
|
/*
|
|
|
|
|
* Current working directories are not implemented yet.
|
|
|
|
|
*/
|
|
|
|
|
if (strcmp (name, "/")) {
|
|
|
|
|
HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#endif
|
1997-09-20 00:36:59 +08:00
|
|
|
|
|
|
|
|
|
FUNC_LEAVE (SUCCEED);
|
|
|
|
|
}
|
|
|
|
|
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_popd
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Purpose: Pops the top current working directory off the stack.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Failure: FAIL
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Friday, September 19, 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
herr_t
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_popd (H5F_t *f)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_ENTER (H5G_popd, NULL, FAIL);
|
1997-08-29 00:37:58 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#ifndef LATER
|
|
|
|
|
/* CWD is not implemented yet. */
|
|
|
|
|
#endif
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
FUNC_LEAVE (SUCCEED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_create
|
1997-08-13 23:36:47 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Return: Success: A handle for the object. Be sure to
|
|
|
|
|
* eventually close it.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Failure: FAIL
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Friday, September 19, 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
H5G_entry_t *
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_create (H5F_t *f, const char *name, size_t ohdr_hint)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
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 */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_ENTER (H5G_create, NULL, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* Check args. */
|
1997-08-13 06:44:46 +08:00
|
|
|
|
assert (f);
|
|
|
|
|
assert (name && *name);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HDmemset (&ent, 0, sizeof(H5G_entry_t));
|
|
|
|
|
|
1997-08-29 00:37:58 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Get the current working directory.
|
1997-08-29 00:37:58 +08:00
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#ifndef LATER
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_shadow_sync (f->shared->root_sym);
|
|
|
|
|
cwd = f->shared->root_sym;
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#endif
|
1997-08-29 00:37:58 +08:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Look up the name -- it shouldn't exist yet.
|
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (H5G_namei (f, cwd, name, &rest, &dir)) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_EXISTS, NULL); /*already exists*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
H5ECLEAR; /*it's OK that we didn't find it*/
|
|
|
|
|
rest = H5G_component (rest, &nchars);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
1997-08-29 00:37:58 +08:00
|
|
|
|
if (!rest || !*rest) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header>0) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
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);
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (1!=H5O_link (f, &ent, 1)) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-09-25 00:30:22 +08:00
|
|
|
|
*(f->shared->root_sym) = ent;
|
|
|
|
|
if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
|
|
|
|
|
}
|
|
|
|
|
HRETURN (ret_value);
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* There should be one component left. Make sure it's null
|
|
|
|
|
* terminated.
|
|
|
|
|
*/
|
1997-08-13 06:44:46 +08:00
|
|
|
|
if (rest[nchars]) {
|
|
|
|
|
if (H5G_component (rest+nchars, NULL)) {
|
1997-09-02 23:38:26 +08:00
|
|
|
|
/* component not found */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else if (nchars+1 > sizeof _comp) {
|
1997-09-02 23:38:26 +08:00
|
|
|
|
/* component is too long */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_COMPLEN, NULL);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
} else {
|
|
|
|
|
/* null terminate */
|
1997-08-29 00:37:58 +08:00
|
|
|
|
HDmemcpy (_comp, rest, nchars);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
_comp[nchars] = '\0';
|
|
|
|
|
rest = _comp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1997-08-29 00:37:58 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Create the object header.
|
1997-08-29 00:37:58 +08:00
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if ((ent.header = H5O_new (f, 0, ohdr_hint))<0) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header<=0) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
H5O_name_t name_mesg;
|
|
|
|
|
name_mesg.s = rest;
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (H5O_modify (f, NO_ADDR, &ent, H5O_NAME, 0, &name_mesg)<0) {
|
1997-08-29 00:37:58 +08:00
|
|
|
|
/* cannot add/change name message */
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (1!=H5O_link (f, &ent, 1)) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*bad link count*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
}
|
1997-09-25 00:30:22 +08:00
|
|
|
|
*(f->shared->root_sym) = ent;
|
|
|
|
|
if (NULL==(ret_value=H5G_shadow_open (f, &dir, f->shared->root_sym))) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
|
|
|
|
|
}
|
|
|
|
|
HRETURN (ret_value);
|
|
|
|
|
} else {
|
1997-08-13 06:44:46 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Make sure the root directory exists. Ignore the failure if it's
|
|
|
|
|
* because the directory already exists.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*/
|
1997-09-25 00:30:22 +08:00
|
|
|
|
hbool_t update_dir = (dir.header==f->shared->root_sym->header);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
herr_t status = H5G_mkroot (f, H5G_SIZE_HINT);
|
|
|
|
|
if (status<0 && -2!=status) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL);
|
|
|
|
|
}
|
|
|
|
|
H5ECLEAR;
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (update_dir) dir = *(f->shared->root_sym);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
1997-08-13 23:36:47 +08:00
|
|
|
|
/*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* This is the normal case. The object is just being inserted as a normal
|
|
|
|
|
* entry into a symbol table.
|
1997-08-13 23:36:47 +08:00
|
|
|
|
*/
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (H5O_link (f, &ent, 1)<0) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, NULL); /*link inc failure*/
|
1997-08-08 03:23:00 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ent_ptr=H5G_stab_insert (f, &dir, rest, &ent))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't insert*/
|
1997-08-10 00:45:59 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent_ptr))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, NULL); /*can't open object*/
|
1997-08-08 03:23:00 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_LEAVE (ret_value);
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_open
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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().
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Return: Success: Ptr to a handle for the object.
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
*
|
1997-09-20 00:36:59 +08:00
|
|
|
|
* Failure: NULL
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Wednesday, September 17, 1997
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-09-20 00:36:59 +08:00
|
|
|
|
H5G_entry_t *
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_open (H5F_t *f, const char *name)
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
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);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* check args */
|
1997-08-08 03:23:00 +08:00
|
|
|
|
assert (f);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
if (!name || !*name) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_BADVALUE, NULL);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* Get CWD */
|
|
|
|
|
#ifndef LATER
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_shadow_sync (f->shared->root_sym);
|
|
|
|
|
cwd = f->shared->root_sym;
|
1997-09-22 10:08:54 +08:00
|
|
|
|
#endif
|
|
|
|
|
assert (cwd || '/'==*name);
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header<=0) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
|
1997-08-08 03:23:00 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ent=H5G_namei (f, cwd, name, NULL, &dir))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, NULL); /*object not found*/
|
1997-08-08 03:23:00 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ret_value=H5G_shadow_open (f, &dir, ent))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTOPENOBJ, NULL);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
}
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_LEAVE (ret_value);
|
[svn-r6] Added the next layer of symbol table functions. Given a symbol table
name, they operate to query or modify the corresponding symbol table entry.
They don't understand directory hierarchies (that's the next layer up).
Since the object header stuff isn't done yet, they call four stub functions
that all return failure:
not_implemented_yet__create_object_header()
not_implemented_yet__insert_symtab_message()
not_implemented_yet__get_symtab_message()
not_implemented_yet__update_symtab_message()
The interface is:
haddr_t H5G_new (file, initial_heap_size)
Creates a new symbol table.
haddr_t H5G_find (file, symtab_addr, symbol_name, *entry)
Returns a symbol table entry given the name.
herr_t H5G_modify (file, symtab_addr, symbol_name, *entry)
Modifies the symbol table entry for the specified name.
herr_t H5G_insert (file, symtab_addr, symbol_name, *entry)
Inserts a new name and symbol table entry pair.
intn H5G_list (file, symtab_addr, maxentries, names[], entries[])
Returns a list of all names and symbol table entries.
1997-08-02 04:20:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1997-07-31 05:17:56 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_close
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Purpose: Closes an object that was open for modification.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-08-08 03:23:00 +08:00
|
|
|
|
* Failure: FAIL
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Thursday, September 18, 1997
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_close (H5F_t *f, H5G_entry_t *ent)
|
1997-07-31 05:17:56 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
FUNC_ENTER (H5G_close, NULL, FAIL);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
|
|
|
|
assert (f);
|
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (ent && H5G_shadow_close (f, ent)<0) {
|
|
|
|
|
HRETURN_ERROR (H5E_SYM, H5E_CANTFLUSH, FAIL);
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
1997-08-08 03:23:00 +08:00
|
|
|
|
FUNC_LEAVE (SUCCEED);
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* Function: H5G_find
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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).
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* This function will fail if the root object is
|
|
|
|
|
* requested and there is none.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* DIRECTORY NOTFOUND Object not found.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* 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.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-08-08 03:23:00 +08:00
|
|
|
|
* Failure: FAIL
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
1997-09-22 10:08:54 +08:00
|
|
|
|
* robb@maya.nuance.com
|
|
|
|
|
* Aug 12 1997
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1997-09-25 00:30:22 +08:00
|
|
|
|
H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
|
1997-09-22 10:08:54 +08:00
|
|
|
|
const char *name, H5G_entry_t *ent)
|
1997-07-31 05:17:56 +08:00
|
|
|
|
{
|
1997-09-22 10:08:54 +08:00
|
|
|
|
H5G_entry_t *ent_p = NULL;
|
|
|
|
|
FUNC_ENTER (H5G_find, NULL, FAIL);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
/* check args */
|
1997-08-08 03:23:00 +08:00
|
|
|
|
assert (f);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
assert (name && *name);
|
|
|
|
|
assert (cwd || '/'==*name);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1997-09-25 00:30:22 +08:00
|
|
|
|
if (f->shared->root_sym->header<=0) {
|
1997-09-22 10:08:54 +08:00
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (NULL==(ent_p=H5G_namei (f, cwd, name, NULL, dir_ent))) {
|
|
|
|
|
HRETURN_ERROR (H5E_DIRECTORY, H5E_NOTFOUND, FAIL); /*object not found*/
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
1997-09-22 10:08:54 +08:00
|
|
|
|
if (ent) *ent = *ent_p;
|
1997-08-08 03:23:00 +08:00
|
|
|
|
FUNC_LEAVE (SUCCEED);
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
|
|
|
|
|