1997-07-31 05:17:56 +08:00
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Copyright (C) 1997 National Center for Supercomputing Applications.
|
|
|
|
|
* All rights reserved.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Created: H5G.c
|
|
|
|
|
* Jul 18 1997
|
|
|
|
|
* Robb Matzke <matzke@llnl.gov>
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Symbol table functions. The functions that
|
|
|
|
|
* begin with `H5G_stab_' don't understand the
|
|
|
|
|
* naming system; they operate on a single
|
|
|
|
|
* symbol table at a time.
|
1997-08-10 00:45:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* 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.
|
1997-08-10 00:45:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* The remaining functions know how to traverse the
|
|
|
|
|
* group directed graph
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1997-08-08 03:23:00 +08:00
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Robb Matzke, 5 Aug 1997
|
|
|
|
|
* Added calls to H5E.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Robb Matzke, 30 Aug 1997
|
|
|
|
|
* Added `Errors:' field to function prologues.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-28 13:47:19 +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>
|
1998-03-18 06:46:27 +08:00
|
|
|
|
#include <H5Iprivate.h>
|
1997-08-16 00:51:34 +08:00
|
|
|
|
#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
|
|
|
|
|
1998-01-28 13:47:19 +08:00
|
|
|
|
#define H5G_INIT_HEAP 8192
|
|
|
|
|
#define H5G_RESERVED_ATOMS 0
|
|
|
|
|
#define PABLO_MASK H5G_mask
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
[svn-r139] ./src/*.[ch]
Removed the interface initialization argument from
FUNC_ENTER() and made it a locally-defined preprocessor
symbol, INTERFACE_INIT.
Changed `offset' to `address' and `length' to `size' in
documentation so it's more consistent. `Offset' still appears
occassionally when it refers to a byte offset within some
other data structure.
Moved interface termination function prototypes from public
header files to .c files and made them static.
./src/H5.c
./src/H5public.h
Added H5init() because it's possible that the predefined data
types are not initialized. This happens only if the first
call to the hdf5 library passes a predefined data type symbol
as an argument. There should be some way to fix this...
./src/H5A.c
./src/H5Aprivate.h
./src/H5Apublic.h
The free_func returns SUCCEED or FAIL, although the return
value is ignored by H5A. This is so we can use the various
H5*_close() functions to free things.
H5Ainc_ref() and H5Adec_ref() are no longer public. Many of
the other atom functions should also be made private, but I'll
save that for later...
Added additional template groups called H5_TEMPLATE_0 through
H5_TEMPLATE_7 that are used by the various template
subclasses.
Increased the number of bits used for atom groups to prevent
negative atoms.
./src/H5AC.c
./src/H5ACprivate.h
Changed H5AC_new() to H5AC_create() to make names more consistent.
./src/H5B.c
./src/H5Bprivate.h
Changed H5B_new() to H5B_create() to make names more consistent.
./src/H5C.c
./src/H5Cprivate.h
./src/H5Cpublic.h
Now supports multiple subclasses of templates, although it's
done with big switch statements. The default values for
templates are defined in the source file to which that
template belongs. This got rid of lots of needless
preprocessor constants.
Added H5Ccreate() to create a new template. Changed
H5C_release() to H5Cclose() to make the naming more
consistent.
./src/H5D.c
./src/H5Dprivate.h
./src/H5Dpublic.h
Enhanced to use the new dataset interface, and uses the enhanced
data type and data space interfaces, which haven't been
completely implemented. The dataset interface doesn't handle
non-contiguous storage, compression, or data type and space
conversions yet.
./src/H5F.c
./src/H5Fprivate.h
./src/H5Fpublic.h
Removed H5Fflush() since just calls H5F_flush(), which doesn't
do what the user would probably think it does, namely, flush
everything. It only flushes those things sitting in the H5AC
cache and the boot block.
Changed the `file_create_parms' field of H5F_low_t to just
`create_parms' since the `file' part is obvious.
./src/H5Fistore.c
Added some support for external files. Mostly just in the
file format and not supported much by the library yet. I need
to finish some dataset functions first.
Changed H5F_istore_new() to H5F_istore_create() to make names
more uniform across packages.
./src/H5Flow.c
Flushing a file causes the file to be physically extended to
the logical eof. This prevents H5F_open() from thinking a
file has been truncated. Most of the time the file will
already be that large, and when it isn't Unix will often just
allocate the final block anyway.
./src/H5G.c
./src/H5Gent.c
./src/H5Gnode.c
./src/H5Gpkg.h
./src/H5Gprivate.h
./src/H5Gstab.c
Removed H5G_basename()
Removed (temporarily) data type information from symbol table
entries and renamed H5G_CACHED_SDATA to H5G_CACHED_SDSPACE to
reflect that it's a simple data space and has nothing to do
with raw data.
Changed H5G_node_new() to H5G_node_create() and H5G_stab_new()
to H5G_stab_create() to make names more uniform across
packages.
Fixed an undefined address bug that happens when H5G_node_debug()
program doesn't pass enough info to H5G_node_load().
./src/H5H.c
./src/H5Hprivate.h
Changed H5H_new() to H5H_create() to make the names more
uniform across packages.
./src/H5M.c
./src/H5Mprivate.h
./src/H5Mpublic.h
Nulled all the create functions. Most of the other callbacks
are to public functions. Removed H5Mcreate().
Changed hobjtype_t to group_t since it has to be the same
thing anyway.
./src/H5O.c
./src/H5Oprivate.h
./src/H5Osdim.c
./src/H5Osdtyp.c
Changed H5O_SIM_DIM to H5O_SDSPACE (simple data space) since
`simple data space' is its official name, not `simple
dimensions'. Will eventually add H5O_CDSPACE for comples data
spaces. Changed _sim_dim_ to _dspace_.
Replaced H5O_SIM_DTYPE and the compound data type messages
with a single H5O_DTYPE message. Changed _sim_dtype_ to _dtype_.
Changed H5O_STD_STORE to H5O_CSTORE (contiguous storage) since
contiguous storage is not necessarily standard. Changed
_std_store_ to _cstore_ in H5Ocstore.c
Added the H5O_EFL (external file list) message.
Changed H5O_new() to H5O_create() to make names more uniform
across packages.
./src/H5Oefl.c NEW
External file list message for specifying which non-hdf5 files
contain raw data for a dataset.
./src/H5P.c
./src/H5Pprivate.h
./src/H5Ppublic.h
Renamed and moved data structures to make the names conform to
our naming scheme.
./src/H5T.c
./src/H5Tprivate.h
./src/H5Tpublic.h
./src/H5Tpkg.h NEW
Data structures redesigned to be more flexible. The interface
was redesigned to make it more regular and to make some names
more uniform across packages.
./src/H5detect.c
Output was changed to produce a file that conforms to the hdf5
coding standard.
./src/Makefile.in
Generates H5Tinit.c by running H5detect.
./src/debug.c
Moved command argument processing.
1997-12-11 06:41:07 +08:00
|
|
|
|
/* Interface initialization */
|
1998-01-28 13:47:19 +08:00
|
|
|
|
static hbool_t interface_initialize_g = FALSE;
|
1998-03-24 22:53:57 +08:00
|
|
|
|
#define INTERFACE_INIT H5G_init_interface
|
1998-01-28 13:47:19 +08:00
|
|
|
|
static herr_t H5G_init_interface(void);
|
|
|
|
|
static void H5G_term_interface(void);
|
1997-09-22 10:08:54 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
static H5G_entry_t *H5G_getcwg(H5F_t *f);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gcreate
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Creates a new group in FILE and gives it the specified
|
|
|
|
|
* NAME. Unless NAME begins with `/' it is relative to the
|
|
|
|
|
* current working group. The group is opened for write access
|
|
|
|
|
* and it's object ID is returned.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* The optional SIZE_HINT specifies how much file space to
|
|
|
|
|
* reserve to store the names that will appear in this
|
|
|
|
|
* group. If a non-positive value is supplied for the SIZE_HINT
|
|
|
|
|
* then a default size is chosen.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* See also: H5Gset(), H5Gpush(), H5Gpop()
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: The object ID of a new, empty group open for
|
|
|
|
|
* writing. Call H5Gclose() when finished with
|
|
|
|
|
* the group.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-06 11:07:15 +08:00
|
|
|
|
hid_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gcreate(hid_t file_id, const char *name, size_t size_hint)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5F_t *f = NULL;
|
|
|
|
|
H5G_t *grp;
|
|
|
|
|
hid_t ret_value = FAIL;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5Gcreate, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check arguments */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_FILE != H5I_group(file_id) ||
|
|
|
|
|
NULL == (f = H5I_object(file_id))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (!name || !*name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Create the group */
|
|
|
|
|
if (NULL == (grp = H5G_create(f, name, size_hint))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if ((ret_value = H5I_register(H5_GROUP, grp)) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_close(grp);
|
|
|
|
|
HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL,
|
|
|
|
|
"unable to register group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(ret_value);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gopen
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Opens an existing group for modification. When finished,
|
|
|
|
|
* call H5Gclose() to close it and release resources.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: Object ID of the group.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, December 31, 1997
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
hid_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gopen(hid_t file_id, const char *name)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
hid_t ret_value = FAIL;
|
|
|
|
|
H5F_t *f = NULL;
|
|
|
|
|
H5G_t *grp = NULL;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5Gopen, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check args */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_FILE != H5I_group(file_id) ||
|
|
|
|
|
NULL == (f = H5I_object(file_id))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (!name || !*name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Open the group */
|
|
|
|
|
if (NULL == (grp = H5G_open(f, name))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Register an atom for the group */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if ((ret_value = H5I_register(H5_GROUP, grp)) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_close(grp);
|
|
|
|
|
HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL,
|
|
|
|
|
"unable to register group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(ret_value);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
}
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gclose
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Closes the specified group. The group ID will no longer be
|
|
|
|
|
* valid for accessing the group.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, December 31, 1997
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gclose(hid_t grp_id)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5Gclose, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check args */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_GROUP != H5I_group(grp_id) ||
|
|
|
|
|
NULL == H5I_object(grp_id)) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Decrement the counter on the group atom. It will be freed if the count
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* reaches zero.
|
|
|
|
|
*/
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5I_dec_ref(grp_id) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
1997-10-21 07:14:35 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gset
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Sets the working group for file handle FILE to the
|
|
|
|
|
* specified group.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Each file handle maintains its own notion of the current
|
|
|
|
|
* working group. That is, if a single file is opened with
|
|
|
|
|
* multiple calls to H5Fopen(), which returns multiple file
|
|
|
|
|
* handles, then each handle's current working group can be
|
|
|
|
|
* set independently of the other file handles for that file.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* See also: H5Gpush(), H5Gpop()
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gset(hid_t file_id, const char *name)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5F_t *f = NULL;
|
|
|
|
|
H5G_t *grp;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5Gset, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check/fix arguments */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_FILE != H5I_group(file_id) ||
|
|
|
|
|
NULL == (f = H5I_object(file_id))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (!name || !*name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (NULL == (grp = H5G_open(f, name))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_NOTFOUND, FAIL, "no such group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Set the current working group */
|
|
|
|
|
if (H5G_set(f, grp) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"unable to change current working group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Close the handle */
|
|
|
|
|
if (H5G_close(grp) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gpush
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Similar to H5Gset() except the new working group is pushed
|
|
|
|
|
* on a stack.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Each file handle maintains its own notion of the current
|
|
|
|
|
* working group. That is, if a single file is opened with
|
|
|
|
|
* multiple calls to H5Fopen(), which returns multiple file
|
|
|
|
|
* handles, then each handle's current working group can be
|
|
|
|
|
* set independently of the other file handles for that file.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* See also: H5Gset(), H5Gpop()
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gpush(hid_t file_id, const char *name)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5F_t *f = NULL;
|
|
|
|
|
H5G_t *grp;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5Gpush, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check arguments */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_FILE != H5I_group(file_id) ||
|
|
|
|
|
NULL == (f = H5I_object(file_id))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (!name || !*name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (NULL == (grp = H5G_open(f, name))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_NOTFOUND, FAIL, "no such group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Push group onto stack */
|
|
|
|
|
if (H5G_push(f, grp) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"can't change current working group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* Close the handle */
|
|
|
|
|
if (H5G_close(grp) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5Gpop
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Removes the top (latest) entry from the working group stack
|
|
|
|
|
* and sets the current working group to the previous value.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Each file handle maintains its own notion of the current
|
|
|
|
|
* working group. That is, if a single file is opened with
|
|
|
|
|
* multiple calls to H5Fopen(), which returns multiple file
|
|
|
|
|
* handles, then each handle's current working group can be
|
|
|
|
|
* set independently of the other file handles for that file.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* See also: H5Gset(), H5Gpush()
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL. The final entry cannot be popped from
|
|
|
|
|
* the group stack (but it can be changed
|
|
|
|
|
* with H5Gset()).
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5Gpop(hid_t file_id)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5F_t *f = NULL;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5Gpop, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check arguments */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5_FILE != H5I_group(file_id) ||
|
|
|
|
|
NULL == (f = H5I_object(file_id))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* pop */
|
|
|
|
|
if (H5G_pop(f) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"stack is empty");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
1998-03-24 22:53:57 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5Giterate
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Iterates over the entries of a group. The FILE_ID and NAME
|
|
|
|
|
* identify the group over which to iterate and INDEX indicates
|
|
|
|
|
* where to start iterating (zero means at the beginning). The
|
|
|
|
|
* OPERATOR is called for each member and the iteration
|
|
|
|
|
* continues until the operator returns non-zero or all members
|
|
|
|
|
* are processed. The operator is passed a group ID for the
|
|
|
|
|
* group being iterated, a member name, and OP_DATA for each
|
|
|
|
|
* member.
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: The return value of the first operator that
|
|
|
|
|
* returns non-zero, or zero if all members were
|
|
|
|
|
* processed with no operator returning non-zero.
|
|
|
|
|
*
|
|
|
|
|
* Failure: FAIL if something goes wrong within the
|
|
|
|
|
* library, or a negative value returned by one
|
|
|
|
|
* of the operators.
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, March 23, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
|
|
|
|
H5Giterate (hid_t file_id, const char *name, int *index,
|
|
|
|
|
H5G_iterate_t op, void *op_data)
|
|
|
|
|
{
|
|
|
|
|
H5F_t *f = NULL;
|
|
|
|
|
int _index = 0;
|
|
|
|
|
H5G_bt_ud2_t udata;
|
|
|
|
|
herr_t ret_value = FAIL;
|
|
|
|
|
|
|
|
|
|
FUNC_ENTER (H5Giterate, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check args */
|
|
|
|
|
if (H5_FILE!=H5I_group (file_id) ||
|
|
|
|
|
NULL==(f=H5I_object (file_id))) {
|
|
|
|
|
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
|
|
|
|
|
}
|
|
|
|
|
if (!name || !*name) {
|
|
|
|
|
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
|
|
|
|
|
}
|
|
|
|
|
if (!index) index = &_index;
|
|
|
|
|
if (!op) {
|
|
|
|
|
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Open the group on which to operate. We also create a group ID which
|
|
|
|
|
* we can pass to the application-defined operator.
|
|
|
|
|
*/
|
|
|
|
|
if (NULL==(udata.group = H5G_open (f, name))) {
|
|
|
|
|
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to open group");
|
|
|
|
|
}
|
|
|
|
|
if ((udata.group_id=H5I_register (H5_GROUP, udata.group))<0) {
|
|
|
|
|
H5G_close (udata.group);
|
|
|
|
|
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"unable to register group");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
|
|
|
|
|
udata.skip = *index;
|
|
|
|
|
udata.op = op;
|
|
|
|
|
udata.op_data = op_data;
|
|
|
|
|
|
|
|
|
|
/* Iterate over the group members */
|
|
|
|
|
if ((ret_value = H5B_iterate (f, H5B_SNODE,
|
|
|
|
|
&(udata.group->ent.cache.stab.btree_addr),
|
|
|
|
|
&udata))<0) {
|
|
|
|
|
HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed");
|
|
|
|
|
}
|
|
|
|
|
H5I_dec_ref (udata.group_id); /*also closes udata.group*/
|
|
|
|
|
FUNC_LEAVE (ret_value);
|
|
|
|
|
}
|
|
|
|
|
|
1997-10-21 07:14:35 +08:00
|
|
|
|
/*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
* N O A P I F U N C T I O N S B E Y O N D T H I S P O I N T
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_init_interface
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Initializes the H5G interface.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, January 5, 1998
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_init_interface(void)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_init_interface, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Initialize the atom group for the group IDs */
|
1998-03-18 06:46:27 +08:00
|
|
|
|
if (H5I_init_group(H5_GROUP, H5I_GROUPID_HASHSIZE, H5G_RESERVED_ATOMS,
|
1998-01-23 00:41:32 +08:00
|
|
|
|
(herr_t (*)(void *)) H5G_close) < 0 ||
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5_add_exit(H5G_term_interface) < 0) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"unable to initialize interface");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_term_interface
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Terminates the H5G interface
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: void
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, January 5, 1998
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static void
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_term_interface(void)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-03-18 06:46:27 +08:00
|
|
|
|
H5I_destroy_group(H5_GROUP);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_component
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* 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-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: Ptr into NAME.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: Ptr to the null terminator of NAME.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* matzke@llnl.gov
|
|
|
|
|
* Aug 11 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-17 06:23:43 +08:00
|
|
|
|
static const char *
|
|
|
|
|
H5G_component(const char *name, size_t *size_p)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
assert(name);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
while ('/' == *name)
|
1998-01-28 13:47:19 +08:00
|
|
|
|
name++;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
if (size_p)
|
1998-01-28 13:47:19 +08:00
|
|
|
|
*size_p = HDstrcspn(name, "/");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
return name;
|
|
|
|
|
}
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_namei
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Translates a name to a symbol table entry.
|
|
|
|
|
*
|
|
|
|
|
* If the specified name can be fully resolved, then this
|
|
|
|
|
* function returns the symbol table entry for the named object
|
|
|
|
|
* through the OBJ_ENT argument. The symbol table entry for the
|
|
|
|
|
* group containing the named object is returned through the
|
|
|
|
|
* GRP_ENT argument if it is non-null. However, if the name
|
|
|
|
|
* refers to the root object then the GRP_ENT will be
|
|
|
|
|
* initialized with an undefined object header address. The
|
|
|
|
|
* REST argument, if present, will point to the null terminator
|
|
|
|
|
* of NAME.
|
|
|
|
|
*
|
|
|
|
|
* If the specified name cannot be fully resolved, then OBJ_ENT
|
|
|
|
|
* is initialized with the undefined object header address. The
|
|
|
|
|
* REST argument will point into the NAME argument to the start
|
|
|
|
|
* of the component that could not be located. The GRP_ENT will
|
|
|
|
|
* contain the entry for the symbol table that was being
|
|
|
|
|
* searched at the time of the failure and will have an
|
|
|
|
|
* undefined object header address if the search failed at the
|
|
|
|
|
* root object. For instance, if NAME is `/foo/bar/baz' and the
|
|
|
|
|
* root directory exists and contains an entry for `foo', and
|
|
|
|
|
* foo is a group that contains an entry for baz, but baz is not
|
|
|
|
|
* a group, then the results will be that REST points to `baz',
|
|
|
|
|
* GRP_ENT has an undefined object header address, and GRP_ENT
|
|
|
|
|
* is the symbol table entry for `bar' in `/foo'.
|
|
|
|
|
*
|
|
|
|
|
* If a file contains more than one object, then `/' is the name
|
|
|
|
|
* of the root object which is a group. Otherwise, a file can
|
|
|
|
|
* consist of a single object, not necessarily a group, whose
|
|
|
|
|
* name is `/foo' where `foo' is the value of the name messsage
|
|
|
|
|
* in the object header. A file can also contain no objects in
|
|
|
|
|
* which case the function returns so REST points to the
|
|
|
|
|
* beginning of NAME and OBJ_ENT and GRP_ENT contain undefined
|
|
|
|
|
* header addresses.
|
|
|
|
|
*
|
|
|
|
|
* Components of a name are separated from one another by one or
|
|
|
|
|
* more slashes (/). Slashes at the end of a name are ignored.
|
|
|
|
|
* If the name begins with a slash then the search begins at the
|
|
|
|
|
* root object, otherwise it begins at the group CWG, otherwise
|
|
|
|
|
* it begins at the current working group of file F. The
|
|
|
|
|
* component `.' is a no-op, but `..' is not understood by this
|
|
|
|
|
* function (unless it appears as an entry in the symbol table).
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED if name can be fully resolved. See
|
|
|
|
|
* above for values of REST, GRP_ENT, and
|
|
|
|
|
* OBJ_ENT.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL if the name could not be fully resolved.
|
|
|
|
|
* See above for values of REST, GRP_ENT, and
|
|
|
|
|
* OBJ_ENT.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* matzke@llnl.gov
|
|
|
|
|
* Aug 11 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-06 11:07:15 +08:00
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_namei(H5F_t *f, H5G_entry_t *cwg, const char *name,
|
1998-03-24 22:53:57 +08:00
|
|
|
|
const char **rest/*out*/, H5G_entry_t *grp_ent/*out*/,
|
|
|
|
|
H5G_entry_t *obj_ent/*out*/)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-03-24 22:53:57 +08:00
|
|
|
|
H5G_entry_t _grp_ent; /*entry for current group */
|
|
|
|
|
H5G_entry_t _obj_ent; /*entry found */
|
|
|
|
|
size_t nchars; /*component name length */
|
|
|
|
|
char comp[1024]; /*component name buffer */
|
|
|
|
|
hbool_t aside = FALSE; /*did we look at a name message?*/
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
/* clear output args before FUNC_ENTER() in case it fails */
|
1998-03-24 22:53:57 +08:00
|
|
|
|
if (rest) *rest = name;
|
|
|
|
|
if (!grp_ent) grp_ent = &_grp_ent;
|
|
|
|
|
if (!obj_ent) obj_ent = &_obj_ent;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
memset(grp_ent, 0, sizeof(H5G_entry_t));
|
|
|
|
|
H5F_addr_undef(&(grp_ent->header));
|
|
|
|
|
memset(obj_ent, 0, sizeof(H5G_entry_t));
|
|
|
|
|
H5F_addr_undef(&(obj_ent->header));
|
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_namei, FAIL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(name && *name);
|
|
|
|
|
|
|
|
|
|
/* If the file contains no objects then return failure */
|
|
|
|
|
if (!f->shared->root_ent) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no root group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/* starting point */
|
|
|
|
|
if ('/' == *name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
*obj_ent = *(f->shared->root_ent);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else if (cwg) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
*obj_ent = *cwg;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else if ((cwg = H5G_getcwg(f))) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
*obj_ent = *cwg;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no current working group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
assert(H5F_addr_defined(&(obj_ent->header)));
|
|
|
|
|
|
|
|
|
|
/* traverse the name */
|
|
|
|
|
while ((name = H5G_component(name, &nchars)) && *name) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (rest)
|
|
|
|
|
*rest = name;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The special name `.' is a no-op.
|
|
|
|
|
*/
|
|
|
|
|
if ('.' == name[0] && !name[1])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Advance to the next component of the name.
|
|
|
|
|
*/
|
|
|
|
|
*grp_ent = *obj_ent;
|
|
|
|
|
HDmemset(obj_ent, 0, sizeof(H5G_entry_t));
|
|
|
|
|
H5F_addr_undef(&(obj_ent->header));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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)) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_COMPLEN, FAIL, "component is too long");
|
|
|
|
|
}
|
|
|
|
|
HDmemcpy(comp, name, nchars);
|
|
|
|
|
comp[nchars] = '\0';
|
|
|
|
|
|
|
|
|
|
if (H5G_stab_find(grp_ent, comp, obj_ent /*out */ ) < 0) {
|
|
|
|
|
/*
|
|
|
|
|
* Component was not found in the current symbol table, possibly
|
|
|
|
|
* because GRP_ENT isn't a symbol table. If it is the root symbol
|
|
|
|
|
* then 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'.
|
|
|
|
|
*/
|
|
|
|
|
H5O_name_t mesg =
|
|
|
|
|
{0};
|
|
|
|
|
if (!aside &&
|
|
|
|
|
H5F_addr_eq(&(grp_ent->header),
|
|
|
|
|
&(f->shared->root_ent->header)) &&
|
|
|
|
|
H5O_read(grp_ent, H5O_NAME, 0, &mesg) &&
|
|
|
|
|
!HDstrcmp(mesg.s, comp)) {
|
|
|
|
|
H5O_reset(H5O_NAME, &mesg);
|
|
|
|
|
*obj_ent = *grp_ent;
|
|
|
|
|
HDmemset(grp_ent, 0, sizeof(H5G_entry_t));
|
|
|
|
|
H5F_addr_undef(&(grp_ent->header));
|
|
|
|
|
aside = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
H5O_reset(H5O_NAME, &mesg);
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* next component */
|
|
|
|
|
name += nchars;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (rest)
|
1998-01-28 13:47:19 +08:00
|
|
|
|
*rest = name; /*final null */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_mkroot
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Creates the root group if it doesn't exist; otherwise
|
|
|
|
|
* nothing happens. If the root symbol table entry previously
|
|
|
|
|
* pointed to something other than a group, then that object
|
|
|
|
|
* is made a member of the root group 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
|
|
|
|
|
* then the name `Root Object' is used.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
* Errors:
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL. This function returns -2 if the
|
|
|
|
|
* failure is because a root group already
|
|
|
|
|
* exists.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* matzke@llnl.gov
|
|
|
|
|
* Aug 11 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1997-08-29 00:37:58 +08:00
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_mkroot(H5F_t *f, size_t size_hint)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
herr_t ret_value = FAIL; /*return value */
|
|
|
|
|
H5O_name_t name =
|
|
|
|
|
{NULL}; /*object name */
|
|
|
|
|
H5O_stab_t stab; /*symbol table message */
|
|
|
|
|
H5G_entry_t new_root; /*new root object */
|
|
|
|
|
const char *obj_name = NULL; /*name of old root object */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_mkroot, FAIL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If we already have a root object, then get it's name.
|
|
|
|
|
*/
|
|
|
|
|
if (f->shared->root_ent) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (H5O_read(f->shared->root_ent, H5O_STAB, 0, &stab)) {
|
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, -2, "root group already exists");
|
|
|
|
|
} else if (NULL == H5O_read(f->shared->root_ent, H5O_NAME, 0, &name)) {
|
|
|
|
|
obj_name = "Root Object";
|
|
|
|
|
} else {
|
|
|
|
|
obj_name = name.s; /*don't reset message until the end! */
|
|
|
|
|
}
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Create the new root group. Set the link count to 1.
|
|
|
|
|
*/
|
|
|
|
|
if (H5G_stab_create(f, size_hint, &new_root /*out */ ) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cant create root");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (1 != H5O_link(&new_root, 1)) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL,
|
|
|
|
|
"internal error (wrong link count)");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* If there was a previous root object then insert it into the new root
|
|
|
|
|
* symbol table with the specified name. Then make the root object the
|
|
|
|
|
* new symbol table.
|
|
|
|
|
*/
|
|
|
|
|
if (f->shared->root_ent) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
assert(1 == H5O_link(f->shared->root_ent, 0));
|
|
|
|
|
|
|
|
|
|
if (H5G_stab_insert(&new_root, obj_name, f->shared->root_ent) < 0) {
|
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"can't reinsert old root object");
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* 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->shared->root_ent, H5O_NAME, H5O_ALL);
|
1998-03-01 02:19:05 +08:00
|
|
|
|
H5E_clear(); /*who really cares? */
|
1998-01-28 13:47:19 +08:00
|
|
|
|
|
|
|
|
|
*(f->shared->root_ent) = new_root;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
} else {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
f->shared->root_ent = H5G_ent_calloc(&new_root);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
H5O_close(&new_root);
|
|
|
|
|
ret_value = SUCCEED;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
H5O_reset(H5O_NAME, &name);
|
|
|
|
|
FUNC_LEAVE(ret_value);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_create
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Creates a new empty group with the specified name. The name
|
|
|
|
|
* is either an absolute name or is relative to the current
|
|
|
|
|
* working group.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* A root group 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:
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: A handle for the group. The group is opened
|
|
|
|
|
* and should eventually be close by calling
|
|
|
|
|
* H5G_close().
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: NULL
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* matzke@llnl.gov
|
|
|
|
|
* Aug 11 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-03-24 22:53:57 +08:00
|
|
|
|
H5G_t *
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_create(H5F_t *f, const char *name, size_t size_hint)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-03-24 22:53:57 +08:00
|
|
|
|
const char *rest = NULL; /*the base name */
|
|
|
|
|
H5G_entry_t grp_ent; /*group containing new group */
|
|
|
|
|
char _comp[1024]; /*name component */
|
|
|
|
|
size_t nchars; /*number of characters in compon*/
|
|
|
|
|
herr_t status; /*function return status */
|
|
|
|
|
H5G_t *grp = NULL; /*new group */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_create, NULL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(name && *name);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Try to create the root group. Ignore the error if this function
|
|
|
|
|
* fails because the root group already exists.
|
|
|
|
|
*/
|
1998-03-24 22:53:57 +08:00
|
|
|
|
if ((status=H5G_mkroot(f, H5G_SIZE_HINT))<0 && -2!=status) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create root group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-01 02:19:05 +08:00
|
|
|
|
H5E_clear();
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
/* lookup name */
|
|
|
|
|
if (0 == H5G_namei(f, NULL, name, &rest, &grp_ent, NULL)) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, NULL, "already exists");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-01 02:19:05 +08:00
|
|
|
|
H5E_clear(); /*it's OK that we didn't find it */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
assert(H5F_addr_defined(&(grp_ent.header)));
|
|
|
|
|
|
|
|
|
|
/* should be one null-terminated component left */
|
|
|
|
|
rest = H5G_component(rest, &nchars);
|
|
|
|
|
assert(rest && *rest);
|
|
|
|
|
if (rest[nchars]) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (H5G_component(rest + nchars, NULL)) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "missing component");
|
|
|
|
|
} else if (nchars + 1 > sizeof _comp) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_COMPLEN, NULL, "component is too long");
|
|
|
|
|
} else {
|
|
|
|
|
/* null terminate */
|
|
|
|
|
HDmemcpy(_comp, rest, nchars);
|
|
|
|
|
_comp[nchars] = '\0';
|
|
|
|
|
rest = _comp;
|
|
|
|
|
}
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-24 22:53:57 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
/* create an open group */
|
|
|
|
|
grp = H5MM_xcalloc(1, sizeof(H5G_t));
|
1998-03-24 22:53:57 +08:00
|
|
|
|
if (H5G_stab_create(f, size_hint, &(grp->ent)/*out*/) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
grp = H5MM_xfree(grp);
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-24 22:53:57 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
/* insert child name into parent */
|
|
|
|
|
if (H5G_stab_insert(&grp_ent, rest, &(grp->ent)) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5O_close(&(grp->ent));
|
|
|
|
|
grp = H5MM_xfree(grp);
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't insert");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
grp->nref = 1;
|
|
|
|
|
FUNC_LEAVE(grp);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_open
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Opens an existing group. The group should eventually be
|
|
|
|
|
* closed by calling H5G_close().
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: Ptr to a new group.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: NULL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, January 5, 1998
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-02-27 02:05:27 +08:00
|
|
|
|
H5G_t *
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_open(H5F_t *f, const char *name)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-02-27 02:05:27 +08:00
|
|
|
|
H5G_t *grp = NULL;
|
|
|
|
|
H5G_t *ret_value = NULL;
|
|
|
|
|
H5O_stab_t mesg;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_open, NULL);
|
|
|
|
|
|
|
|
|
|
/* Check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(name && *name);
|
|
|
|
|
|
1998-02-27 02:05:27 +08:00
|
|
|
|
/* Open the object, making sure it's a group */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
grp = H5MM_xcalloc(1, sizeof(H5G_t));
|
|
|
|
|
if (H5G_find(f, name, NULL, &(grp->ent)) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "group not found");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (H5O_open(f, &(grp->ent)) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-02-27 02:05:27 +08:00
|
|
|
|
if (NULL==H5O_read (&(grp->ent), H5O_STAB, 0, &mesg)) {
|
|
|
|
|
H5O_close (&(grp->ent));
|
|
|
|
|
HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group");
|
|
|
|
|
}
|
1998-01-17 06:23:43 +08:00
|
|
|
|
grp->nref = 1;
|
|
|
|
|
ret_value = grp;
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (!ret_value && grp) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5MM_xfree(grp);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(ret_value);
|
1997-09-20 00:36:59 +08:00
|
|
|
|
}
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_reopen
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Reopens a group by incrementing the open count.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: The GRP argument.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: NULL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, January 5, 1998
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_t *
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_reopen(H5G_t *grp)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_reopen, NULL);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
assert(grp);
|
|
|
|
|
assert(grp->nref > 0);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
grp->nref++;
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_LEAVE(grp);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_close
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Closes the specified group.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, January 5, 1998
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_close(H5G_t *grp)
|
1998-01-06 11:07:15 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_close, FAIL);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
/* Check args */
|
|
|
|
|
assert(grp);
|
|
|
|
|
assert(grp->nref > 0);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
if (1 == grp->nref) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (H5O_close(&(grp->ent)) < 0) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
|
|
|
|
|
}
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
--grp->nref;
|
1998-01-06 11:07:15 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1998-01-06 11:07:15 +08:00
|
|
|
|
}
|
1997-09-20 00:36:59 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_set
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Sets the current working group to be the specified group.
|
|
|
|
|
* This affects only the top item on the group stack for the
|
|
|
|
|
* specified file as accessed through this file handle. If the
|
|
|
|
|
* file is opened multiple times, then the current working group
|
|
|
|
|
* for this file handle is the only one that is changed.
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Note: The group is re-opened and held open until it is removed from
|
|
|
|
|
* the current working group stack.
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1997-10-21 07:14:35 +08:00
|
|
|
|
* Errors:
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* SYM CWG Can't open group.
|
|
|
|
|
* SYM CWG Couldn't close previous c.w.g.
|
|
|
|
|
* SYM CWG Not a group.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_set(H5F_t *f, H5G_t *grp)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_set, FAIL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(grp);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If there is no stack then create one, otherwise close the current
|
|
|
|
|
* working group.
|
|
|
|
|
*/
|
|
|
|
|
if (!f->cwg_stack) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
f->cwg_stack = H5MM_xcalloc(1, sizeof(H5G_cwgstk_t));
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else if (H5G_close(f->cwg_stack->grp) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CWG, FAIL, "couldn't close previous c.w.g.");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
f->cwg_stack->grp = H5G_reopen(grp);
|
|
|
|
|
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-10-21 07:14:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_getcwg
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Returns a ptr to the symbol table entry for the current
|
|
|
|
|
* working group. If there is no current working group then a
|
|
|
|
|
* pointer to the root symbol is returned. If there is no root
|
|
|
|
|
* symbol then the null pointer is returned.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: Ptr to the current working group or root
|
|
|
|
|
* object. The pointer is valid only until the
|
|
|
|
|
* root object changes or the current working
|
|
|
|
|
* group changes.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: NULL
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, September 24, 1997
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-17 06:23:43 +08:00
|
|
|
|
static H5G_entry_t *
|
|
|
|
|
H5G_getcwg(H5F_t *f)
|
1997-10-21 07:14:35 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_entry_t *ret_value = NULL;
|
1997-10-21 07:14:35 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_getcwg, NULL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
|
|
|
|
|
/* return a pointer directly into the stack */
|
|
|
|
|
if (f->cwg_stack && f->cwg_stack->grp) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
ret_value = &(f->cwg_stack->grp->ent);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
ret_value = f->shared->root_ent;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FUNC_LEAVE(ret_value);
|
|
|
|
|
}
|
1997-10-21 07:14:35 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_push
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Pushes a new current working group onto the stack. The GRP
|
|
|
|
|
* is reopened and held open until it is removed from the stack.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* SYM CWG Can't open group.
|
|
|
|
|
* SYM CWG Not a group.
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Friday, September 19, 1997
|
1997-09-20 00:36:59 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_push(H5F_t *f, H5G_t *grp)
|
1997-09-20 00:36:59 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_cwgstk_t *stack = NULL;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_push, FAIL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(grp);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Push a new entry onto the stack.
|
|
|
|
|
*/
|
|
|
|
|
stack = H5MM_xcalloc(1, sizeof(H5G_cwgstk_t));
|
|
|
|
|
stack->grp = H5G_reopen(grp);
|
|
|
|
|
stack->next = f->cwg_stack;
|
|
|
|
|
f->cwg_stack = stack;
|
1997-09-20 00:36:59 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
|
|
|
|
}
|
1997-08-13 06:44:46 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_pop
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Pops the top current working group off the stack.
|
1997-10-21 07:14:35 +08:00
|
|
|
|
*
|
|
|
|
|
* Errors:
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* SYM CWG Can't close current working group.
|
|
|
|
|
* SYM CWG Stack is empty.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL if the stack is empty.
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* 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
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_pop(H5F_t *f)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_cwgstk_t *stack = NULL;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_pop, FAIL);
|
|
|
|
|
|
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
|
|
|
|
|
if ((stack = f->cwg_stack)) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (H5G_close(stack->grp) < 0) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CWG, FAIL,
|
|
|
|
|
"can't close current working group");
|
|
|
|
|
}
|
|
|
|
|
f->cwg_stack = stack->next;
|
|
|
|
|
stack->grp = NULL;
|
|
|
|
|
H5MM_xfree(stack);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
} else {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CWG, FAIL, "stack is empty");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-08-13 06:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Function: H5G_insert
|
1997-08-13 23:36:47 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Purpose: Inserts a symbol table entry into the group graph. The file
|
|
|
|
|
* that is used is contained in the ENT argument.
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*
|
1997-10-21 07:14:35 +08:00
|
|
|
|
* Errors:
|
1998-01-06 11:07:15 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Friday, September 19, 1997
|
1997-08-13 06:44:46 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
1997-09-02 23:38:26 +08:00
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-01-06 11:07:15 +08:00
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_insert(const char *name, H5G_entry_t *ent)
|
1997-08-13 06:44:46 +08:00
|
|
|
|
{
|
1998-01-28 13:47:19 +08:00
|
|
|
|
const char *rest = NULL; /*part of name not existing yet */
|
|
|
|
|
H5G_entry_t grp; /*entry for group to contain obj */
|
|
|
|
|
size_t nchars; /*number of characters in name */
|
|
|
|
|
char _comp[1024]; /*name component */
|
|
|
|
|
hbool_t update_grp;
|
|
|
|
|
herr_t status;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER(H5G_insert, FAIL);
|
|
|
|
|
|
|
|
|
|
/* Check args. */
|
|
|
|
|
assert(name && *name);
|
|
|
|
|
assert(ent);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Look up the name -- it shouldn't exist yet.
|
|
|
|
|
*/
|
|
|
|
|
if (H5G_namei(ent->file, NULL, name, &rest, &grp, NULL) >= 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-01 02:19:05 +08:00
|
|
|
|
H5E_clear(); /*it's OK that we didn't find it */
|
1998-01-17 06:23:43 +08:00
|
|
|
|
rest = H5G_component(rest, &nchars);
|
|
|
|
|
|
|
|
|
|
if (!rest || !*rest) {
|
1998-01-28 13:47:19 +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.
|
|
|
|
|
*/
|
|
|
|
|
if (ent->file->shared->root_ent) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "root exists");
|
|
|
|
|
}
|
|
|
|
|
if (1 != H5O_link(ent, 1)) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_LINK, FAIL, "bad link count");
|
|
|
|
|
}
|
|
|
|
|
ent->name_off = 0;
|
|
|
|
|
ent->file->shared->root_ent = H5G_ent_calloc(ent);
|
|
|
|
|
HRETURN(SUCCEED);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* There should be one component left. Make sure it's null
|
|
|
|
|
* terminated.
|
|
|
|
|
*/
|
|
|
|
|
if (rest[nchars]) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
if (H5G_component(rest + nchars, NULL)) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
|
|
|
|
|
} else if (nchars + 1 > sizeof _comp) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_COMPLEN, FAIL, "component is too long");
|
|
|
|
|
} else {
|
|
|
|
|
/* null terminate */
|
|
|
|
|
HDmemcpy(_comp, rest, nchars);
|
|
|
|
|
_comp[nchars] = '\0';
|
|
|
|
|
rest = _comp;
|
|
|
|
|
}
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (!ent->file->shared->root_ent) {
|
1998-01-28 13:47:19 +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).
|
|
|
|
|
*/
|
|
|
|
|
H5O_name_t name_mesg;
|
|
|
|
|
name_mesg.s = rest;
|
|
|
|
|
if (H5O_modify(ent, H5O_NAME, 0, 0, &name_mesg) < 0) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
|
|
|
|
|
"cannot add/change name message");
|
|
|
|
|
}
|
|
|
|
|
if (1 != H5O_link(ent, 1)) {
|
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_LINK, FAIL, "bad link count");
|
|
|
|
|
}
|
|
|
|
|
ent->file->shared->root_ent = H5G_ent_calloc(ent);
|
|
|
|
|
HRETURN(SUCCEED);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
/*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Make sure the root group exists. Ignore the failure if it's
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* because the group already exists.
|
|
|
|
|
*/
|
1998-01-29 04:24:49 +08:00
|
|
|
|
update_grp = (hbool_t)H5F_addr_eq(&(grp.header),
|
1998-01-28 13:47:19 +08:00
|
|
|
|
&(ent->file->shared->root_ent->header));
|
1998-01-17 06:23:43 +08:00
|
|
|
|
if ((status = H5G_mkroot(ent->file, H5G_SIZE_HINT)) < 0 && -2 != status) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create root group");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
1998-03-01 02:19:05 +08:00
|
|
|
|
H5E_clear();
|
1998-01-29 04:24:49 +08:00
|
|
|
|
if (update_grp==TRUE)
|
1998-01-28 13:47:19 +08:00
|
|
|
|
grp = *(ent->file->shared->root_ent);
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
/*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* This is the normal case. The object is just being inserted as a normal
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* entry into a symbol table.
|
|
|
|
|
*/
|
|
|
|
|
if (H5O_link(ent, 1) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_LINK, FAIL, "link inc failure");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
if (H5G_stab_insert(&grp, rest, ent) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* 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 the current working group. On successful return,
|
|
|
|
|
* GRP_ENT (if non-null) will be initialized with the symbol
|
|
|
|
|
* table information for the group in which the object
|
|
|
|
|
* appears (it will have an undefined object header address if
|
|
|
|
|
* the object is the root object) and OBJ_ENT will be
|
|
|
|
|
* initialized with the symbol table entry for the object
|
|
|
|
|
* (OBJ_ENT is optional when the caller is interested only in
|
|
|
|
|
* the existence of the object).
|
|
|
|
|
*
|
|
|
|
|
* 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:
|
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Return: Success: SUCCEED, see above for values of GRP_ENT and
|
|
|
|
|
* OBJ_ENT.
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Failure: FAIL
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
1998-01-28 13:47:19 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* matzke@llnl.gov
|
|
|
|
|
* Aug 12 1997
|
1997-07-31 05:17:56 +08:00
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
H5G_find(H5F_t *f, const char *name,
|
1998-01-28 13:47:19 +08:00
|
|
|
|
H5G_entry_t *grp_ent /*out */ , H5G_entry_t *obj_ent /*out */ )
|
1997-07-31 05:17:56 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
FUNC_ENTER(H5G_find, FAIL);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
/* check args */
|
|
|
|
|
assert(f);
|
|
|
|
|
assert(name && *name);
|
1997-08-08 03:23:00 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
if (H5G_namei(f, NULL, name, NULL, grp_ent, obj_ent) < 0) {
|
1998-01-28 13:47:19 +08:00
|
|
|
|
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
}
|
|
|
|
|
FUNC_LEAVE(SUCCEED);
|
1997-07-31 05:17:56 +08:00
|
|
|
|
}
|