/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Programmer: Robb Matzke <matzke@llnl.gov>
* Friday, September 19, 1997
*
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5G_PACKAGE /*suppress error about including H5Gpkg */
/* Packages needed by this file... */
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
#include "H5MMprivate.h" /* Memory management */
/* Private prototypes */
/*-------------------------------------------------------------------------
* Function: H5G_stab_create
*
* Purpose: Creates a new empty symbol table (object header, name heap,
* and B-tree). The caller can specify an initial size for the
* name heap. The object header of the group is opened for
* write access.
*
* In order for the B-tree to operate correctly, the first
* item in the heap is the empty string, and must appear at
* heap offset zero.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Aug 1 1997
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_create(H5F_t *f, hid_t dxpl_id, size_t init, H5G_entry_t *self/*out*/)
{
size_t name_offset; /* Offset of "" name */
H5O_stab_t stab; /*symbol table message */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_create, FAIL)
/*
* Check arguments.
*/
HDassert(f);
HDassert(self);
init = MAX(init, H5HL_SIZEOF_FREE(f) + 2);
/* Create symbol table private heap */
if(H5HL_create(f, dxpl_id, init, &(stab.heap_addr)/*out*/)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
name_offset = H5HL_insert(f, dxpl_id, stab.heap_addr, 1, "");
if((size_t)(-1) == name_offset)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
/*
* B-tree's won't work if the first name isn't at the beginning
* of the heap.
*/
HDassert(0 == name_offset);
/* Create the B-tree */
if (H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab.btree_addr)/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
/*
* Create symbol table object header. It has a zero link count
* since nothing refers to it yet. The link count will be
* incremented if the object is added to the group directed graph.
*/
if (H5O_create(f, dxpl_id, 4 + 2 * H5F_SIZEOF_ADDR(f), self/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header")
/*
* Insert the symbol table message into the object header and the symbol
* table entry.
*/
if (H5O_modify(self, H5O_STAB_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, &stab, dxpl_id)<0) {
H5O_close(self);
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
}
self->cache.stab.btree_addr = stab.btree_addr;
self->cache.stab.heap_addr = stab.heap_addr;
self->type = H5G_CACHED_STAB;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_create() */
/*-------------------------------------------------------------------------
* Function: H5G_stab_find
*
* Purpose: Finds a symbol named NAME in the symbol table whose
* description is stored in GRP_ENT in file F and returns its
* symbol table entry through OBJ_ENT (which is optional).
*
* Errors:
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
*
* Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
* Added `id to name' support.
* Added a deep copy of the symbol table entry
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id)
{
H5G_bt_ud1_t udata; /*data to pass through B-tree */
H5O_stab_t stab; /*symbol table message */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_find, FAIL)
/* Check arguments */
assert(grp_ent);
assert(grp_ent->file);
assert(obj_ent);
assert(name && *name);
/* set up the udata */
if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
udata.common.name = name;
udata.common.heap_addr = stab.heap_addr;
udata.ent = obj_ent;
/* search the B-tree */
if (H5B_find(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
/* Set the name for the symbol entry OBJ_ENT */
if (H5G_name_set( grp_ent, obj_ent, name ) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_find() */
/*-------------------------------------------------------------------------
* Function: H5G_stab_insert
*
* Purpose: Insert a new symbol into the table described by GRP_ENT in
* file F. The name of the new symbol is NAME and its symbol
* table entry is OBJ_ENT.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Aug 1 1997
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent,
hbool_t inc_link, hid_t dxpl_id)
{
H5O_stab_t stab; /* Symbol table message */
H5G_bt_ud1_t udata; /*data to pass through B-tree */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_insert, FAIL)
/* check arguments */
HDassert(grp_ent && grp_ent->file);
HDassert(name && *name);
HDassert(obj_ent && obj_ent->file);
if(grp_ent->file->shared != obj_ent->file->shared)
HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed")
/* initialize data to pass through B-tree */
if(NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
udata.common.name = name;
udata.common.heap_addr = stab.heap_addr;
udata.ent = obj_ent;
/* insert */
if(H5B_insert(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
/* Set the name for the symbol entry OBJ_ENT */
if(H5G_name_set(grp_ent, obj_ent, name) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
/* Increment link count on object, if appropriate */
if(inc_link)
if (H5O_link(obj_ent, 1, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_insert() */
/*-------------------------------------------------------------------------
* Function: H5G_stab_remove
*
* Purpose: Remove NAME from a symbol table.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Thursday, September 17, 1998
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id)
{
H5O_stab_t stab; /*symbol table message */
H5G_bt_ud2_t udata; /*data to pass through B-tree */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL)
HDassert(grp_ent && grp_ent->file);
HDassert(name && *name);
/* initialize data to pass through B-tree */
if(NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
/* Initialize data to pass through B-tree */
udata.common.name = name;
udata.common.heap_addr = stab.heap_addr;
udata.adj_link = TRUE;
/* Remove */
if(H5B_remove(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_remove() */
/*-------------------------------------------------------------------------
* Function: H5G_stab_delete
*
* Purpose: Delete entire symbol table information from file
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, March 20, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, hbool_t adj_link)
{
H5G_bt_ud2_t udata; /*data to pass through B-tree */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5G_stab_delete, FAIL);
assert(f);
assert(stab);
assert(H5F_addr_defined(stab->btree_addr));
assert(H5F_addr_defined(stab->heap_addr));
/* Set up user data for B-tree deletion */
udata.common.name = NULL;
udata.common.heap_addr = stab->heap_addr;
udata.adj_link = adj_link;
/* Delete entire B-tree */
if(H5B_delete(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table B-tree");
/* Delete local heap for names */
if(H5HL_delete(f, dxpl_id, stab->heap_addr)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table heap");
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5G_stab_delete() */
syntax highlighted by Code2HTML, v. 0.9.1