summaryrefslogtreecommitdiffstats
path: root/src/H5Gstab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Gstab.c')
-rw-r--r--src/H5Gstab.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
new file mode 100644
index 0000000..209cbc4
--- /dev/null
+++ b/src/H5Gstab.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 1997 National Center for Supercomputing Applications
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Friday, September 19, 1997
+ *
+ */
+#define H5G_PACKAGE
+
+#include <H5private.h>
+#include <H5ACprivate.h>
+#include <H5Eprivate.h>
+#include <H5Gpkg.h>
+#include <H5Hprivate.h>
+#include <H5MMprivate.h>
+#include <H5Oprivate.h>
+
+#define PABLO_MASK H5G_stab_mask
+static hbool_t interface_initialize_g = FALSE;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_new
+ *
+ * Purpose: Creates a new empty symbol table (object header, name heap,
+ * and B-tree). The caller can specify an initial size for the
+ * name heap.
+ *
+ * In order for the B-tree to operate correctly, the first
+ * item in the heap is the empty string, and must appear at
+ * heap offset zero.
+ *
+ * Errors:
+ * INTERNAL CANTINIT B-tree's won't work if the first
+ * name isn't at the beginning of the
+ * heap.
+ * SYM CANTINIT Can't create B-tree.
+ * SYM CANTINIT Can't create header.
+ * SYM CANTINIT Can't create heap.
+ * SYM CANTINIT Can't create message.
+ * SYM CANTINIT Can't initialize heap.
+ *
+ * Return: Success: Address of new symbol table header. If
+ * the caller supplies a symbol table entry
+ * SELF then it will be initialized to point to
+ * this symbol table.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5G_stab_new (hdf5_file_t *f, H5G_entry_t *self, size_t init)
+{
+ off_t name; /*offset of "" name */
+ haddr_t addr; /*object header address */
+ H5O_stab_t stab; /*symbol table message */
+
+ FUNC_ENTER (H5G_stab_new, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ init = MAX(init, H5H_SIZEOF_FREE(f)+2);
+
+ /* Create symbol table private heap */
+ if ((stab.heap_addr = H5H_new (f, H5H_LOCAL, init))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create heap*/
+ }
+ if ((name = H5H_insert (f, stab.heap_addr, 1, "")<0)) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't initialize heap*/
+ }
+ if (0!=name) {
+ /*
+ * B-tree's won't work if the first name isn't at the beginning
+ * of the heap.
+ */
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
+ }
+
+ /* Create the B-tree */
+ if ((stab.btree_addr = H5B_new (f, H5B_SNODE))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create B-tree*/
+ }
+
+ /*
+ * Create symbol table object header. It has a zero link count
+ * since nothing refers to it yet. The link count will be
+ * incremented if the object is added to the directory hierarchy.
+ */
+ if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
+ }
+
+ /* insert the symbol table message */
+ if (self) {
+ memset (self, 0, sizeof(H5G_entry_t));
+ self->header = addr;
+ }
+ if (H5O_modify(f, addr, self, H5O_STAB, H5O_NEW_MESG, &stab)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create message*/
+ }
+
+ FUNC_LEAVE (addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_find
+ *
+ * Purpose: Finds a symbol named NAME in the symbol table whose
+ * description is stored in SELF in file F and returns a
+ * pointer to the symbol table entry. SELF is optional if the
+ * symbol table address is supplied through ADDR.
+ *
+ * Errors:
+ * SYM BADMESG Can't read message.
+ * SYM NOTFOUND Not found.
+ *
+ * Return: Success: Pointer to the symbol table entry.
+ * The pointer is intended for immediate
+ * read-only access since it points
+ * directly to an entry in a cached
+ * symbol table node. The pointer is
+ * guaranteed to be valid only until the
+ * next call to one of the H5AC functions.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_entry_t *
+H5G_stab_find (hdf5_file_t *f, haddr_t addr, H5G_entry_t *self,
+ const char *name)
+{
+ H5G_bt_ud1_t udata; /*data to pass through B-tree */
+ H5O_stab_t stab; /*symbol table message */
+
+ FUNC_ENTER (H5G_stab_find, NULL, NULL);
+
+ /* Check arguments */
+ assert (f);
+ if (addr<=0 && (!self || self->header<=0)) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
+ }
+ if (addr<=0) addr = self->header;
+
+ /* set up the udata */
+ if (NULL==H5O_read (f, addr, self, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, NULL); /*can't read message*/
+ }
+ udata.operation = H5G_OPER_FIND;
+ udata.name = name;
+ udata.heap_addr = stab.heap_addr;
+ udata.dir_addr = addr;
+ udata.node_ptr = NULL;
+
+ /* search the B-tree */
+ if (H5B_find (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
+ if (udata.node_ptr) {
+ H5AC_unprotect (f, H5AC_SNODE, udata.node_addr, udata.node_ptr);
+ }
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, NULL); /*not found*/
+ }
+
+ /* Unprotect the symbol table node */
+ if (udata.node_ptr) {
+ if (H5AC_unprotect (f, H5AC_SNODE, udata.node_addr, udata.node_ptr)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_PROTECT, NULL);
+ }
+ }
+
+ /* return the result */
+ FUNC_LEAVE (udata.entry_ptr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_insert
+ *
+ * Purpose: Insert a new symbol into the table described by SELF in
+ * file F. The name of the new symbol is NAME and its symbol
+ * table entry is ENT.
+ *
+ * Errors:
+ * SYM BADMESG Can't read message.
+ * SYM CANTINSERT Can't insert entry.
+ *
+ * Return: Success: Pointer to the cached symbol table entry.
+ * This is a pointer directly into a symbol
+ * table node and will become invalid on the
+ * next call to the H5AC package.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ * Robb Matzke, 18 Sep 1997
+ * If ENT has a shadow, then the shadow will be associated with the
+ * entry when it is added to the symbol table.
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_entry_t *
+H5G_stab_insert (hdf5_file_t *f, H5G_entry_t *self, const char *name,
+ H5G_entry_t *ent)
+{
+ H5O_stab_t stab; /*symbol table message */
+ H5G_bt_ud1_t udata; /*data to pass through B-tree */
+
+ FUNC_ENTER (H5G_stab_insert, NULL, NULL);
+
+ /* check arguments */
+ assert (f);
+ assert (self && self->header>=0);
+ assert (name && *name);
+ assert (ent);
+
+ /* initialize data to pass through B-tree */
+ if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, NULL); /*can't read message*/
+ }
+
+ udata.operation = H5G_OPER_INSERT;
+ udata.name = name;
+ udata.heap_addr = stab.heap_addr;
+ udata.dir_addr = self->header;
+ udata.entry = *ent;
+ udata.entry.name_off = -1;
+ udata.node_ptr = NULL;
+
+ /* insert */
+ if (H5B_insert (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
+ if (udata.node_ptr) {
+ H5AC_unprotect (f, H5AC_SNODE, udata.node_addr, udata.node_ptr);
+ }
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, NULL); /*can't insert entry*/
+ }
+
+ /*
+ * The H5G_node_insert() called H5AC_protect() for the node so that the
+ * udata.entry_ptr field didn't become invalid on the way back out of the
+ * B-tree code. We unprotect it now, but the pointer will remain valid
+ * until the next call to H5AC.
+ */
+ if (H5AC_unprotect (f, H5AC_SNODE, udata.node_addr, udata.node_ptr)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_PROTECT, NULL); /*can't unprotect*/
+ }
+
+ /* update the name offset in the entry */
+ ent->name_off = udata.entry.name_off;
+ FUNC_LEAVE (udata.entry_ptr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_list
+ *
+ * Purpose: Returns a list of all the symbols in a symbol table.
+ * The caller allocates an array of pointers which this
+ * function will fill in with malloc'd names. The caller
+ * also allocates an array of symbol table entries which will
+ * be filled in with data from the symbol table. Each of these
+ * arrays should have at least MAXENTRIES elements.
+ *
+ * Errors:
+ * SYM BADMESG Not a symbol table.
+ * SYM CANTLIST B-tree list failure.
+ *
+ * Return: Success: The total number of symbols in the
+ * symbol table. This may exceed MAXENTRIES,
+ * but at most MAXENTRIES values are copied
+ * into the NAMES and ENTRIES arrays.
+ *
+ * Failure: FAIL, the pointers in NAMES are undefined but
+ * no memory is allocated. The values in
+ * ENTRIES are undefined.
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5G_stab_list (hdf5_file_t *f, H5G_entry_t *self, intn maxentries,
+ char *names[], H5G_entry_t entries[])
+{
+ H5G_bt_ud2_t udata;
+ H5O_stab_t stab;
+ intn i;
+
+ FUNC_ENTER (H5G_stab_list, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (self && self->header>=0);
+ assert (maxentries>=0);
+
+ /* initialize data to pass through B-tree */
+ if (NULL==H5O_read (f, self->header, self, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL); /*not a symbol table*/
+ }
+ udata.entry = entries;
+ udata.name = names;
+ udata.dir_addr = self->header;
+ udata.heap_addr = stab.heap_addr;
+ udata.maxentries = maxentries;
+ udata.nsyms = 0;
+ if (names) HDmemset (names, 0, maxentries);
+
+ /* list */
+ if (H5B_list (f, H5B_SNODE, stab.btree_addr, &udata)<0) {
+ if (names) {
+ for (i=0; i<maxentries; i++) H5MM_xfree (names[i]);
+ }
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLIST, FAIL); /*B-tree list failure*/
+ }
+
+ FUNC_LEAVE (udata.nsyms);
+}
+