summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-08-07 19:23:00 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-08-07 19:23:00 (GMT)
commita905a3a1e343d4507049c30512842957e2f6307c (patch)
treeaa01b7418431c48634458a028c2fe6fd354f1684
parentdd0fbd5b0060ebc7703da8eaab747f7a3025be2a (diff)
downloadhdf5-a905a3a1e343d4507049c30512842957e2f6307c.zip
hdf5-a905a3a1e343d4507049c30512842957e2f6307c.tar.gz
hdf5-a905a3a1e343d4507049c30512842957e2f6307c.tar.bz2
[svn-r15] ./src/H5AC.c
./src/H5ACprivate.h ./src/H5ACproto.h ./src/H5Bproto.h ./src/H5Gproto.h ./src/H5Hproto.h ./src/H5MFprivate.h ./src/H5MFproto.h ./src/H5MM.c ./src/H5MMprivate.h ./src/H5MMproto.h Changed my e-mail address. ./src/H5O.c NEW ./src/H5Onull.c NEW ./src/H5Ocont. NEW ./src/H5Ostab.c NEW New functions for dealing with object headers. The H5O.c is the generic stuff, and each particular message has a source file for the specific stuff. Use ./src/H5Ostab.c as a model for implementing other messages. ./src/Makefile ./src/test/Makefile Added new files ./src/debug.c Added debugging calls for object headers. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c ./src/H5MF.c Changed my e-mail address. Improved error handling. ./src/H5Eprivate.h ./src/H5Eproto.h Added more error symbols ./src/H5F.c Changed my e-mail address. Used macros for sizeof offsets and lengths. Added the interface initialization function to H5F_block_read() and H5F_block_write(). Updated H5F_debug() ./src/H5Fprivate.h Got rid of H5F_symbol_table_size(). Use H5G_SIZEOF_ENTRY() instead. Reformatted H5F_decode_offset() for readability. ./src/H5G.c Changed my e-mail address. Improved error handling. Replaced not_implemented_yet__*() with real functions from H5O. ./src/H5Gprivate.h Changed `symtab' to `stab' to be consistent with other stuff. ./src/H5H.c ./src/H5Hprivate.h Changed my e-mail address. Improved error handling. Added an extra argument to H5H_new() to indicate whether you want a global heap or a local heap. ./src/hdf5gen.h Added NELMTS() Fixed FUNC_ENTER() Rewrote FUNC_LEAVE() in terms of HRETURN(). ./src/hdf5meta.h Added `const' to the decode macros. ./src/hdf5pabl.h Added PABLO_SAVE() ./test/testhdf5.c ./test/testhdf5.h Added calls for object header testing. ./test/theap.c Turned off some output.
-rw-r--r--src/H5AC.c14
-rw-r--r--src/H5ACprivate.h2
-rw-r--r--src/H5ACproto.h2
-rw-r--r--src/H5B.c478
-rw-r--r--src/H5Bprivate.h4
-rw-r--r--src/H5Bproto.h2
-rw-r--r--src/H5Eprivate.h14
-rw-r--r--src/H5Eproto.h22
-rw-r--r--src/H5F.c37
-rw-r--r--src/H5Fprivate.h22
-rw-r--r--src/H5G.c297
-rw-r--r--src/H5Gnode.c313
-rw-r--r--src/H5Gprivate.h8
-rw-r--r--src/H5Gproto.h2
-rw-r--r--src/H5H.c306
-rw-r--r--src/H5Hprivate.h9
-rw-r--r--src/H5Hproto.h2
-rw-r--r--src/H5MF.c40
-rw-r--r--src/H5MFprivate.h2
-rw-r--r--src/H5MFproto.h2
-rw-r--r--src/H5MM.c12
-rw-r--r--src/H5MMprivate.h2
-rw-r--r--src/H5MMproto.h2
-rw-r--r--src/H5O.c1242
-rw-r--r--src/H5Ocont.c164
-rw-r--r--src/H5Onull.c33
-rw-r--r--src/H5Oprivate.h127
-rw-r--r--src/H5Oproto.h30
-rw-r--r--src/H5Ostab.c328
-rw-r--r--src/Makefile14
-rw-r--r--src/debug.c26
-rw-r--r--src/hdf5gen.h15
-rw-r--r--src/hdf5meta.h12
-rw-r--r--src/hdf5pabl.h6
34 files changed, 3155 insertions, 436 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index 3a2e446..2adbafb 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -43,7 +43,7 @@ static int interface_initialize_g = FALSE; /*initialized?*/
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -74,7 +74,7 @@ H5AC_new (hdf5_file_t *f)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -113,7 +113,7 @@ H5AC_dest (hdf5_file_t *f)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -147,7 +147,7 @@ H5AC_find (hdf5_file_t *f, const H5AC_class_t *type, haddr_t addr,
* Return right away if the item is in the cache.
*/
if (f->cache[idx].type==type && f->cache[idx].addr==addr) {
- return f->cache[idx].thing;
+ HRETURN (f->cache[idx].thing);
}
/*
@@ -209,7 +209,7 @@ H5AC_find (hdf5_file_t *f, const H5AC_class_t *type, haddr_t addr,
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -276,7 +276,7 @@ H5AC_flush (hdf5_file_t *f, const H5AC_class_t *type, haddr_t addr,
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -326,7 +326,7 @@ H5AC_set (hdf5_file_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 9d10f19..d5c8cad 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -6,7 +6,7 @@
*
* Created: H5ACprivate.h
* Jul 9 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Constants and typedefs available to the rest of the
* library.
diff --git a/src/H5ACproto.h b/src/H5ACproto.h
index 25218a9..1423333 100644
--- a/src/H5ACproto.h
+++ b/src/H5ACproto.h
@@ -6,7 +6,7 @@
*
* Created: H5ACproto.h
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Function prototypes for the H5AC package.
*
diff --git a/src/H5B.c b/src/H5B.c
index 89316b2..0ffdc61 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -6,7 +6,7 @@
*
* Created: hdf5btree.c
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Implements balanced, sibling-linked, N-ary trees
* capable of storing any type of data with unique key
@@ -79,7 +79,10 @@
* that type of B-tree.
*
*
- * Modifications:
+ * Modifications:
+ *
+ * Robb Matzke, 4 Aug 1997
+ * Added calls to H5E.
*
*-------------------------------------------------------------------------
*/
@@ -102,11 +105,14 @@
#include "hdf5.h"
/* private headers */
+#include "H5private.h" /*library */
#include "H5ACprivate.h" /*cache */
#include "H5Bprivate.h" /*B-link trees */
#include "H5MFprivate.h" /*File memory management */
#include "H5MMprivate.h" /*Core memory management */
+#define PABLO_MASK H5B_mask
+
#define BOUND(MIN,X,MAX) ((MIN)<(X)?(MIN):((MAX)>(X)?(MAX):(X)))
#define false 0
#define true 1
@@ -130,6 +136,9 @@ static const H5AC_class_t H5AC_BT[1] = {{
(herr_t(*)(hdf5_file_t*,hbool_t,haddr_t,void*))H5B_flush,
}};
+/* Is the H5B interface initialized? */
+static interface_initialize_g = FALSE;
+
/*-------------------------------------------------------------------------
* Function: H5B_new
@@ -138,10 +147,10 @@ static const H5AC_class_t H5AC_BT[1] = {{
*
* Return: Success: address of new node.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -157,11 +166,22 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type, size_t sizeof_rkey)
size_t total_native_keysize;
intn offset, i;
+ FUNC_ENTER (H5B_new, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (type);
+ assert (sizeof_rkey>0);
+
/*
* Allocate file and memory data structures.
*/
size = H5B_nodesize (f, type, &total_native_keysize, sizeof_rkey);
- if ((addr = H5MF_alloc (f, size))<=0) return -1;
+ if ((addr = H5MF_alloc (f, size))<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
bt = H5MM_xmalloc (sizeof(H5B_t));
bt->type = type;
bt->sizeof_rkey = sizeof_rkey;
@@ -201,8 +221,11 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type, size_t sizeof_rkey)
/*
* Cache the new B-tree node.
*/
- H5AC_set (f, H5AC_BT, addr, bt);
- return addr;
+ if (H5AC_set (f, H5AC_BT, addr, bt)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (addr);
}
@@ -216,7 +239,7 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type, size_t sizeof_rkey)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -228,14 +251,19 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
{
const H5B_class_t *type = (const H5B_class_t *)_data;
size_t size, total_nkey_size;
- H5B_t *bt = H5MM_xmalloc (sizeof(H5B_t));
+ H5B_t *bt = NULL;
intn i;
uint8 *p;
+ FUNC_ENTER (H5B_load, NULL, NULL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
assert (type);
assert (type->get_sizeof_rkey);
-
-
+
+ bt = H5MM_xmalloc (sizeof(H5B_t));
bt->sizeof_rkey = (type->get_sizeof_rkey)(f);
size = H5B_nodesize (f, type, &total_nkey_size, bt->sizeof_rkey);
bt->type = type;
@@ -245,7 +273,9 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
bt->native = H5MM_xmalloc (total_nkey_size);
bt->key = H5MM_xmalloc ((2*type->k+1) * sizeof(H5B_key_t));
bt->child = H5MM_xmalloc (2 * type->k * sizeof(haddr_t));
- H5F_block_read (f, addr, size, bt->page);
+ if (H5F_block_read (f, addr, size, bt->page)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_READERROR, NULL);
+ }
p = bt->page;
/* magic number */
@@ -282,7 +312,7 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
bt->key[2*type->k].dirty = 0;
bt->key[2*type->k].rkey = p;
bt->key[2*type->k].nkey = NULL;
- return bt;
+ FUNC_LEAVE (bt);
error:
if (bt) {
@@ -292,7 +322,7 @@ error:
H5MM_xfree (bt->native);
H5MM_xfree (bt);
}
- return NULL;
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, NULL);
}
@@ -301,12 +331,12 @@ error:
*
* Purpose: Flushes a dirty B-tree node to disk.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -317,11 +347,21 @@ static herr_t
H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
{
intn i;
- size_t size = H5B_nodesize (f, bt->type, NULL, bt->sizeof_rkey);
+ size_t size = 0;
uint8 *p = bt->page;
+ FUNC_ENTER (H5B_flush, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (bt);
assert (bt->type);
assert (bt->type->encode);
+
+ size = H5B_nodesize (f, bt->type, NULL, bt->sizeof_rkey);
if (bt->dirty) {
@@ -347,7 +387,9 @@ H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
assert (bt->key[i].rkey == p);
if (bt->key[i].dirty) {
if (bt->key[i].nkey) {
- (bt->type->encode)(f, bt->key[i].rkey, bt->key[i].nkey);
+ if ((bt->type->encode)(f, bt->key[i].rkey, bt->key[i].nkey)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTENCODE, FAIL);
+ }
}
bt->key[i].dirty = 0;
}
@@ -366,7 +408,9 @@ H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
* bother writing data for the child entries that don't exist or
* for the final unchanged children.
*/
- H5F_block_write (f, addr, size, bt->page);
+ if (H5F_block_write (f, addr, size, bt->page)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTFLUSH, FAIL);
+ }
bt->dirty = 0;
bt->ndirty = 0;
}
@@ -378,7 +422,8 @@ H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
H5MM_xfree (bt->native);
H5MM_xfree (bt);
}
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -401,7 +446,7 @@ H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
* Failure: -1 if not found.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -414,32 +459,47 @@ H5B_find (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
H5B_t *bt=NULL;
uint8 lt_key[256], rt_key[256];
intn idx=-1, lt=0, rt, cmp=1;
+ int retval = FAIL;
+ FUNC_ENTER (H5B_find, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
assert (type);
assert (type->sizeof_nkey < sizeof lt_key);
assert (type->decode);
assert (type->cmp);
assert (type->found);
+ assert (addr>=0);
/*
* Perform a binary search to locate the child which contains
* the thing for which we're searching. The comparison function
* may preempt the B-tree node from the cache.
*/
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
- bt = H5AC_find (f, H5AC_BT, addr, type);
- if (!bt) return -1;
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
/* the left key */
- if (!bt->key[idx].nkey) H5B_decode_key (f, bt, idx);
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
HDmemcpy (lt_key, bt->key[idx].nkey, type->sizeof_nkey);
/* the right key */
- if (!bt->key[idx+1].nkey) H5B_decode_key (f, bt, idx+1);
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
HDmemcpy (rt_key, bt->key[idx+1].nkey, type->sizeof_nkey);
/* compare */
@@ -449,18 +509,30 @@ H5B_find (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
lt = idx+1;
}
}
- if (cmp) return -1;
+ if (cmp) {
+ HRETURN_ERROR (H5E_BTREE, H5E_NOTFOUND, FAIL);
+ }
/*
* Follow the link to the subtree or to the data node.
*/
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
assert (idx>=0 && idx<bt->nchildren);
if (bt->level > 0) {
- return H5B_find (f, type, bt->child[idx], udata);
+ retval = H5B_find (f, type, bt->child[idx], udata);
+ if (retval<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_NOTFOUND, FAIL);
+ }
+ } else {
+ retval = (type->found)(f, bt->child[idx], lt_key, udata, rt_key);
+ if (retval<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_NOTFOUND, FAIL);
+ }
}
-
- return (type->found)(f, bt->child[idx], lt_key, udata, rt_key);
+
+ FUNC_LEAVE (retval);
}
@@ -474,10 +546,10 @@ H5B_find (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
*
* Return: Success: Address of the new node.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 3 1997
*
* Modifications:
@@ -487,15 +559,33 @@ H5B_find (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
static haddr_t
H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
{
- H5B_t *old = H5AC_find (f, H5AC_BT, addr, type);
- H5B_t *bt = H5MM_xmalloc (sizeof(H5B_t));
+ H5B_t *old = NULL;
+ H5B_t *bt = NULL;
size_t total_nkey_size, size;
intn i, offset;
intn delta = H5B_ANCHOR_LT==anchor ? type->k : 0;
- size_t recsize = old->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
+ size_t recsize = 0;
haddr_t tmp_addr, new_addr;
H5B_t *tmp=NULL;
+ FUNC_ENTER (H5B_split, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (type);
+ assert (addr>=0);
+
+ /*
+ * Initialize variables
+ */
+ if (NULL==(old=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
+ bt = H5MM_xmalloc (sizeof(H5B_t));
+ recsize = old->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
+
/*
* Create the new B-tree node.
*/
@@ -597,18 +687,24 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
* Add the new node to the cache.
*/
new_addr = H5MF_alloc (f, size);
- H5AC_set (f, H5AC_BT, new_addr, bt);
+ if (H5AC_set (f, H5AC_BT, new_addr, bt)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
+ }
/*
* Update sibling pointers of old nodes.
*/
- old = H5AC_find (f, H5AC_BT, addr, type);
+ if (NULL==(old = H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
if (H5B_ANCHOR_LT==anchor) {
old->dirty += 1;
tmp_addr = old->right;
old->right = new_addr;
if (tmp_addr) {
- tmp = H5AC_find (f, H5AC_BT, tmp_addr, type);
+ if (NULL==(tmp = H5AC_find (f, H5AC_BT, tmp_addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
tmp->dirty += 1;
tmp->left = new_addr;
}
@@ -617,13 +713,15 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
tmp_addr = old->left;
old->left = new_addr;
if (tmp_addr) {
- tmp = H5AC_find (f, H5AC_BT, tmp_addr, type);
+ if (NULL==(tmp = H5AC_find (f, H5AC_BT, tmp_addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
tmp->dirty += 1;
tmp->right = new_addr;
}
}
- return new_addr;
+ FUNC_LEAVE (new_addr);
}
@@ -632,12 +730,12 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
*
* Purpose: Decode the specified key into native format.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 8 1997
*
* Modifications:
@@ -647,9 +745,14 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
static herr_t
H5B_decode_key (hdf5_file_t *f, H5B_t *bt, intn idx)
{
+ FUNC_ENTER (H5B_decode_key, NULL, FAIL);
+
bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey;
- (bt->type->decode)(f, bt->key[idx].rkey, bt->key[idx].nkey);
- return 0;
+ if ((bt->type->decode)(f, bt->key[idx].rkey, bt->key[idx].nkey)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -663,10 +766,10 @@ H5B_decode_key (hdf5_file_t *f, H5B_t *bt, intn idx)
* B-tree root address may change if the old
* root is split.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -682,26 +785,43 @@ H5B_insert (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
intn level;
H5B_t *bt;
+ FUNC_ENTER (H5B_insert, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
assert (type);
assert (type->sizeof_nkey < sizeof lt_key);
child = H5B_insert_helper (f, addr, type, lt_key, &lt_key_changed,
md_key, udata, rt_key, &rt_key_changed);
- if (child<0) return -1;
- if (0==child) return addr;
+ if (child<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
+ }
+ if (0==child) HRETURN (addr);
/* the current root */
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
level = bt->level;
if (!lt_key_changed) {
- if (!bt->key[0].nkey) H5B_decode_key (f, bt, 0);
+ if (!bt->key[0].nkey && H5B_decode_key (f, bt, 0)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (lt_key, bt->key[0].nkey, type->sizeof_nkey);
}
/* the new node */
- bt = H5AC_find (f, H5AC_BT, child, type);
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
if (!rt_key_changed) {
- if (!bt->key[bt->nchildren].nkey) H5B_decode_key (f, bt, bt->nchildren);
+ if (!bt->key[bt->nchildren].nkey &&
+ H5B_decode_key (f, bt, bt->nchildren)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (rt_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey);
}
@@ -716,22 +836,37 @@ H5B_insert (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
uint8 *buf = H5MM_xmalloc (size);
haddr_t tmp_addr = H5MF_alloc (f, size);
- H5AC_flush (f, H5AC_BT, addr, FALSE);
- H5F_block_read (f, addr, size, buf);
- H5F_block_write (f, tmp_addr, size, buf);
- H5AC_rename (f, H5AC_BT, addr, tmp_addr);
+ if (tmp_addr<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
+ if (H5AC_flush (f, H5AC_BT, addr, FALSE)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTFLUSH, FAIL);
+ }
+ if (H5F_block_read (f, addr, size, buf)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_READERROR, FAIL);
+ }
+ if (H5F_block_write (f, tmp_addr, size, buf)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_WRITEERROR, FAIL);
+ }
+ if (H5AC_rename (f, H5AC_BT, addr, tmp_addr)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
+ }
buf = H5MM_xfree (buf);
new_root = addr;
addr = tmp_addr;
/* update the new child's left pointer */
- bt = H5AC_find (f, H5AC_BT, child, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
bt->dirty += 1;
bt->left = addr;
/* clear the old root at the old address */
- bt = H5AC_find (f, H5AC_BT, new_root, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
bt->dirty += 1;
bt->ndirty = 0;
bt->left = 0;
@@ -742,11 +877,15 @@ H5B_insert (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
/*
* The new root is created at a new file location.
*/
- new_root = H5B_new (f, type, bt->sizeof_rkey);
+ if ((new_root = H5B_new (f, type, bt->sizeof_rkey))<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
+ }
#endif
/* the new root */
- bt = H5AC_find (f, H5AC_BT, new_root, type);
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
bt->dirty += 1;
bt->ndirty = 2;
bt->level = level+1;
@@ -766,7 +905,7 @@ H5B_insert (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
bt->key[2].nkey = bt->native + 2 * type->sizeof_nkey;
memcpy (bt->key[2].nkey, rt_key, type->sizeof_nkey);
- return new_root;
+ FUNC_LEAVE (new_root);
}
@@ -776,17 +915,19 @@ H5B_insert (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
* Purpose: Insert a child at the specified address with the
* specified left or right key.
*
- * Return: void
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 8 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-static void
+static herr_t
H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
intn idx, haddr_t child, intn anchor, void *md_key)
{
@@ -794,8 +935,11 @@ H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
size_t recsize;
intn i;
- bt = H5AC_find (f, H5AC_BT, addr, type);
- assert (bt);
+ FUNC_ENTER (H5B_insert_child, NULL, FAIL);
+
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
bt->dirty += 1;
recsize = bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
@@ -848,6 +992,8 @@ H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
bt->child[idx] = child;
bt->nchildren += 1;
bt->ndirty = bt->nchildren;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -873,10 +1019,10 @@ H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
* 0 if the node didn't split. The MD_KEY
* buffer is undefined.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 9 1997
*
* Modifications:
@@ -894,10 +1040,21 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
intn anchor;
haddr_t child, twin=0;
+ FUNC_ENTER (H5B_insert_helper, NULL, FAIL);
+
+ /*
+ * Check arguments
+ */
+ assert (f);
+ assert (addr>=0);
assert (type);
assert (type->decode);
assert (type->cmp);
assert (type->new);
+ assert (lt_key);
+ assert (lt_key_changed);
+ assert (rt_key);
+ assert (rt_key_changed);
/*
* Use a binary search to find the child that will receive the new
@@ -905,21 +1062,27 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* the cache each time through the loop. When the search completes
* IDX points to the child that should get the new data.
*/
- bt = H5AC_find (f, H5AC_BT, addr, type);
- if (!bt) goto error;
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
- bt = H5AC_find (f, H5AC_BT, addr, type);
- if (!bt) goto error;
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
/* left key */
- if (!bt->key[idx].nkey) H5B_decode_key (f, bt, idx);
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (lt_key, bt->key[idx].nkey, type->sizeof_nkey);
/* right key */
- if (!bt->key[idx+1].nkey) H5B_decode_key (f, bt, idx+1);
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (rt_key, bt->key[idx+1].nkey, type->sizeof_nkey);
/* compare */
@@ -936,23 +1099,33 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* function needs them as input. Don't worry about it at higher node
* levels because this function uses them for output only.
*/
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
if (cmp<0 && idx<=0) {
idx = 0;
cmp = 0;
if (0==bt->level && bt->nchildren) {
- if (!bt->key[idx].nkey) H5B_decode_key (f, bt, idx);
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (lt_key, bt->key[idx].nkey, type->sizeof_nkey);
- if (!bt->key[idx+1].nkey) H5B_decode_key (f, bt, idx+1);
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (rt_key, bt->key[idx+1].nkey, type->sizeof_nkey);
}
} else if (cmp>0 && idx+1>=bt->nchildren) {
idx = bt->nchildren-1;
cmp = 0;
if (0==bt->level && bt->nchildren) {
- if (!bt->key[idx].nkey) H5B_decode_key (f, bt, idx);
+ if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (lt_key, bt->key[idx].nkey, type->sizeof_nkey);
- if (!bt->key[idx+1].nkey) H5B_decode_key (f, bt, idx+1);
+ if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
+ }
memcpy (rt_key, bt->key[idx+1].nkey, type->sizeof_nkey);
}
}
@@ -965,9 +1138,12 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* buffers are output values.
*/
if (0==bt->nchildren) {
- child = (type->new)(f, lt_key, udata, rt_key);
- if (child<=0) goto error;
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if ((child = (type->new)(f, lt_key, udata, rt_key))<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
+ }
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
bt->nchildren = 1;
bt->dirty += 1;
bt->ndirty = 1;
@@ -998,8 +1174,10 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
md_key, udata,
rt_key, rt_key_changed);
}
- if (child<0) goto error;
- bt = H5AC_find (f, H5AC_BT, addr, type);
+ if (child<0) HRETURN_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
/*
* Update the left and right keys.
@@ -1032,7 +1210,9 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* and that `idx' is adjusted appropriately.
*/
if (child && bt->nchildren==2*type->k) {
- twin = H5B_split (f, type, addr, anchor);
+ if ((twin = H5B_split (f, type, addr, anchor))<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
+ }
if (idx<=type->k) {
addr = H5B_ANCHOR_LT==anchor ? addr : twin;
} else {
@@ -1045,7 +1225,9 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* If the child split, then insert the new child.
*/
if (child) {
- H5B_insert_child (f, type, addr, idx, child, anchor, md_key);
+ if (H5B_insert_child (f, type, addr, idx, child, anchor, md_key)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
+ }
}
/*
@@ -1053,24 +1235,24 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* by the left and right node).
*/
if (twin) {
- bt = H5AC_find (f, H5AC_BT, twin, type);
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, twin, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
if (H5B_ANCHOR_LT==anchor) {
- if (!bt->key[0].nkey) {
- H5B_decode_key (f, bt, 0);
+ if (!bt->key[0].nkey && H5B_decode_key (f, bt, 0)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
memcpy (md_key, bt->key[0].nkey, type->sizeof_nkey);
} else {
- if (!bt->key[bt->nchildren].nkey) {
- H5B_decode_key (f, bt, bt->nchildren);
+ if (!bt->key[bt->nchildren].nkey &&
+ H5B_decode_key (f, bt, bt->nchildren)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
memcpy (md_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey);
}
}
- return twin;
-
-error:
- return -1;
+ FUNC_LEAVE (twin);
}
@@ -1080,12 +1262,12 @@ error:
* Purpose: Calls the list callback for each leaf node of the
* B-tree, passing it the UDATA structure.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -1098,27 +1280,39 @@ H5B_list (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
H5B_t *bt;
haddr_t *child=NULL;
haddr_t twin;
- intn i, nchildren, status;
- herr_t (*list)(hdf5_file_t*,haddr_t,void*);
+ intn i, nchildren;
+ herr_t (*list)(hdf5_file_t*,haddr_t,void*) = NULL;
+ FUNC_ENTER (H5B_list, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
assert (type);
assert (type->list);
+ assert (addr>=0);
+ assert (udata);
- bt = H5AC_find (f, H5AC_BT, addr, type);
- if (!bt) return -1;
+ if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
if (bt->level>0) {
- return H5B_list (f, type, bt->child[0], udata);
+ if (H5B_list (f, type, bt->child[0], udata)<0) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLIST, FAIL);
+ } else {
+ HRETURN (SUCCEED);
+ }
} else {
child = H5MM_xmalloc (2 * type->k * sizeof(haddr_t));
list = type->list;
twin = addr;
while (twin) { /*for each leaf node*/
- bt = H5AC_find (f, H5AC_BT, twin, type);
- if (!bt) {
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, twin, type))) {
H5MM_xfree (child);
- return -1;
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
nchildren = bt->nchildren;
twin = bt->right;
@@ -1126,16 +1320,16 @@ H5B_list (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
bt = NULL; /*list callback may invalidate the cache*/
for (i=0; i<nchildren; i++) {
- status = (list)(f, child[i], udata);
- if (status<0) {
+ if ((list)(f, child[i], udata)<0) {
H5MM_xfree (child);
- return -1;
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
}
}
H5MM_xfree (child);
}
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -1152,10 +1346,10 @@ H5B_list (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
*
* Return: Success: Size of node in file.
*
- * Failure: never fails.
+ * Failure: 0
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 3 1997
*
* Modifications:
@@ -1166,13 +1360,32 @@ static size_t
H5B_nodesize (hdf5_file_t *f, const H5B_class_t *type,
size_t *total_nkey_size, size_t sizeof_rkey)
{
+ size_t size;
+
+ FUNC_ENTER (H5B_nodesize, NULL, (size_t)0);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (type);
+ assert (sizeof_rkey>0);
+
+ /*
+ * Total native key size.
+ */
if (total_nkey_size) {
*total_nkey_size = (2 * type->k + 1) * type->sizeof_nkey;
}
- return (H5B_SIZEOF_HDR(f) + /*node header */
+ /*
+ * Total node size.
+ */
+ size = (H5B_SIZEOF_HDR(f) + /*node header */
2 * type->k * H5F_SIZEOF_OFFSET(f) + /*child pointers*/
(2*type->k+1) * sizeof_rkey); /*keys */
+
+ FUNC_LEAVE (size);
}
@@ -1181,12 +1394,12 @@ H5B_nodesize (hdf5_file_t *f, const H5B_class_t *type,
*
* Purpose: Prints debugging info about a B-tree.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 4 1997
*
* Modifications:
@@ -1197,10 +1410,30 @@ herr_t
H5B_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth, const H5B_class_t *type)
{
- H5B_t *bt = H5AC_find (f, H5AC_BT, addr, type);
+ H5B_t *bt = NULL;
+
+ FUNC_ENTER (H5B_debug, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+ assert (type);
- if (!bt) return -1;
+ /*
+ * Load the tree node.
+ */
+ if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
+ HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
+ }
+ /*
+ * Print the values.
+ */
fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
"Tree type ID:",
(int)(bt->type->id));
@@ -1225,5 +1458,6 @@ H5B_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
"Number of children:",
(int)(bt->nchildren));
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index bb9d95c..4364203 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -52,8 +52,8 @@ typedef struct H5B_class_t {
haddr_t (*insert)(hdf5_file_t*,haddr_t,int*,void*,int*,void*,void*,
void*,int*);
herr_t (*list)(hdf5_file_t*,haddr_t,void*);
- void (*decode)(hdf5_file_t*,uint8*,void*);
- void (*encode)(hdf5_file_t*,uint8*,void*);
+ herr_t (*decode)(hdf5_file_t*,uint8*,void*);
+ herr_t (*encode)(hdf5_file_t*,uint8*,void*);
} H5B_class_t;
/*
diff --git a/src/H5Bproto.h b/src/H5Bproto.h
index 3869db4..b1eb82c 100644
--- a/src/H5Bproto.h
+++ b/src/H5Bproto.h
@@ -6,7 +6,7 @@
*
* Created: H5Bproto.h
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Non-API function prototypes for B-link trees.
*
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index d21adde..d36b2a2 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -58,6 +58,10 @@ static const hdf_maj_error_messages_t hdf_maj_error_messages[] =
{H5E_FUNC, "Function Entry/Exit"},
{H5E_ATOM, "Object Atom"},
{H5E_CACHE, "Object Cache"},
+ {H5E_BTREE, "B-Tree Node"},
+ {H5E_SYM, "Symbol Table"},
+ {H5E_HEAP, "Heap"},
+ {H5E_OHDR, "Object Header"},
};
typedef struct
@@ -90,6 +94,16 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_CANTREGISTER, "Can't register new atom"},
{H5E_CANTFLUSH, "Can't flush object from cache"},
{H5E_CANTLOAD, "Can't load object into cache"},
+ {H5E_NOTFOUND, "Object not found"},
+ {H5E_CANTENCODE, "Can't encode value"},
+ {H5E_CANTDECODE, "Can't decode value"},
+ {H5E_CANTSPLIT, "Can't split node"},
+ {H5E_CANTINSERT, "Can't insert object"},
+ {H5E_CANTLIST, "Can't list node"},
+ {H5E_LINKCOUNT, "Bad object header link count"},
+ {H5E_VERSION, "Wrong version number"},
+ {H5E_ALIGNMENT, "Alignment error"},
+ {H5E_BADMESG, "Unrecognized message"},
};
/* We use a stack to hold the errors plus we keep track of the function,
diff --git a/src/H5Eproto.h b/src/H5Eproto.h
index c51ceac..95c198c 100644
--- a/src/H5Eproto.h
+++ b/src/H5Eproto.h
@@ -77,7 +77,11 @@ typedef enum
H5E_IO, /* Low-level I/O */
H5E_FUNC, /* Function Entry/Exit */
H5E_ATOM, /* Object Atom */
- H5E_CACHE /* Object Cache */
+ H5E_CACHE, /* Object Cache */
+ H5E_BTREE, /* B-Tree Node */
+ H5E_SYM, /* Symbol Table */
+ H5E_HEAP, /* Heap */
+ H5E_OHDR /* Object Header */
}
hdf_maj_err_code_t;
@@ -118,7 +122,21 @@ typedef enum
/* Cache related errors */
H5E_CANTFLUSH, /* Can't flush object from cache */
- H5E_CANTLOAD /* Can't load object into cache */
+ H5E_CANTLOAD, /* Can't load object into cache */
+
+ /* B-tree related errors */
+ H5E_NOTFOUND, /* Object not found */
+ H5E_CANTENCODE, /* Can't encode value */
+ H5E_CANTDECODE, /* Can't decode value */
+ H5E_CANTSPLIT, /* Can't split node */
+ H5E_CANTINSERT, /* Can't insert object */
+ H5E_CANTLIST, /* Can't list node */
+
+ /* Object header related errors */
+ H5E_LINKCOUNT, /* Bad object header link count */
+ H5E_VERSION, /* Wrong version number */
+ H5E_ALIGNMENT, /* Alignment error */
+ H5E_BADMESG /* Unrecognized message */
}
hdf_min_err_code_t;
diff --git a/src/H5F.c b/src/H5F.c
index 3c756c4..145e4a7 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -32,6 +32,8 @@ static char RcsId[] = "@(#)$Revision$";
H5F_init_interface -- initialize the H5F interface
*/
+#include <assert.h>
+
#define HDF5_FILE_MASTER
#include "hdf5.h"
#undef HDF5_FILE_MASTER
@@ -318,7 +320,7 @@ done:
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -353,7 +355,7 @@ H5F_new (void)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -495,7 +497,9 @@ hatom_t H5Fcreate(const char *filename, uintn flags, hatom_t create_temp, hatom_
H5F_encode_offset(new_file,p,new_file->smallobj_off); /* Encode offset of global small-object heap */
H5F_encode_offset(new_file,p,new_file->freespace_off); /* Encode offset of global free-space heap */
/* Predict the header length and encode it: */
- H5F_encode_length(new_file,p,(p-temp_buf)+f_create_parms->length_size+H5F_symbol_table_size(new_file)); /* Encode length of boot-block */
+ H5F_encode_length(new_file,p,((p-temp_buf) +
+ H5F_SIZEOF_SIZE(new_file) +
+ H5G_SIZEOF_ENTRY(new_file)));
/* Encode the (bogus) symbol-table entry */
if (H5G_encode (new_file, &p, new_file->root_sym)<0) {
@@ -779,7 +783,7 @@ done:
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -789,7 +793,7 @@ done:
herr_t
H5F_block_read (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
{
- FUNC_ENTER (H5F_block_read, NULL, FAIL);
+ FUNC_ENTER (H5F_block_read, H5F_init_interface, FAIL);
if (0==size) return 0;
addr += f->file_create_parms.userblock_size;
@@ -816,7 +820,7 @@ H5F_block_read (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -826,7 +830,7 @@ H5F_block_read (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
herr_t
H5F_block_write (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
{
- FUNC_ENTER (H5F_block_write, NULL, FAIL);
+ FUNC_ENTER (H5F_block_write, H5F_init_interface, FAIL);
if (0==size) return 0;
addr += f->file_create_parms.userblock_size;
@@ -849,12 +853,12 @@ H5F_block_write (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
* is indented and the field name occupies the specified width
* number of characters.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -865,6 +869,16 @@ herr_t
H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth)
{
+ FUNC_ENTER (H5F_debug, H5F_init_interface, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ /* debug */
fprintf (stream, "%*sFile Boot Block...\n", indent, "");
fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
@@ -919,6 +933,5 @@ H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
"Shared header version number:",
(unsigned)(f->file_create_parms.sharedheader_ver));
-
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index fde8fb3..687072b 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -51,12 +51,6 @@ typedef struct {
struct H5G_entry_t *root_sym; /* Extra for the root symbol in the file */
} hdf5_file_t;
-/* Define a macro to ease calculation of the symbol-table entry size */
-#define H5F_symbol_table_size(f) (4+ /* "Symbol-type" bytes */ \
- H5F_SIZEOF_OFFSET(f)+ /* Offset bytes */ \
- H5F_SIZEOF_SIZE(f)+ /* Length bytes */ \
- 4+ /* Name offset in local heap */ \
- 24) /* "Scratch" space */
#ifdef NOT_YET
#define H5F_encode_offset(f,p,o) (H5F_SIZEOF_OFFSET(f)==4 ? UINT32ENCODE(p,o) \
@@ -68,9 +62,19 @@ typedef struct {
case 8: UINT64ENCODE(p,o); break;\
case 2: UINT16ENCODE(p,o); break;}
#endif /* NOT_YET */
-#define H5F_decode_offset(f,p,o) switch(H5F_SIZEOF_OFFSET(f)) { case 4: UINT32DECODE(p,o); break;\
- case 8: UINT64DECODE(p,o); break;\
- case 2: UINT16DECODE(p,o); break;}
+
+#define H5F_decode_offset(f,p,o) \
+ switch (H5F_SIZEOF_OFFSET (f)) { \
+ case 4: \
+ UINT32DECODE (p, o); \
+ break; \
+ case 8: \
+ UINT64DECODE (p, o); \
+ break; \
+ case 2: \
+ UINT16DECODE (p, o); \
+ break; \
+ }
#ifdef NOT_YET
#define H5F_encode_length(f,p,l) (H5F_SIZEOF_SIZE(f)==4 ? UINT32ENCODE(p,l) \
diff --git a/src/H5G.c b/src/H5G.c
index fa7da12..19ba355 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -6,11 +6,14 @@
*
* Created: H5G.c
* Jul 18 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose:
*
- * Modifications:
+ * Modifications:
+ *
+ * Robb Matzke, 5 Aug 1997
+ * Added calls to H5E.
*
*-------------------------------------------------------------------------
*/
@@ -21,12 +24,19 @@
#define H5G_INIT_HEAP 8192
/* Packages needed by this file... */
+#include "H5private.h"
#include "H5Bprivate.h"
#include "H5Gprivate.h"
#include "H5Hprivate.h"
#include "H5MMprivate.h"
+#include "H5Oprivate.h"
+
+#define PABLO_MASK H5G_mask
+
+
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
-/* PRIVATE PROTOTYPES */
/*-------------------------------------------------------------------------
@@ -46,10 +56,10 @@
*
* Return: Success: Address of new symbol table.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -59,27 +69,48 @@
haddr_t
H5G_new (hdf5_file_t *f, size_t init)
{
- haddr_t addr; /*symtab object header */
- haddr_t heap; /*private heap */
off_t name; /*offset of "" name */
+ haddr_t addr; /*object header address */
+ H5O_stab_t stab; /*symbol table message */
+
+ FUNC_ENTER (H5G_new, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
/* Create symbol table private heap */
if (init>0) {
- if ((heap = H5H_new (f, init))<0) return -1;
- if ((name = H5H_insert (f, heap, 1, "")<0)) return -1;
- assert (0==name); /*or B-tree's won't work*/
+ if ((stab.heap = H5H_new (f, H5H_LOCAL, init))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if ((name = H5H_insert (f, stab.heap, 1, "")<0)) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ 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);
+ }
} else {
- heap = 0; /*we'll create it later*/
+ stab.heap = 0; /*we'll create it later*/
}
- /* Create symbol table object header */
- addr = not_implemented_yet__create_object_header();
- if (addr<0) return -1;
+ /* The B-tree is created on demand later */
+ stab.btree = 0;
- /* Insert the heap and B-tree addresses */
- not_implemented_yet__insert_symtab_message (f, addr, heap, 0);
+ /* Create symbol table object header */
+ if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if (H5O_modify(f, addr, NULL, NULL, H5O_STAB, H5O_NEW_MESG, &stab)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
- return addr;
+ FUNC_LEAVE (addr);
}
@@ -92,10 +123,10 @@ H5G_new (hdf5_file_t *f, size_t init)
*
* Return: Success: Address corresponding to the name.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -106,20 +137,35 @@ haddr_t
H5G_find (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
{
H5G_node_ud1_t udata; /*data to pass through B-tree */
- haddr_t btree; /*address of B-tree */
+ H5O_stab_t stab; /*symbol table message */
+
+ FUNC_ENTER (H5G_find, NULL, FAIL);
+
+ /* Check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (name && *name);
+ assert (entry);
/* set up the udata */
- not_implemented_yet__get_symtab_message (f, addr, &(udata.heap), &btree);
- if (btree<=0 || udata.heap<=0) return -1; /*empty symbol table*/
+ if (NULL==H5O_read (f, addr, NULL, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
+ }
+ if (stab.btree<=0 || stab.heap<=0) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*empty symbol table*/
+ }
udata.operation = H5G_OPER_FIND;
udata.name = name;
+ udata.heap = stab.heap;
/* search the B-tree */
- if (H5B_find (f, H5B_SNODE, btree, &udata)<0) return -1;
+ if (H5B_find (f, H5B_SNODE, stab.btree, &udata)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
/* return the result */
if (entry) *entry = udata.entry;
- return udata.entry.header;
+ FUNC_LEAVE (udata.entry.header);
}
@@ -131,12 +177,12 @@ H5G_find (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
* file F. ENTRY is the new symbol table entry to use for the
* symbol.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -147,18 +193,34 @@ herr_t
H5G_modify (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
{
H5G_node_ud1_t udata; /*data to pass through B-tree */
- haddr_t btree; /*address of B-tree */
+ H5O_stab_t stab; /*symbol table message */
+
+ FUNC_ENTER (H5G_modify, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (name && *name);
+ assert (entry);
/* set up the udata */
- not_implemented_yet__get_symtab_message (f, addr, &(udata.heap), &btree);
- if (btree<=0 || udata.heap<=0) return -1; /*empty symbol table*/
+ if (NULL==H5O_read (f, addr, NULL, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
+ }
+ if (stab.btree<=0 || stab.heap<=0) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL); /*empty symbol table*/
+ }
udata.operation = H5G_OPER_MODIFY;
udata.name = name;
+ udata.heap = stab.heap;
udata.entry = *entry;
/* search and modify the B-tree */
- if (H5B_find (f, H5B_SNODE, btree, &udata)<0) return -1;
- return 0;
+ if (H5B_find (f, H5B_SNODE, stab.btree, &udata)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -169,12 +231,12 @@ H5G_modify (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
* file F. The name of the new symbol is NAME and its symbol
* table entry is ENTRY.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -184,31 +246,51 @@ H5G_modify (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
herr_t
H5G_insert (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
{
- haddr_t btree; /*file address of B-tree */
+ H5O_stab_t stab; /*symbol table message */
H5G_node_ud1_t udata; /*data to pass through B-tree */
off_t offset; /*offset of name within heap */
+ FUNC_ENTER (H5G_insert, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (addr>=0);
+ assert (name && *name);
+ assert (entry);
+
/* make sure we have a B-tree and a heap */
- not_implemented_yet__get_symtab_message (f, addr, &btree, &(udata.heap));
- if (btree<=0 || udata.heap<=0) {
- if (btree<=0 &&
- (btree = H5B_new (f, H5B_SNODE, sizeof(H5G_node_key_t)))<0) {
- return -1;
+ if (NULL==H5O_read (f, addr, NULL, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
+ }
+ if (stab.btree<=0 || stab.heap<=0) {
+ if (stab.btree<=0 &&
+ (stab.btree = H5B_new (f, H5B_SNODE, sizeof(H5G_node_key_t)))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if (stab.heap<=0) {
+ stab.heap = H5H_new (f, H5H_LOCAL,
+ MAX(strlen(name)+1, H5G_INIT_HEAP));
+ if (stab.heap<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if (0!=(offset = H5H_insert (f, stab.heap, 1, ""))) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL);
+ }
}
- if (udata.heap<=0) {
- udata.heap = H5H_new (f, MAX(strlen(name)+1, H5G_INIT_HEAP));
- if (udata.heap<0) return -1;
- if (0!=(offset = H5H_insert (f, udata.heap, 1, ""))) return -1;
+ if (H5O_modify (f, addr, NULL, NULL, H5O_STAB, 0, &stab)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
- not_implemented_yet__update_symtab_message (f, addr, udata.heap, btree);
}
/* initialize data to pass through B-tree */
udata.name = name;
+ udata.heap = stab.heap;
udata.entry = *entry;
- if (H5B_insert (f, H5B_SNODE, btree, &udata)<0) return -1;
+ if (H5B_insert (f, H5B_SNODE, stab.btree, &udata)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
+ }
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -227,12 +309,12 @@ H5G_insert (hdf5_file_t *f, haddr_t addr, const char *name, H5G_entry_t *entry)
* but at most MAXENTRIES values are copied
* into the NAMES and ENTRIES arrays.
*
- * Failure: -1, the pointers in NAMES are undefined but
+ * Failure: FAIL, the pointers in NAMES are undefined but
* no memory is allocated. The values in
* ENTRIES are undefined.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -244,26 +326,31 @@ H5G_list (hdf5_file_t *f, haddr_t addr, int maxentries,
char *names[], H5G_entry_t entries[])
{
H5G_node_list_t udata;
- haddr_t btree;
+ H5O_stab_t stab;
intn i;
-
- not_implemented_yet__get_symtab_message (f, addr, &btree, &(udata.heap));
- if (btree<=0 || udata.heap<=0) return 0; /*empty directory*/
+
+ FUNC_ENTER (H5G_list, NULL, FAIL);
+
+ if (NULL==H5O_read (f, addr, NULL, H5O_STAB, 0, &stab)) {
+ HRETURN_ERROR (H5E_SYM, H5E_BADMESG, FAIL);
+ }
+ if (stab.btree<=0 || stab.heap<=0) HRETURN (0); /*empty directory*/
udata.entry = entries;
udata.name = names;
+ udata.heap = stab.heap;
udata.maxentries = maxentries;
udata.nsyms = 0;
if (names) HDmemset (names, 0, maxentries);
- if (H5B_list (f, H5B_SNODE, btree, &udata)<0) {
+ if (H5B_list (f, H5B_SNODE, stab.btree, &udata)<0) {
if (names) {
for (i=0; i<maxentries; i++) H5MM_xfree (names[i]);
}
- return -1;
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLIST, FAIL);
}
- return udata.nsyms;
+ FUNC_LEAVE (udata.nsyms);
}
@@ -273,13 +360,13 @@ H5G_list (hdf5_file_t *f, haddr_t addr, int maxentries,
* Purpose: Same as H5G_decode() except it does it for an array of
* symbol table entries.
*
- * Return: Success: 0, with *pp pointing to the first byte
+ * Return: Success: SUCCEED, with *pp pointing to the first byte
* after the last symbol.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -291,10 +378,22 @@ H5G_decode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
{
intn i;
+ FUNC_ENTER (H5G_decode_vec, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (pp);
+ assert (ent);
+ assert (n>=0);
+
+ /* decode entries */
for (i=0; i<n; i++) {
- if (H5G_decode (f, pp, ent+i)<0) return -1;
+ if (H5G_decode (f, pp, ent+i)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTDECODE, FAIL);
+ }
}
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -303,13 +402,13 @@ H5G_decode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
*
* Purpose: Decodes a symbol table entry pointed to by `*pp'.
*
- * Return: Success: 0 with *pp pointing to the first byte
+ * Return: Success: SUCCEED with *pp pointing to the first byte
* following the symbol table entry.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -320,11 +419,20 @@ herr_t
H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
{
uint8 *p_ret = *pp;
-
+
+ FUNC_ENTER (H5G_decode, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (pp);
+ assert (ent);
+
+ /* decode header */
H5F_decode_offset (f, *pp, ent->name_off);
H5F_decode_offset (f, *pp, ent->header);
UINT32DECODE (*pp, ent->type);
+ /* decode scratch-pad */
switch (ent->type) {
case H5G_NOTHING_CACHED:
break;
@@ -338,9 +446,9 @@ H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
UINT32DECODE (*pp, ent->cache.sdata.dim[3]);
break;
- case H5G_CACHED_SYMTAB:
- UINT32DECODE (*pp, ent->cache.symtab.btree);
- UINT32DECODE (*pp, ent->cache.symtab.heap);
+ case H5G_CACHED_STAB:
+ UINT32DECODE (*pp, ent->cache.stab.btree);
+ UINT32DECODE (*pp, ent->cache.stab.heap);
break;
default:
@@ -348,7 +456,7 @@ H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
}
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -358,13 +466,13 @@ H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
* Purpose: Same as H5G_encode() except it does it for an array of
* symbol table entries.
*
- * Return: Success: 0, with *pp pointing to the first byte
+ * Return: Success: SUCCEED, with *pp pointing to the first byte
* after the last symbol.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -376,10 +484,22 @@ H5G_encode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
{
intn i;
+ FUNC_ENTER (H5G_encode_vec, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (pp);
+ assert (ent);
+ assert (n>=0);
+
+ /* encode entries */
for (i=0; i<n; i++) {
- if (H5G_encode (f, pp, ent+i)<0) return -1;
+ if (H5G_encode (f, pp, ent+i)<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTENCODE, FAIL);
+ }
}
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -389,13 +509,13 @@ H5G_encode_vec (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
* Purpose: Encodes the specified symbol table entry into the buffer
* pointed to by *pp.
*
- * Return: Success: 0, with *pp pointing to the first byte
+ * Return: Success: SUCCEED, with *pp pointing to the first byte
* after the symbol table entry.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -407,10 +527,19 @@ H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
{
uint8 *p_ret = *pp;
+ FUNC_ENTER (H5G_encode, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (pp);
+ assert (ent);
+
+ /* encode header */
H5F_encode_offset (f, *pp, ent->name_off);
H5F_encode_offset (f, *pp, ent->header);
UINT32ENCODE (*pp, ent->type);
+ /* encode scratch-pad */
switch (ent->type) {
case H5G_NOTHING_CACHED:
break;
@@ -424,9 +553,9 @@ H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
UINT32ENCODE (*pp, ent->cache.sdata.dim[3]);
break;
- case H5G_CACHED_SYMTAB:
- UINT32ENCODE (*pp, ent->cache.symtab.btree);
- UINT32ENCODE (*pp, ent->cache.symtab.heap);
+ case H5G_CACHED_STAB:
+ UINT32ENCODE (*pp, ent->cache.stab.btree);
+ UINT32ENCODE (*pp, ent->cache.stab.heap);
break;
default:
@@ -434,11 +563,7 @@ H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
}
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
-herr_t not_implemented_yet__create_object_header (void) {return FAIL;}
-herr_t not_implemented_yet__insert_symtab_message (hdf5_file_t* f, haddr_t addr, haddr_t heap, haddr_t btree) {return FAIL;}
-herr_t not_implemented_yet__get_symtab_message (hdf5_file_t *f, haddr_t addr, haddr_t *heap, haddr_t *btree) {return FAIL;}
-herr_t not_implemented_yet__update_symtab_message (hdf5_file_t *f, haddr_t addr, haddr_t heap, haddr_t btree) {return FAIL;}
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 3ce046e..9e66188 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -13,7 +13,10 @@
* table entries. A B-tree usually points to the
* symbol table nodes for any given symbol table.
*
- * Modifications:
+ * Modifications:
+ *
+ * Robb Matzke, 5 Aug 1997
+ * Added calls to H5E.
*
*-------------------------------------------------------------------------
*/
@@ -24,6 +27,7 @@
#include "hdf5.h"
/* Packages needed by this file... */
+#include "H5private.h" /*library */
#include "H5ACprivate.h" /*cache */
#include "H5Bprivate.h" /*B-link trees */
#include "H5Gprivate.h" /*me */
@@ -31,9 +35,12 @@
#include "H5MFprivate.h" /*file memory management */
#include "H5MMprivate.h" /*core memory management */
+#define PABLO_MASK H5G_node_mask
+
+
/* PRIVATE PROTOTYPES */
-static void H5G_node_decode_key (hdf5_file_t *f, uint8 *raw, void *_key);
-static void H5G_node_encode_key (hdf5_file_t *f, uint8 *raw, void *_key);
+static herr_t H5G_node_decode_key (hdf5_file_t *f, uint8 *raw, void *_key);
+static herr_t H5G_node_encode_key (hdf5_file_t *f, uint8 *raw, void *_key);
static size_t H5G_node_size (hdf5_file_t *f);
static haddr_t H5G_node_new (hdf5_file_t *f, void *_lt_key, void *_udata,
void *_rt_key);
@@ -73,6 +80,9 @@ const H5B_class_t H5B_SNODE[1] = {{
H5G_node_encode_key, /*encode */
}};
+/* Has the interface been initialized? */
+static intn interface_initialize_g = FALSE;
+
/*-------------------------------------------------------------------------
* Function: H5G_node_sizeof_rkey
@@ -85,7 +95,7 @@ const H5B_class_t H5B_SNODE[1] = {{
* Failure: never fails
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 14 1997
*
* Modifications:
@@ -104,22 +114,32 @@ H5G_node_sizeof_rkey (hdf5_file_t *f)
*
* Purpose: Decodes a raw key into a native key.
*
- * Return: void
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 8 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-static void
+static herr_t
H5G_node_decode_key (hdf5_file_t *f, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
+ FUNC_ENTER (H5G_node_decode_key, NULL, FAIL);
+
+ assert (f);
+ assert (raw);
+ assert (key);
+
H5F_decode_offset (f, raw, key->offset);
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -128,22 +148,32 @@ H5G_node_decode_key (hdf5_file_t *f, uint8 *raw, void *_key)
*
* Purpose: Encodes a native key into a raw key.
*
- * Return: void
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 8 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-static void
+static herr_t
H5G_node_encode_key (hdf5_file_t *f, uint8 *raw, void *_key)
{
H5G_node_key_t *key = (H5G_node_key_t *)_key;
+ FUNC_ENTER (H5G_node_encode_key, NULL, FAIL);
+
+ assert (f);
+ assert (raw);
+ assert (key);
+
H5F_encode_offset (f, raw, key->offset);
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -157,7 +187,7 @@ H5G_node_encode_key (hdf5_file_t *f, uint8 *raw, void *_key)
* Failure: Never fails.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -182,10 +212,10 @@ H5G_node_size (hdf5_file_t *f)
*
* Return: Success: Address of symbol table node.
*
- * Failure: 0
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -197,23 +227,44 @@ H5G_node_new (hdf5_file_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
H5G_node_key_t *lt_key = (H5G_node_key_t*)_lt_key;
H5G_node_key_t *rt_key = (H5G_node_key_t*)_rt_key;
- H5G_node_t *sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
- size_t size = H5G_node_size (f);
- haddr_t addr = H5MF_alloc (f, size);
+ H5G_node_t *sym = NULL;
+ size_t size = 0;
+ haddr_t addr;
+
+ FUNC_ENTER (H5G_node_new, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (lt_key);
+ assert (rt_key);
+
+ sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
+ size = H5G_node_size (f);
+ if ((addr = H5MF_alloc (f, size))<0) {
+ H5MM_xfree (sym);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
sym->dirty = 1;
sym->entry = H5MM_xcalloc (2 * H5G_NODE_K, sizeof(H5G_entry_t));
- H5AC_set (f, H5AC_SNODE, addr, sym);
+ if (H5AC_set (f, H5AC_SNODE, addr, sym)<0) {
+ H5MM_xfree (sym->entry);
+ H5MM_xfree (sym);
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
/*
* The left and right symbols in an empty tree are both the
- * empty string stored at offset zero by the symtab.c functions. This
+ * empty string stored at offset zero by the H5G functions. This
* allows the comparison functions to work correctly without knowing
* that there are no symbols.
*/
if (lt_key) lt_key->offset = 0;
if (rt_key) rt_key->offset = 0;
- return addr;
+
+ FUNC_LEAVE (addr);
}
@@ -222,12 +273,12 @@ H5G_node_new (hdf5_file_t *f, void *_lt_key, void *_udata, void *_rt_key)
*
* Purpose: Flush a symbol table node to disk.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -239,6 +290,16 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
{
uint8 *buf=NULL, *p=NULL;
size_t size;
+ herr_t status;
+
+ FUNC_ENTER (H5G_node_flush, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (sym);
if (sym->dirty) {
size = H5G_node_size (f);
@@ -261,8 +322,9 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
H5G_encode_vec (f, &p, sym->entry, sym->nsyms);
- H5F_block_write (f, addr, p-buf, buf);
+ status = H5F_block_write (f, addr, p-buf, buf);
buf = H5MM_xfree (buf);
+ if (status<0) HRETURN_ERROR (H5E_SYM, H5E_WRITEERROR, FAIL);
}
if (destroy) {
@@ -270,7 +332,7 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
H5MM_xfree (sym);
}
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -284,7 +346,7 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -294,14 +356,32 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
static H5G_node_t *
H5G_node_load (hdf5_file_t *f, haddr_t addr, const void *_udata)
{
- H5G_node_t *sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
- size_t size = H5G_node_size (f);
- uint8 *buf = H5MM_xmalloc (size);
- uint8 *p = buf;
-
+ H5G_node_t *sym = NULL;
+ size_t size = 0;
+ uint8 *buf = NULL, *p = NULL;
+ FUNC_ENTER (H5G_node_load, NULL, NULL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (NULL==_udata);
+
+ /*
+ * Initialize variables.
+ */
+ size = H5G_node_size (f);
+ buf = p = H5MM_xmalloc (size);
+ sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
sym->entry = H5MM_xcalloc (2*H5G_NODE_K, sizeof(H5G_entry_t));
- H5F_block_read (f, addr, size, buf);
+
+ if (H5F_block_read (f, addr, size, buf)<0) {
+ H5MM_xfree (sym->entry);
+ H5MM_xfree (sym);
+ HRETURN_ERROR (H5E_SYM, H5E_READERROR, NULL);
+ }
/* magic */
if (HDmemcmp (p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC)) goto error;
@@ -317,15 +397,15 @@ H5G_node_load (hdf5_file_t *f, haddr_t addr, const void *_udata)
UINT16DECODE (p, sym->nsyms);
/* entries */
- H5G_decode_vec (f, &p, sym->entry, sym->nsyms);
+ if (H5G_decode_vec (f, &p, sym->entry, sym->nsyms)<0) goto error;
H5MM_xfree (buf);
- return sym;
+ FUNC_LEAVE (sym);
error:
H5MM_xfree (buf);
H5MM_xfree (sym);
- return NULL;
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, NULL);
}
@@ -346,10 +426,10 @@ error:
* the LEFT key (exclusive) and the
* RIGHT key (inclusive).
*
- * Failure: Never fails
+ * Failure: FAIL (same as LT < RT)
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -364,15 +444,21 @@ H5G_node_cmp (hdf5_file_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key;
const char *s;
+ FUNC_ENTER (H5G_node_cmp, NULL, FAIL);
+
/* left side */
- s = H5H_peek (f, udata->heap, lt_key->offset);
- if (HDstrcmp (udata->name, s)<=0) return -1;
+ if (NULL==(s=H5H_peek (f, udata->heap, lt_key->offset))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
+ if (HDstrcmp (udata->name, s)<=0) HRETURN (-1);
/* right side */
- s = H5H_peek (f, udata->heap, rt_key->offset);
- if (HDstrcmp (udata->name, s)>0) return 1;
+ if (NULL==(s=H5H_peek (f, udata->heap, rt_key->offset))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
+ if (HDstrcmp (udata->name, s)>0) HRETURN(-1);
- return 0;
+ FUNC_LEAVE (0);
}
@@ -391,13 +477,13 @@ H5G_node_cmp (hdf5_file_t *f, void *_lt_key, void *_udata, void *_rt_key)
* entry field. Otherwise the entry is copied from the
* UDATA entry field to the symbol table.
*
- * Return: Success: 0 if found and data returned through the
+ * Return: Success: SUCCEED if found and data returned through the
* UDATA pointer.
*
- * Failure: -1 if not found.
+ * Failure: FAIL if not found.
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
@@ -413,8 +499,18 @@ H5G_node_found (hdf5_file_t *f, haddr_t addr, void *_lt_key, void *_udata,
intn lt=0, idx=0, rt, cmp=1;
const char *s;
- sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
- if (!sn) return -1;
+ FUNC_ENTER (H5G_node_found, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
rt = sn->nsyms;
/*
@@ -422,8 +518,12 @@ H5G_node_found (hdf5_file_t *f, haddr_t addr, void *_lt_key, void *_udata,
*/
while (lt<rt && cmp) {
idx = (lt + rt) / 2;
- sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
- s = H5H_peek (f, udata->heap, sn->entry[idx].name_off);
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
+ if (NULL==(s=H5H_peek (f, udata->heap, sn->entry[idx].name_off))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
cmp = HDstrcmp (udata->name, s);
if (cmp<0) {
@@ -432,7 +532,7 @@ H5G_node_found (hdf5_file_t *f, haddr_t addr, void *_lt_key, void *_udata,
lt = idx+1;
}
}
- if (cmp) return -1;
+ if (cmp) HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
switch (udata->operation) {
case H5G_OPER_FIND:
@@ -451,7 +551,7 @@ H5G_node_found (hdf5_file_t *f, haddr_t addr, void *_lt_key, void *_udata,
break;
}
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -484,7 +584,7 @@ H5G_node_found (hdf5_file_t *f, haddr_t addr, void *_lt_key, void *_udata,
* Failure: -1
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 24 1997
*
* Modifications:
@@ -508,6 +608,18 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
intn idx=-1, nsyms, cmp=1;
intn lt=0, rt; /*binary search cntrs */
+ FUNC_ENTER (H5G_node_insert, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (anchor);
+ assert (md_key);
+ assert (rt_key);
+ assert (udata);
+
/*
* Symbol tables are always split so the new symbol table node is
* to the right of the old one.
@@ -520,8 +632,9 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* Load the symbol node and buffer the entries so we don't have to
* worry about the cached value disappearing.
*/
- sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
- if (!sn) return -1;
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
HDmemcpy (ent, sn->entry, sn->nsyms * sizeof(H5G_entry_t));
rt = nsyms = sn->nsyms;
sn = NULL;
@@ -531,8 +644,12 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
*/
while (lt<rt) {
idx = (lt + rt) / 2;
- s = H5H_peek (f, udata->heap, ent[idx].name_off);
- if (0==(cmp=HDstrcmp (udata->name, s))) return -1; /*already present*/
+ if (NULL==(s=H5H_peek (f, udata->heap, ent[idx].name_off))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
+ if (0==(cmp=HDstrcmp (udata->name, s))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL); /*already present*/
+ }
if (cmp<0) {
rt = idx;
} else {
@@ -547,6 +664,7 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* with the new heap address.
*/
offset = H5H_insert (f, udata->heap, strlen(udata->name)+1, udata->name);
+ if (offset<0) HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
if (nsyms>=2*H5G_NODE_K) {
/*
@@ -556,7 +674,9 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
*/
/* The left node */
- sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
HDmemset (sn->entry+H5G_NODE_K, 0, H5G_NODE_K*sizeof(H5G_entry_t));
sn->nsyms = H5G_NODE_K;
sn->dirty += 1;
@@ -573,8 +693,12 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
md_key->offset = sn->entry[sn->nsyms-1].name_off;
/* The right node */
- new_node = H5G_node_new (f, NULL, NULL, NULL);
- sn = H5AC_find (f, H5AC_SNODE, new_node, NULL);
+ if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ }
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, new_node, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
HDmemcpy (sn->entry, ent+H5G_NODE_K,
H5G_NODE_K*sizeof(H5G_entry_t));
sn->nsyms = H5G_NODE_K;
@@ -598,7 +722,9 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
/*
* Add the new symbol to the node.
*/
- sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
sn->dirty += 1;
HDmemmove (sn->entry+idx+1, sn->entry+idx,
(sn->nsyms-idx) * sizeof (H5G_entry_t));
@@ -612,7 +738,7 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
}
}
- return new_node;
+ FUNC_LEAVE (new_node);
}
@@ -622,12 +748,12 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* Purpose: This function gets called during a directory list operation.
* It should fill in data in the UDATA struct.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jun 24 1997
*
* Modifications:
@@ -638,12 +764,23 @@ static herr_t
H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
{
H5G_node_list_t *udata = (H5G_node_list_t *)_udata;
- H5G_node_t *sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
+ H5G_node_t *sn = NULL;
off_t *offsets = NULL;
intn nsyms, i;
const char *s;
- if (!sn) return -1;
+ FUNC_ENTER (H5G_node_list, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (udata);
+
+ if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
+ HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ }
nsyms = sn->nsyms;
/*
@@ -653,7 +790,7 @@ H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
*/
if (udata->nsyms >= udata->maxentries) {
udata->nsyms += nsyms;
- return 0;
+ HRETURN (SUCCEED);
}
/*
@@ -677,11 +814,14 @@ H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
if (udata->name && udata->entry) {
for (i=0; i<nsyms && udata->nsyms+i<udata->maxentries; i++) {
s = H5H_peek (f, udata->heap, udata->entry[udata->nsyms+i].name_off);
+ if (!s) HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
udata->name[udata->nsyms+i] = H5MM_xstrdup (s);
}
} else if (udata->name) {
for (i=0; i<nsyms && udata->nsyms+i<udata->maxentries; i++) {
- s = H5H_peek (f, udata->heap, offsets[i]);
+ if (NULL==(s=H5H_peek (f, udata->heap, offsets[i]))) {
+ HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ }
udata->name[udata->nsyms+i] = H5MM_xstrdup (s);
}
offsets = H5MM_xfree (offsets);
@@ -691,7 +831,7 @@ H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
* Update the number of symbols.
*/
udata->nsyms += nsyms;
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -701,12 +841,12 @@ H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
* Purpose: Prints debugging information about a symbol table node
* or a B-tree node for a symbol table B-tree.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 4 1997
*
* Modifications:
@@ -719,18 +859,32 @@ H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
{
int i, j;
char buf[64];
- H5G_node_t *sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
+ H5G_node_t *sn = NULL;
+ herr_t status;
+
+ FUNC_ENTER (H5G_node_debug, NULL, FAIL);
+
+ /*
+ * Check arguments.
+ */
+ assert (f);
+ assert (addr>=0);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
/*
* If we couldn't load the symbol table node, then try loading the
* B-tree node.
*/
- if (!sn) {
- return H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
+ if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, NULL))) {
+ H5ECLEAR; /*discard that error*/
+ status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
+ if (status<0) HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ HRETURN (SUCCEED);
}
- if (!sn) return -1;
fprintf (stream, "%*sSymbol Table Node...\n", indent, "");
fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
"Dirty:",
@@ -773,14 +927,14 @@ H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
}
break;
- case H5G_CACHED_SYMTAB:
+ case H5G_CACHED_STAB:
fprintf (stream, "Symbol Table\n");
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
"B-tree address:",
- (unsigned long)(sn->entry[i].cache.symtab.btree));
+ (unsigned long)(sn->entry[i].cache.stab.btree));
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
"Heap address:",
- (unsigned long)(sn->entry[i].cache.symtab.heap));
+ (unsigned long)(sn->entry[i].cache.stab.heap));
break;
default:
@@ -788,6 +942,7 @@ H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
break;
}
}
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 5e08c4d..fdfa10c 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -6,7 +6,7 @@
*
* Created: H5Gprivate.h
* Jul 11 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Private stuff for the H5G package (symbol tables).
*
@@ -45,7 +45,7 @@
typedef enum H5G_type_t {
H5G_NOTHING_CACHED =0, /*nothing is cached */
H5G_CACHED_SDATA =1, /*simple dataset, `sdata' */
- H5G_CACHED_SYMTAB =2 /*symbol table, `symtab' */
+ H5G_CACHED_STAB =2 /*symbol table, `stab' */
} H5G_type_t;
/*
@@ -68,8 +68,8 @@ typedef struct H5G_entry_t {
struct {
haddr_t btree; /*file address of symbol table B-tree */
- haddr_t heap; /*file address of symtab name heap */
- } symtab;
+ haddr_t heap; /*file address of stab name heap */
+ } stab;
} cache; /*cached data from object header */
} H5G_entry_t;
diff --git a/src/H5Gproto.h b/src/H5Gproto.h
index 5c7a66d..4b0569f 100644
--- a/src/H5Gproto.h
+++ b/src/H5Gproto.h
@@ -6,7 +6,7 @@
*
* Created: H5Gproto.h
* Jul 11 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Prototypes for the H5G package (symbol tables).
*
diff --git a/src/H5H.c b/src/H5H.c
index 11ed3b2..8a58f2a 100644
--- a/src/H5H.c
+++ b/src/H5H.c
@@ -6,23 +6,29 @@
*
* Created: H5H.c
* Jul 16 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
- * Purpose: Heap functions.
+ * Purpose: Heap functions for the global small object heap
+ * and for local symbol table name heaps.
*
- * Modifications:
+ * Modifications:
+ *
+ * Robb Matzke, 5 Aug 1997
+ * Added calls to H5E.
*
*-------------------------------------------------------------------------
*/
#include <assert.h>
#include "hdf5.h"
+#include "H5private.h" /*library */
#include "H5ACprivate.h" /*cache */
#include "H5Hprivate.h" /*self */
#include "H5MFprivate.h" /*file memory management */
#include "H5MMprivate.h" /*core memory management */
#define H5H_FREE_NULL 1 /*end of free list on disk */
+#define PABLO_MASK H5H_mask
#define H5H_SIZEOF_HDR(F) \
(H5H_SIZEOF_MAGIC + /*heap signature */ \
@@ -50,6 +56,7 @@ typedef struct H5H_t {
H5H_free_t *freelist; /*the free list */
} H5H_t;
+/* PRIVATE PROTOTYPES */
static H5H_t *H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata);
static herr_t H5H_flush (hdf5_file_t *f, hbool_t dest, haddr_t addr,
H5H_t *heap);
@@ -62,6 +69,9 @@ static const H5AC_class_t H5AC_HEAP[1] = {{
(herr_t(*)(hdf5_file_t*,hbool_t,haddr_t,void*))H5H_flush,
}};
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
+
/*-------------------------------------------------------------------------
* Function: H5H_new
@@ -75,24 +85,37 @@ static const H5AC_class_t H5AC_HEAP[1] = {{
*
* Return: Success: File address of new heap.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 16 1997
*
* Modifications:
*
+ * Robb Matzke, 5 Aug 1997
+ * Takes a flag that determines the type of heap that is
+ * created.
+ *
*-------------------------------------------------------------------------
*/
haddr_t
-H5H_new (hdf5_file_t *f, size_t size_hint)
+H5H_new (hdf5_file_t *f, H5H_type_t heap_type, size_t size_hint)
{
H5H_t *heap = NULL;
size_t total_size; /*total heap size on disk */
haddr_t addr; /*heap file address */
-
+
+ FUNC_ENTER (H5H_new, NULL, FAIL);
+
+ /* check arguments */
assert (f);
+ if (H5H_GLOBAL==heap_type) {
+#ifndef NDEBUG
+ fprintf (stderr, "H5H_new: a local heap is used as the global heap\n");
+#endif
+ }
+
size_hint = MAX (0, size_hint);
if (size_hint && size_hint<H5H_SIZEOF_FREE(f)) {
size_hint = H5H_SIZEOF_FREE(f);
@@ -100,7 +123,9 @@ H5H_new (hdf5_file_t *f, size_t size_hint)
/* allocate file version */
total_size = H5H_SIZEOF_HDR(f) + size_hint;
- if ((addr = H5MF_alloc (f, total_size))<0) return -1;
+ if ((addr = H5MF_alloc (f, total_size))<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
/* allocate memory version */
heap = H5MM_xcalloc (1, sizeof(H5H_t));
@@ -121,9 +146,13 @@ H5H_new (hdf5_file_t *f, size_t size_hint)
/* add to cache */
heap->dirty = 1;
- H5AC_set (f, H5AC_HEAP, addr, heap);
-
- return addr;
+ if (H5AC_set (f, H5AC_HEAP, addr, heap)<0) {
+ heap->chunk = H5MM_xfree (heap->chunk);
+ heap->freelist = H5MM_xfree (heap->freelist);
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (addr);
}
@@ -137,7 +166,7 @@ H5H_new (hdf5_file_t *f, size_t size_hint)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 17 1997
*
* Modifications:
@@ -148,16 +177,23 @@ static H5H_t *
H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
{
uint8 hdr[20], *p;
- H5H_t *heap = H5MM_xcalloc (1, sizeof(H5H_t));
+ H5H_t *heap=NULL;
H5H_free_t *fl=NULL, *tail=NULL;
haddr_t free_block;
+ FUNC_ENTER (H5H_load, NULL, NULL);
+
+ /* check arguments */
+ assert (f);
assert (addr>0);
assert (H5H_SIZEOF_HDR(f) <= sizeof hdr);
assert (!udata);
- if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) goto error;
+ if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) {
+ HRETURN_ERROR (H5E_HEAP, H5E_READERROR, NULL);
+ }
p = hdr;
+ heap = H5MM_xcalloc (1, sizeof(H5H_t));
/* magic number */
if (HDmemcmp (hdr, H5H_MAGIC, H5H_SIZEOF_MAGIC)) goto error;
@@ -169,7 +205,9 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
/* free list head */
H5F_decode_offset (f, p, free_block);
- assert (-1==free_block || (free_block>=0 && free_block<heap->disk_alloc));
+ if (-1!=free_block && (free_block<0 || free_block>=heap->disk_alloc)) {
+ goto error;
+ }
/* data */
H5F_decode_offset (f, p, heap->addr);
@@ -182,7 +220,7 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
/* free list */
while (H5H_FREE_NULL!=free_block) {
- assert (free_block>=0 && free_block<heap->disk_alloc);
+ if (free_block<0 || free_block>=heap->disk_alloc) goto error;
fl = H5MM_xmalloc (sizeof (H5H_free_t));
fl->offset = free_block;
fl->prev = tail;
@@ -195,16 +233,22 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
H5F_decode_offset (f, p, free_block);
H5F_decode_length (f, p, fl->size);
- assert (fl->offset + fl->size <= heap->disk_alloc);
+ if (fl->offset + fl->size > heap->disk_alloc) goto error;
}
- return heap;
+
+ FUNC_LEAVE (heap);
+
error:
if (heap) {
heap->chunk = H5MM_xfree (heap->chunk);
H5MM_xfree (heap);
+ for (fl=heap->freelist; fl; fl=tail) {
+ tail = fl->next;
+ H5MM_xfree (fl);
+ }
}
- return NULL;
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
}
@@ -214,12 +258,12 @@ error:
* Purpose: Flushes a heap from memory to disk if it's dirty. Optionally
* deletes the heap from memory.
*
- * Return: Success: 0
+ * Return: Success: SUCCEED
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 17 1997
*
* Modifications:
@@ -231,6 +275,13 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
{
uint8 *p = heap->chunk;
H5H_free_t *fl = heap->freelist;
+
+ FUNC_ENTER (H5H_flush, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ assert (addr>0);
+ assert (heap);
if (heap->dirty) {
@@ -240,8 +291,11 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
* disk storage.
*/
if (heap->mem_alloc > heap->disk_alloc) {
- H5MF_free (f, heap->addr, heap->disk_alloc);
- heap->addr = H5MF_alloc (f, heap->mem_alloc);
+ haddr_t old_addr = heap->addr;
+ if ((heap->addr = H5MF_alloc (f, heap->mem_alloc))<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
+ H5MF_free (f, old_addr, heap->disk_alloc); /*don't care if fail*/
heap->disk_alloc = heap->mem_alloc;
}
@@ -273,15 +327,15 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
if (heap->addr == addr + H5H_SIZEOF_HDR(f)) {
if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f)+heap->disk_alloc,
heap->chunk)<0) {
- return -1;
+ HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL);
}
} else {
if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f), heap->chunk)<0) {
- return -1;
+ HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL);
}
if (H5F_block_write (f, heap->addr, heap->disk_alloc,
heap->chunk + H5H_SIZEOF_HDR(f))<0) {
- return -1;
+ HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL);
}
}
@@ -301,7 +355,7 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
H5MM_xfree (heap);
}
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -319,12 +373,15 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
* Attempting to read past the end of an object may cause this
* function to fail.
*
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
+ *
* Return: Success: BUF (or the allocated buffer)
*
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 16 1997
*
* Modifications:
@@ -334,14 +391,26 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
void *
H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
{
- H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *heap = NULL;
+
+ FUNC_ENTER (H5H_read, NULL, NULL);
+
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (offset>=0);
- assert (offset>=0 && offset<heap->mem_alloc);
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
+ }
+ assert (offset<heap->mem_alloc);
assert (offset+size<=heap->mem_alloc);
if (!buf) buf = H5MM_xmalloc (size);
HDmemcpy (buf, heap->chunk+H5H_SIZEOF_HDR(f)+offset, size);
- return buf;
+
+ FUNC_LEAVE (buf);
}
@@ -358,6 +427,9 @@ H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
* byte offset of the object from the beginning of the heap and
* may include an offset into the interior of the object.
*
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
+ *
* Return: Success: Ptr to the object. The pointer points to
* a chunk of memory large enough to hold the
* object from the specified offset (usually
@@ -368,7 +440,7 @@ H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
* Failure: NULL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 16 1997
*
* Modifications:
@@ -378,10 +450,24 @@ H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
const void *
H5H_peek (hdf5_file_t *f, haddr_t addr, off_t offset)
{
- H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *heap = NULL;
+ const void *retval = NULL;
- assert (offset>=0 && offset<heap->mem_alloc);
- return heap->chunk+H5H_SIZEOF_HDR(f)+offset;
+ FUNC_ENTER (H5H_peek, NULL, NULL);
+
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (offset>=0);
+
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
+ }
+ assert (offset<heap->mem_alloc);
+
+ retval = heap->chunk+H5H_SIZEOF_HDR(f)+offset;
+ FUNC_LEAVE (retval);
}
@@ -393,7 +479,7 @@ H5H_peek (hdf5_file_t *f, haddr_t addr, off_t offset)
* Return: void
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 17 1997
*
* Modifications:
@@ -415,12 +501,15 @@ H5H_remove_free (H5H_t *heap, H5H_free_t *fl)
*
* Purpose: Inserts a new item into the heap.
*
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
+ *
* Return: Success: Offset of new item within heap.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 17 1997
*
* Modifications:
@@ -430,11 +519,26 @@ H5H_remove_free (H5H_t *heap, H5H_free_t *fl)
off_t
H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
{
- H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *heap=NULL;
H5H_free_t *fl=NULL, *max_fl=NULL;
off_t offset = -1;
size_t need_more;
+#ifndef NDEBUG
+ static nmessages = 0;
+#endif
+
+ FUNC_ENTER (H5H_insert, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (size>0);
+ assert (buf);
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
+ }
heap->dirty += 1;
/*
@@ -477,10 +581,16 @@ H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
max_fl->size += need_more - size;
if (max_fl->size < H5H_SIZEOF_FREE(f)) {
+#ifndef NDEBUG
if (max_fl->size) {
fprintf (stderr, "H5H_insert: lost %d bytes at line %d\n",
max_fl->size, __LINE__);
+ if (0==nmessages++) {
+ fprintf (stderr, "Messages from H5H_insert() will go away "
+ "when assertions are turned off.\n");
+ }
}
+#endif
H5H_remove_free (heap, max_fl);
}
@@ -498,15 +608,27 @@ H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
fl->next = heap->freelist;
if (heap->freelist) heap->freelist->prev = fl;
heap->freelist = fl;
+#ifndef NDEBUG
} else if (need_more>size) {
fprintf (stderr, "H5H_insert: lost %d bytes at line %d\n",
need_more-size, __LINE__);
+ if (0==nmessages++) {
+ fprintf (stderr, "Messages from H5H_insert() will go away "
+ "when assertions are turned off.\n");
+ }
+#endif
}
}
+#ifndef NDEBUG
fprintf (stderr, "H5H_insert: resize mem buf from %lu to %lu bytes\n",
(unsigned long)(heap->mem_alloc),
(unsigned long)(heap->mem_alloc + need_more));
+ if (0==nmessages++) {
+ fprintf (stderr, "Messages from H5H_insert() will go away "
+ "when assertions are turned off.\n");
+ }
+#endif
heap->mem_alloc += need_more;
heap->chunk = H5MM_xrealloc (heap->chunk,
H5H_SIZEOF_HDR(f)+heap->mem_alloc);
@@ -516,7 +638,7 @@ H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
* Copy the data into the heap
*/
HDmemcpy (heap->chunk + H5H_SIZEOF_HDR(f) + offset, buf, size);
- return offset;
+ FUNC_LEAVE (offset);
}
@@ -531,12 +653,15 @@ H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
* Do not partially write an object to create it; the first
* write for an object must be for the entire object.
*
- * Return: Success: 0
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
*
- * Failure: -1
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 16 1997
*
* Modifications:
@@ -547,15 +672,27 @@ herr_t
H5H_write (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
const void *buf)
{
- H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *heap = NULL;
- assert (offset>=0 && offset<heap->mem_alloc);
- assert (offset+size<=heap->mem_alloc);
+ FUNC_ENTER (H5H_write, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (offset>=0);
assert (buf);
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
+ }
+ assert (offset<heap->mem_alloc);
+ assert (offset+size<=heap->mem_alloc);
+
heap->dirty += 1;
HDmemcpy (heap->chunk+H5H_SIZEOF_HDR(f)+offset, buf, size);
- return 0;
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -575,12 +712,15 @@ H5H_write (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
* in two separate objects, one at the original offset and
* one at the first offset past the removed portion.
*
- * Return: Success: 0
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
*
- * Failure: -1
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 16 1997
*
* Modifications:
@@ -590,10 +730,25 @@ H5H_write (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
herr_t
H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
{
- H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *heap = NULL;
H5H_free_t *fl = heap->freelist, *fl2 = NULL;
+#ifndef NDEBUG
+ static int nmessages = 0;
+#endif
+
+ FUNC_ENTER (H5H_remove, NULL, FAIL);
- assert (offset>=0 && offset<heap->mem_alloc);
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (offset>=0);
+ assert (size>0);
+
+ if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
+ }
+ assert (offset<heap->mem_alloc);
assert (offset+size<=heap->mem_alloc);
heap->dirty += 1;
@@ -613,10 +768,10 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
fl->offset = fl2->offset;
fl->size += fl2->size;
H5H_remove_free (heap, fl2);
- return 0;
+ HRETURN (SUCCEED);
}
}
- return 0;
+ HRETURN (SUCCEED);
} else if (fl->offset + fl->size == offset) {
fl->size += size;
@@ -625,10 +780,10 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
if (fl->offset + fl->size == fl2->offset) {
fl->size += fl2->size;
H5H_remove_free (heap, fl2);
- return 0;
+ HRETURN (SUCCEED);
}
}
- return 0;
+ HRETURN (SUCCEED);
}
fl = fl->next;
@@ -641,8 +796,14 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
* lost.
*/
if (size < H5H_SIZEOF_FREE(f)) {
+#ifndef NDEUBG
fprintf (stderr, "H5H_remove: lost %d bytes\n", size);
- return 0;
+ if (0==nmessages++) {
+ fprintf (stderr, "Messages from H5H_remove() will go away "
+ "when assertions are turned off.\n");
+ }
+#endif
+ HRETURN (SUCCEED);
}
/*
@@ -656,7 +817,7 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
if (heap->freelist) heap->freelist->prev = fl;
heap->freelist = fl;
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
@@ -665,12 +826,15 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
*
* Purpose: Prints debugging information about a heap.
*
- * Return: Success: 0
+ * If the heap address ADDR is the constant H5H_GLOBAL then
+ * the address comes from the hdf5_file_t global heap field.
*
- * Failure: -1
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Aug 1 1997
*
* Modifications:
@@ -681,14 +845,26 @@ herr_t
H5H_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
intn fwidth)
{
- H5H_t *h = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ H5H_t *h = NULL;
int i, j, overlap;
uint8 c;
H5H_free_t *freelist=NULL;
uint8 *marker = NULL;
size_t amount_free = 0;
- if (!h) return -1;
+ FUNC_ENTER (H5H_debug, NULL, FAIL);
+
+ /* check arguments */
+ assert (f);
+ if (H5H_GLOBAL==addr) addr = f->smallobj_off;
+ assert (addr>0);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
+ HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
+ }
fprintf (stream, "%*sHeap...\n", indent, "");
fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
@@ -771,5 +947,5 @@ H5H_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
}
H5MM_xfree (marker);
- return 0;
+ FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Hprivate.h b/src/H5Hprivate.h
index 0c31df3..dc5318f 100644
--- a/src/H5Hprivate.h
+++ b/src/H5Hprivate.h
@@ -6,7 +6,7 @@
*
* Created: H5Hprivate.h
* Jul 16 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose:
*
@@ -23,10 +23,15 @@
#define H5H_MAGIC "HEAP" /*heap magic number */
#define H5H_SIZEOF_MAGIC 4
+typedef enum H5H_type_t {
+ H5H_LOCAL =0, /*local symtab name heap */
+ H5H_GLOBAL =1 /*global small object heap */
+} H5H_type_t;
+
/*
* Library prototypes...
*/
-haddr_t H5H_new (hdf5_file_t *f, size_t size_hint);
+haddr_t H5H_new (hdf5_file_t *f, H5H_type_t type, size_t size_hint);
void *H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
void *buf);
const void *H5H_peek (hdf5_file_t *f, haddr_t addr, off_t offset);
diff --git a/src/H5Hproto.h b/src/H5Hproto.h
index fcf36f8..93661ac 100644
--- a/src/H5Hproto.h
+++ b/src/H5Hproto.h
@@ -6,7 +6,7 @@
*
* Created: H5Hproto.h
* Jul 16 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose:
*
diff --git a/src/H5MF.c b/src/H5MF.c
index 16c2746..b6900cc 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -6,20 +6,29 @@
*
* Created: H5MF.c
* Jul 11 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: File memory management functions.
*
- * Modifications:
+ * Modifications:
+ *
+ * Robb Matzke, 5 Aug 1997
+ * Added calls to H5E.
*
*-------------------------------------------------------------------------
*/
#include <assert.h>
#include "hdf5.h"
+#include "H5private.h"
#include "H5Fprivate.h"
#include "H5MFprivate.h"
+#define PABLO_MASK H5MF_mask
+
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
+
/*-------------------------------------------------------------------------
* Function: H5MF_alloc
@@ -30,10 +39,10 @@
*
* Return: Success: File address of new chunk.
*
- * Failure: -1
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 11 1997
*
* Modifications:
@@ -44,14 +53,19 @@ haddr_t
H5MF_alloc (hdf5_file_t *f, size_t size)
{
haddr_t addr;
-
+
+ FUNC_ENTER (H5MF_alloc, NULL, FAIL);
+
+ /* check arguments */
assert (f);
assert (f->logical_len>0);
assert (size>0);
+ /* reserve space from the end of the file */
addr = f->logical_len;
f->logical_len += size;
- return addr;
+
+ FUNC_LEAVE (addr);
}
@@ -68,7 +82,7 @@ H5MF_alloc (hdf5_file_t *f, size_t size)
* Failure: -1
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 17 1997
*
* Modifications:
@@ -78,11 +92,17 @@ H5MF_alloc (hdf5_file_t *f, size_t size)
herr_t
H5MF_free (hdf5_file_t *f, haddr_t addr, size_t size)
{
- if (addr<=0 || 0==size) return 0;
+ FUNC_ENTER (H5MF_free, NULL, FAIL);
+ /* check arguments */
+ assert (f);
+ if (addr<=0 || 0==size) HRETURN (SUCCEED);
+
+#ifndef NDEBUG
fprintf (stderr, "H5MF_free: lost %lu bytes of file storage\n",
(unsigned long)size);
-
- return 0;
+#endif
+
+ FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h
index 19265ac..e87ca58 100644
--- a/src/H5MFprivate.h
+++ b/src/H5MFprivate.h
@@ -6,7 +6,7 @@
*
* Created: H5MFprivate.h
* Jul 11 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Private header file for file memory management.
*
diff --git a/src/H5MFproto.h b/src/H5MFproto.h
index 3b54ecd..72e24f6 100644
--- a/src/H5MFproto.h
+++ b/src/H5MFproto.h
@@ -6,7 +6,7 @@
*
* Created: H5MFproto.h
* Jul 11 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Prototypes for file memory management.
*
diff --git a/src/H5MM.c b/src/H5MM.c
index 725085f..74cce42 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -6,7 +6,7 @@
*
* Created: H5MM.c
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Memory management functions.
*
@@ -30,7 +30,7 @@
* Failure: abort()
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -56,7 +56,7 @@ H5MM_xmalloc (size_t size)
* Failure: abort()
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -89,7 +89,7 @@ H5MM_xcalloc (size_t n, size_t size)
* Failure: abort()
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -127,7 +127,7 @@ H5MM_xrealloc (void *mem, size_t size)
* Failure: abort()
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
@@ -160,7 +160,7 @@ H5MM_xstrdup (const char *s)
* Failure: never fails
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 10 1997
*
* Modifications:
diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h
index 68dd73b..f4890df 100644
--- a/src/H5MMprivate.h
+++ b/src/H5MMprivate.h
@@ -6,7 +6,7 @@
*
* Created: H5MMprivate.h
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Private header for memory management.
*
diff --git a/src/H5MMproto.h b/src/H5MMproto.h
index e1598f8..c4ef18f 100644
--- a/src/H5MMproto.h
+++ b/src/H5MMproto.h
@@ -6,7 +6,7 @@
*
* Created: H5MMproto.h
* Jul 10 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Function prototypes for memory management.
*
diff --git a/src/H5O.c b/src/H5O.c
new file mode 100644
index 0000000..6e899fc
--- /dev/null
+++ b/src/H5O.c
@@ -0,0 +1,1242 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5O.c
+ * Aug 5 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: Object header virtual functions.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <assert.h>
+
+#include "hdf5.h"
+
+#include "H5private.h"
+#include "H5ACprivate.h"
+#include "H5Fprivate.h"
+#include "H5MFprivate.h"
+#include "H5MMprivate.h"
+#include "H5Oprivate.h"
+
+#define PABLO_MASK H5O_mask
+
+/* PRIVATE PROTOTYPES */
+static herr_t H5O_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr,
+ H5O_t *oh);
+static H5O_t *H5O_load (hdf5_file_t *f, haddr_t addr, const void *_data);
+static intn H5O_find_in_ohdr (hdf5_file_t *f, haddr_t addr,
+ const H5O_class_t **type_p, intn sequence);
+static intn H5O_alloc (hdf5_file_t *f, H5O_t *oh, const H5O_class_t *type,
+ size_t size);
+static intn H5O_alloc_extend_chunk (H5O_t *oh, intn chunkno, size_t size);
+static intn H5O_alloc_new_chunk (hdf5_file_t *f, H5O_t *oh, size_t size);
+
+/* H5O inherits cache-like properties from H5AC */
+static const H5AC_class_t H5AC_OHDR[1] = {{
+ (void*(*)(hdf5_file_t*,haddr_t,const void*))H5O_load,
+ (herr_t(*)(hdf5_file_t*,hbool_t,haddr_t,void*))H5O_flush,
+}};
+
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
+
+/* ID to type mapping */
+static const H5O_class_t *const message_type_g[] = {
+ H5O_NULL, /*0x0000 Null */
+ NULL, /*0x0001 Simple dimensionality */
+ NULL, /*0x0002 Data space (fiber bundle?) */
+ NULL, /*0x0003 Simple data type */
+ NULL, /*0x0004 Compound data type */
+ NULL, /*0x0005 Data storage -- standard object */
+ NULL, /*0x0006 Data storage -- compact object */
+ NULL, /*0x0007 Data storage -- external object */
+ NULL, /*0x0008 Data storage -- indexed object */
+ NULL, /*0x0009 Data storage -- chunked object */
+ NULL, /*0x000A Data storage -- sparse object */
+ NULL, /*0x000B Data storage -- compressed object */
+ NULL, /*0x000C Attribute list */
+ NULL, /*0x000D Object name */
+ NULL, /*0x000E Object modification date and time */
+ NULL, /*0x000F Shared header message */
+ H5O_CONT, /*0x0010 Object header continuation */
+ H5O_STAB, /*0x0011 Symbol table */
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_new
+ *
+ * Purpose: Creates a new object header, sets the link count
+ * to NLINK, and caches the header.
+ *
+ * Return: Success: Address of new header.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+haddr_t
+H5O_new (hdf5_file_t *f, intn nlink, size_t size_hint)
+{
+ size_t size; /*total size of object header */
+ haddr_t addr = FAIL; /*address of object header */
+ H5O_t *oh = NULL;
+
+ FUNC_ENTER (H5O_new, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (nlink>0);
+ if (size_hint<H5O_MIN_SIZE) size_hint = H5O_MIN_SIZE;
+ H5O_ALIGN (size_hint, H5O_ALIGNMENT);
+
+ /* allocate disk space for header and first chunk */
+ size = H5O_SIZEOF_HDR(f) + size_hint;
+ if ((addr = H5MF_alloc (f, size))<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
+
+ /* allocate the object header in fill in header fields */
+ oh = H5MM_xcalloc (1, sizeof(H5O_t));
+ oh->dirty = TRUE;
+ oh->version = H5O_VERSION;
+ oh->alignment = H5O_ALIGNMENT;
+ oh->nlink = nlink;
+
+ /* create the chunk list and initialize the first chunk */
+ oh->nchunks = 1;
+ oh->alloc_nchunks = H5O_NCHUNKS;
+ oh->chunk = H5MM_xmalloc (oh->alloc_nchunks * sizeof (H5O_chunk_t));
+
+ oh->chunk[0].dirty = TRUE;
+ oh->chunk[0].addr = addr + H5O_SIZEOF_HDR(f);
+ oh->chunk[0].size = size_hint;
+ oh->chunk[0].image = H5MM_xmalloc (size_hint);
+
+ /* create the message list and initialize the first message */
+ oh->nmesgs = 1;
+ oh->alloc_nmesgs = H5O_NMESGS;
+ oh->mesg = H5MM_xcalloc (oh->alloc_nmesgs, sizeof(H5O_mesg_t));
+
+ oh->mesg[0].type = H5O_NULL;
+ oh->mesg[0].dirty = TRUE;
+ oh->mesg[0].native = NULL;
+ oh->mesg[0].raw = oh->chunk[0].image + 4; /*skip id and size fields */
+ oh->mesg[0].raw_size = size_hint - 4;
+ oh->mesg[0].chunkno = 0;
+
+ /* cache it */
+ if (H5AC_set (f, H5AC_OHDR, addr, oh)<0) {
+ H5MM_xfree (oh);
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_load
+ *
+ * Purpose: Loads an object header from disk.
+ *
+ * Return: Success: Pointer to the new object header.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5O_t *
+H5O_load (hdf5_file_t *f, haddr_t addr, const void *_data)
+{
+ H5O_t *oh = NULL;
+ uint8 buf[16], *p;
+ size_t hdr_size, mesg_size;
+ uintn id;
+ intn mesgno, chunkno, curmesg=0, nmesgs;
+ haddr_t chunk_addr;
+ size_t chunk_size;
+ H5O_cont_t *cont=NULL;
+
+ FUNC_ENTER (H5O_load, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (!_data);
+
+ /* allocate ohdr and init chunk list */
+ oh = H5MM_xcalloc (1, sizeof(H5O_t));
+
+ /* read fixed-lenth part of object header */
+ hdr_size = H5O_SIZEOF_HDR (f);
+ if (H5F_block_read (f, addr, hdr_size, buf)<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_READERROR, NULL);
+ }
+ p = buf;
+
+ /* decode version */
+ oh->version = *p++;
+ if (H5O_VERSION!=oh->version) {
+ HRETURN_ERROR (H5E_OHDR, H5E_VERSION, NULL);
+ }
+
+ /* decode alignment */
+ oh->alignment = *p++;
+ if (4!=oh->alignment) {
+ HRETURN_ERROR (H5E_OHDR, H5E_ALIGNMENT, NULL);
+ }
+
+ /* decode number of messages */
+ UINT16DECODE (p, nmesgs);
+
+ /* decode link count */
+ UINT32DECODE (p, oh->nlink);
+
+ /* decode first chunk info */
+ chunk_addr = addr + H5O_SIZEOF_HDR(f);
+ UINT32DECODE (p, chunk_size);
+
+ /* build the message array */
+ oh->alloc_nmesgs = MAX (H5O_NMESGS, nmesgs);
+ oh->mesg = H5MM_xcalloc (oh->alloc_nmesgs, sizeof(H5O_mesg_t));
+
+ /* read each chunk from disk */
+ while (chunk_addr) {
+
+ /* increase chunk array size */
+ if (oh->nchunks>=oh->alloc_nchunks) {
+ oh->alloc_nchunks += H5O_NCHUNKS;
+ oh->chunk = H5MM_xrealloc (oh->chunk,
+ oh->alloc_nchunks * sizeof(H5O_chunk_t));
+ }
+
+ /* read the chunk raw data */
+ chunkno = oh->nchunks++;
+ oh->chunk[chunkno].dirty = FALSE;
+ oh->chunk[chunkno].addr = chunk_addr;
+ oh->chunk[chunkno].size = chunk_size;
+ oh->chunk[chunkno].image = H5MM_xmalloc (chunk_size);
+ if (H5F_block_read (f, chunk_addr, chunk_size,
+ oh->chunk[chunkno].image)<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_READERROR, NULL);
+ }
+
+
+ /* load messages from this chunk */
+ for (p = oh->chunk[chunkno].image;
+ p < oh->chunk[chunkno].image + chunk_size;
+ p += mesg_size) {
+ UINT16DECODE (p, id);
+ UINT16DECODE (p, mesg_size);
+
+ if (id>=NELMTS(message_type_g) || NULL==message_type_g[id]) {
+ HRETURN_ERROR (H5E_OHDR, H5E_BADMESG, NULL);
+ }
+ if (p + mesg_size > oh->chunk[chunkno].image + chunk_size) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, NULL);
+ }
+
+ mesgno = oh->nmesgs++;
+ if (mesgno>=nmesgs) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
+ }
+ oh->mesg[mesgno].type = message_type_g[id];
+ oh->mesg[mesgno].dirty = FALSE;
+ oh->mesg[mesgno].native = NULL;
+ oh->mesg[mesgno].raw = p;
+ oh->mesg[mesgno].raw_size = mesg_size;
+ oh->mesg[mesgno].chunkno = chunkno;
+ }
+ assert (p == oh->chunk[chunkno].image + chunk_size);
+
+ /* decode next object header continuation message */
+ for (chunk_addr=0; 0==chunk_addr && curmesg<oh->nmesgs; curmesg++) {
+ if (H5O_CONT_ID==oh->mesg[curmesg].type->id) {
+ uint8 *p2 = oh->mesg[curmesg].raw;
+ oh->mesg[curmesg].native = (H5O_CONT->decode)(f, p2);
+ cont = (H5O_cont_t*)(oh->mesg[curmesg].native);
+ chunk_addr = cont->addr;
+ chunk_size = cont->size;
+ cont->chunkno = oh->nchunks; /*the next chunk to allocate*/
+ }
+ }
+ }
+
+ FUNC_LEAVE (oh);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_flush
+ *
+ * Purpose: Flushes (and destroys) an object header.
+ *
+ * Return: Success: SUCCESS
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
+{
+ uint8 buf[16], *p;
+ int i;
+ H5O_cont_t *cont = NULL;
+
+ FUNC_ENTER (H5O_flush, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (oh);
+
+ /* flush */
+ if (oh->dirty) {
+ p = buf;
+
+ /* encode version */
+ *p++ = oh->version;
+
+ /* encode alingment */
+ *p++ = oh->alignment;
+
+ /* encode number of messages */
+ UINT16ENCODE (p, oh->nmesgs);
+
+ /* encode link count */
+ UINT32ENCODE (p, oh->nlink);
+
+ /* encode body size */
+ UINT32ENCODE (p, oh->chunk[0].size);
+
+ /* write the object header header */
+ if (H5F_block_write (f, addr, H5O_SIZEOF_HDR(f), buf)<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL);
+ }
+
+ /* encode messages */
+ for (i=0; i<oh->nmesgs; i++) {
+ if (oh->mesg[i].dirty) {
+ p = oh->mesg[i].raw - 4;
+ UINT16ENCODE (p, oh->mesg[i].type->id);
+ UINT16ENCODE (p, oh->mesg[i].raw_size);
+ if (oh->mesg[i].native) {
+ assert (oh->mesg[i].type->encode);
+
+ /* allocate file space for chunks that have none yet */
+ if (H5O_CONT_ID==oh->mesg[i].type->id &&
+ ((H5O_cont_t*)(oh->mesg[i].native))->addr<0) {
+ cont = (H5O_cont_t*)(oh->mesg[i].native);
+ assert (cont->chunkno >= 0);
+ assert (cont->chunkno < oh->nchunks);
+ assert (oh->chunk[cont->chunkno].addr<0);
+ cont->size = oh->chunk[cont->chunkno].size;
+ cont->addr = H5MF_alloc (f, cont->size);
+ if (cont->addr<0) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ }
+ oh->chunk[cont->chunkno].addr = cont->addr;
+ }
+
+ /* encode the message */
+ assert (oh->mesg[i].raw >=
+ oh->chunk[oh->mesg[i].chunkno].image);
+ assert (oh->mesg[i].raw + oh->mesg[i].raw_size <=
+ oh->chunk[oh->mesg[i].chunkno].image +
+ oh->chunk[oh->mesg[i].chunkno].size);
+ if ((oh->mesg[i].type->encode)(f, oh->mesg[i].raw_size,
+ oh->mesg[i].raw,
+ oh->mesg[i].native)<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL);
+ }
+ }
+ oh->mesg[i].dirty = FALSE;
+ oh->chunk[oh->mesg[i].chunkno].dirty = TRUE;
+ }
+ }
+
+ /* write each chunk to disk */
+ for (i=0; i<oh->nchunks; i++) {
+ if (oh->chunk[i].dirty) {
+ assert (oh->chunk[i].addr>0);
+ if (H5F_block_write (f, oh->chunk[i].addr, oh->chunk[i].size,
+ oh->chunk[i].image)<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL);
+ }
+ oh->chunk[i].dirty = FALSE;
+ }
+ }
+ oh->dirty = FALSE;
+ }
+
+
+ if (destroy) {
+ /* destroy chunks */
+ for (i=0; i<oh->nchunks; i++) {
+ oh->chunk[i].image = H5MM_xfree (oh->chunk[i].image);
+ }
+ oh->chunk = H5MM_xfree (oh->chunk);
+
+ /* destroy messages */
+ for (i=0; i<oh->nmesgs; i++) {
+ if (oh->mesg[i].native) {
+ if (oh->mesg[i].type->free) {
+ (oh->mesg[i].type->free)(oh->mesg[i].native);
+ oh->mesg[i].native = NULL;
+ } else {
+ oh->mesg[i].native = H5MM_xfree (oh->mesg[i].native);
+ }
+ }
+ }
+ oh->mesg = H5MM_xfree (oh->mesg);
+
+ /* destroy object header */
+ H5MM_xfree (oh);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link
+ *
+ * Purpose: Adjust the link count for an object header by adding
+ * ADJUST to the link count.
+ *
+ * Return: Success: New link count
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5O_link (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent, intn adjust)
+{
+ H5O_t *oh = NULL;
+
+ FUNC_ENTER (H5O_link, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+
+ /* get header */
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
+ }
+
+ /* adjust link count */
+ if (adjust<0) {
+ if (oh->nlink + adjust < 0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL);
+ }
+ oh->nlink += adjust;
+ if (1==oh->nlink && ent) {
+ fprintf (stderr, "H5O_link: no symbol table entry caching "
+ "(not implemented yet)\n");
+ }
+ } else {
+ oh->nlink += adjust;
+ if (oh->nlink>1 && ent) ent->type = H5G_NOTHING_CACHED;
+ }
+
+
+ oh->dirty = TRUE;
+ FUNC_LEAVE (oh->nlink);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_read
+ *
+ * Purpose: Reads a message from an object header and returns a pointer
+ * to it. The caller will usually supply the memory through
+ * MESG and the return value will be MESG. But if MESG is
+ * the null pointer, then this function will malloc() memory
+ * to hold the result and return its pointer instead.
+ *
+ * Return: Success: Ptr to message in native format.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5O_read (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
+ const H5O_class_t *type, intn sequence, void *mesg)
+{
+ H5O_t *oh = NULL;
+ void *retval = NULL;
+ intn idx;
+
+ FUNC_ENTER (H5O_read, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (sequence>=0);
+
+ /* can we get it from the symbol table? */
+ if (ent && H5G_NOTHING_CACHED!=ent->type && type && type->fast) {
+ retval = (type->fast)(ent, mesg);
+ if (retval) HRETURN (retval);
+ H5ECLEAR;
+ }
+
+ /* can we get it from the object header? */
+ if ((idx = H5O_find_in_ohdr (f, addr, &type, sequence))<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, NULL);
+ }
+
+ /* copy the message to the user-supplied buffer */
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
+ }
+ retval = (type->copy)(oh->mesg[idx].native, mesg);
+ if (!retval) HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, NULL);
+
+ FUNC_LEAVE (retval);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_find_in_ohdr
+ *
+ * Purpose: Find a message in the object header without consulting
+ * a symbol table entry.
+ *
+ * Return: Success: Index number of message.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5O_find_in_ohdr (hdf5_file_t *f, haddr_t addr, const H5O_class_t **type_p,
+ intn sequence)
+{
+ H5O_t *oh = NULL;
+ int i;
+
+ FUNC_ENTER (H5O_find_in_ohdr, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (type_p);
+
+ /* load the object header */
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
+ }
+
+ /* scan through the messages looking for the right one */
+ for (i=0; i<oh->nmesgs; i++) {
+ if (*type_p && (*type_p)->id!=oh->mesg[i].type->id) continue;
+ if (--sequence<0) break;
+ }
+ if (sequence>=0) HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, FAIL);
+
+ /* decode the message if necessary */
+ if (NULL==oh->mesg[i].native) {
+ assert (oh->mesg[i].type->decode);
+ oh->mesg[i].native = (oh->mesg[i].type->decode)(f, oh->mesg[i].raw);
+ if (NULL==oh->mesg[i].native) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTDECODE, FAIL);
+ }
+ }
+
+ /*return the message type */
+ *type_p = oh->mesg[i].type;
+
+ FUNC_LEAVE (i);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_peek
+ *
+ * Purpose: Returns a pointer to a message stored in native format.
+ * The returned memory is read-only, and points directly into
+ * the cache. It is therefore valid only until the next cache
+ * function is called.
+ *
+ * Return: Success: Ptr to read-only message in native format.
+ * The pointer is guranteed to be valid only
+ * until the next call (directly or indirectly)
+ * to an H5AC function.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+const void *
+H5O_peek (hdf5_file_t *f, haddr_t addr, const H5O_class_t *type,
+ intn sequence)
+{
+ intn idx;
+ H5O_t *oh = NULL;
+
+ FUNC_ENTER (H5O_peek, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+
+ if ((idx = H5O_find_in_ohdr (f, addr, &type, sequence))<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, NULL);
+ }
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
+ }
+
+ FUNC_LEAVE (oh->mesg[idx].native);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_modify
+ *
+ * Purpose: Modifies an existing message or creates a new message.
+ * The object header is at file address ADDR of file F. An
+ * optional symbol table entry ENT can be supplied in which
+ * case the cache fields in that symbol table are updated if
+ * appropriate. If the symbol table entry changes then the
+ * optional ENT_MODIFIED arg will point to a non-zero value.
+ *
+ * The OVERWRITE argument is either a sequence number of a
+ * message to overwrite (usually zero) or the constant
+ * H5O_NEW_MESSAGE (-1) to indicate that a new message is to
+ * be created.
+ *
+ * Return: Success: The sequence number of the message that
+ * was modified or created.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
+ hbool_t *ent_modified, const H5O_class_t *type,
+ intn overwrite, const void *mesg)
+{
+ H5O_t *oh = NULL;
+ intn idx, sequence;
+ size_t size;
+
+ FUNC_ENTER (H5O_modify, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (type);
+ assert (mesg);
+
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
+ }
+
+ /* Count similar messages */
+ for (idx=sequence=0; idx<oh->nmesgs; idx++) {
+ if (type->id != oh->mesg[idx].type->id) continue;
+ if (sequence==overwrite) break;
+ sequence++;
+ }
+
+ /* Was the right message found? */
+ if (overwrite>=0 && sequence!=overwrite) {
+ HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, FAIL);
+ }
+
+ /* Allocate space for the new message */
+ if (overwrite<0) {
+ size = (type->size)(f, mesg);
+ H5O_ALIGN (size, oh->alignment);
+ idx = H5O_alloc (f, oh, type, size);
+ if (idx<0) HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL);
+ }
+
+ /* Copy the native value into the object header */
+ oh->mesg[idx].native = (type->copy)(mesg, oh->mesg[idx].native);
+ if (NULL==oh->mesg[idx].native) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL);
+ }
+ oh->mesg[idx].dirty = TRUE;
+ oh->dirty = TRUE;
+
+ /* Copy into the symbol table entry */
+ if (1==oh->nlink && ent && type->cache) {
+ hbool_t modified = (type->cache)(ent, mesg);
+ if (ent_modified) *ent_modified = modified;
+ }
+
+ FUNC_LEAVE (sequence);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_alloc_extend_chunk
+ *
+ * Purpose: Extends a chunk which hasn't been allocated on disk yet
+ * to make the chunk large enough to contain a message whose
+ * data size is at least SIZE bytes.
+ *
+ * If the last message of the chunk is the null message, then
+ * that message will be extended with the chunk. Otherwise a
+ * new null message is created.
+ *
+ * Return: Success: Message index for null message which
+ * is large enough to hold SIZE bytes.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 7 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5O_alloc_extend_chunk (H5O_t *oh, intn chunkno, size_t size)
+{
+ intn idx, i;
+ size_t delta;
+ uint8 *old_addr;
+
+ FUNC_ENTER (H5O_alloc_extend_chunk, NULL, FAIL);
+
+ /* check args */
+ assert (oh);
+ assert (chunkno>=0 && chunkno<oh->nchunks);
+ assert (size>0);
+
+ if (H5O_NO_ADDR!=oh->chunk[chunkno].addr) {
+ HRETURN_ERROR (H5E_OHDR, H5E_NOSPACE, FAIL); /*chunk is on disk*/
+ }
+
+ /* try to extend a null message */
+ for (idx=0; idx<oh->nmesgs; idx++) {
+ if (H5O_NULL_ID==oh->mesg[idx].type->id &&
+ (oh->mesg[idx].raw + oh->mesg[idx].raw_size ==
+ oh->chunk[chunkno].image + oh->chunk[chunkno].size)) {
+
+ delta = MAX (H5O_MIN_SIZE, size-oh->mesg[idx].raw_size);
+ H5O_ALIGN (delta, oh->alignment);
+ oh->mesg[idx].dirty = TRUE;
+ oh->mesg[idx].raw_size += delta;
+
+ old_addr = oh->chunk[chunkno].image;
+ oh->chunk[chunkno].size += delta;
+ oh->chunk[chunkno].image = H5MM_xrealloc (old_addr,
+ oh->chunk[chunkno].size);
+
+ /* adjust raw addresses for messages of this chunk */
+ if (old_addr != oh->chunk[chunkno].image) {
+ for (i=0; i<oh->nmesgs; i++) {
+ if (oh->mesg[i].chunkno==chunkno) {
+ oh->mesg[i].raw = oh->chunk[chunkno].image +
+ (oh->mesg[i].raw - old_addr);
+ }
+ }
+ }
+ HRETURN (idx);
+ }
+ }
+
+ /* create a new null message */
+ if (oh->nmesgs >= oh->alloc_nmesgs) {
+ oh->alloc_nmesgs += H5O_NMESGS;
+ oh->mesg = H5MM_xrealloc (oh->mesg,
+ oh->alloc_nmesgs * sizeof(H5O_mesg_t));
+ }
+
+ delta = MAX (H5O_MIN_SIZE, 4+size);
+ H5O_ALIGN (delta, oh->alignment);
+ idx = oh->nmesgs++;
+ oh->mesg[idx].type = H5O_NULL;
+ oh->mesg[idx].dirty = TRUE;
+ oh->mesg[idx].native = NULL;
+ oh->mesg[idx].raw = oh->chunk[chunkno].image + oh->chunk[chunkno].size + 4;
+ oh->mesg[idx].raw_size = delta-4;
+ oh->mesg[idx].chunkno = chunkno;
+
+ old_addr = oh->chunk[chunkno].image;
+ oh->chunk[chunkno].size += delta;
+ oh->chunk[chunkno].image = H5MM_xrealloc (old_addr,
+ oh->chunk[chunkno].size);
+
+ /* adjust raw addresses for messages of this chunk */
+ if (old_addr != oh->chunk[chunkno].image) {
+ for (i=0; i<oh->nmesgs; i++) {
+ if (oh->mesg[i].chunkno==chunkno) {
+ oh->mesg[i].raw = oh->chunk[chunkno].image +
+ (oh->mesg[i].raw - old_addr);
+ }
+ }
+ }
+
+ FUNC_LEAVE (idx);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_alloc_new_chunk
+ *
+ * Purpose: Allocates a new chunk for the object header but doen't
+ * give the new chunk a file address yet. One of the other
+ * chunks will get an object continuation message. If there
+ * isn't room in any other chunk for the object continuation
+ * message, then some message from another chunk is moved into
+ * this chunk to make room.
+ *
+ * Return: Success: Index number of the null message for the
+ * new chunk. The null message will be at
+ * least SIZE bytes not counting the message
+ * ID or size fields.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 7 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5O_alloc_new_chunk (hdf5_file_t *f, H5O_t *oh, size_t size)
+{
+ size_t cont_size; /*continuation message size */
+ intn found_null=(-1); /*best fit null message */
+ intn found_other=(-1); /*best fit other message */
+ intn idx=FAIL; /*message number return value */
+ uint8 *p = NULL; /*ptr into new chunk */
+ H5O_cont_t *cont = NULL; /*native continuation message */
+ intn i, chunkno;
+
+ FUNC_ENTER (H5O_alloc_new_chunk, NULL, FAIL);
+
+ /* check args */
+ assert (oh);
+ assert (size>0);
+
+ /*
+ * Find the smallest null message that will hold an object
+ * continuation message. Failing that, find the smallest message
+ * that could be moved to make room for the continuation message.
+ * Don't ever move continuation message from one chunk to another.
+ */
+ cont_size = H5F_SIZEOF_OFFSET(f) + H5F_SIZEOF_SIZE(f);
+ for (i=0; i<oh->nmesgs; i++) {
+ if (H5O_NULL_ID == oh->mesg[i].type->id) {
+ if (cont_size == oh->mesg[i].raw_size) {
+ found_null = i;
+ break;
+ } else if (oh->mesg[i].raw_size >= cont_size &&
+ (found_null<0 ||
+ oh->mesg[i].raw_size < oh->mesg[found_null].raw_size)) {
+ found_null = i;
+ }
+ } else if (H5O_CONT_ID == oh->mesg[i].type->id) {
+ /*don't consider continuation messages */
+ } else if (oh->mesg[i].raw_size >= cont_size &&
+ (found_other<0 ||
+ oh->mesg[i].raw_size < oh->mesg[found_other].raw_size)) {
+ found_other = i;
+ }
+ }
+ assert (found_null>=0 || found_other>=0);
+
+ /*
+ * If we must move some other message to make room for the null
+ * message, then make sure the new chunk has enough room for that
+ * other message.
+ */
+ if (found_null<0) size += 4 + oh->mesg[found_other].raw_size;
+
+ /*
+ * The total chunk size must include the requested space plus enough
+ * for the message header. This must be at least some minimum and a
+ * multiple of the alignment size.
+ */
+ size = MAX (H5O_MIN_SIZE, size+4);
+ H5O_ALIGN (size, oh->alignment);
+
+ /*
+ * Create the new chunk without giving it a file address.
+ */
+ if (oh->nchunks >= oh->alloc_nchunks) {
+ oh->alloc_nchunks += H5O_NCHUNKS;
+ oh->chunk = H5MM_xrealloc (oh->chunk,
+ oh->alloc_nchunks * sizeof(H5O_chunk_t));
+ }
+ chunkno = oh->nchunks++;
+ oh->chunk[chunkno].dirty = TRUE;
+ oh->chunk[chunkno].addr = H5O_NO_ADDR;
+ oh->chunk[chunkno].size = size;
+ oh->chunk[chunkno].image = p = H5MM_xmalloc (size);
+
+ /*
+ * Make sure we have enough space for all possible new messages
+ * that could be generated below.
+ */
+ if (oh->nmesgs+3 > oh->alloc_nmesgs) {
+ oh->alloc_nmesgs += MAX (H5O_NMESGS, 3);
+ oh->mesg = H5MM_xrealloc (oh->mesg,
+ oh->alloc_nmesgs * sizeof(H5O_mesg_t));
+ }
+
+ /*
+ * Describe the messages of the new chunk.
+ */
+ if (found_null<0) {
+ found_null = i = oh->nmesgs++;
+ oh->mesg[i].type = H5O_NULL;
+ oh->mesg[i].dirty = TRUE;
+ oh->mesg[i].native = NULL;
+ oh->mesg[i].raw = oh->mesg[found_other].raw;
+ oh->mesg[i].raw_size = oh->mesg[found_other].raw_size;
+ oh->mesg[i].chunkno = oh->mesg[found_other].chunkno;
+
+ oh->mesg[found_other].dirty = TRUE;
+ oh->mesg[found_other].raw = p+4;
+ oh->mesg[found_other].chunkno = chunkno;
+ p += 4 + oh->mesg[found_other].raw_size;
+ size -= 4 + oh->mesg[found_other].raw_size;
+ }
+
+ idx = oh->nmesgs++;
+ oh->mesg[idx].type = H5O_NULL;
+ oh->mesg[idx].dirty = TRUE;
+ oh->mesg[idx].native = NULL;
+ oh->mesg[idx].raw = p+4;
+ oh->mesg[idx].raw_size = size-4;
+ oh->mesg[idx].chunkno = chunkno;
+
+ /*
+ * If the null message that will receive the continuation message
+ * is larger than the continuation message, then split it into
+ * two null messages.
+ */
+ if (oh->mesg[found_null].raw_size > cont_size) {
+ i = oh->nmesgs++;
+ oh->mesg[i].type = H5O_NULL;
+ oh->mesg[i].dirty = TRUE;
+ oh->mesg[i].native = NULL;
+ oh->mesg[i].raw = oh->mesg[found_null].raw + cont_size + 4;
+ oh->mesg[i].raw_size = oh->mesg[found_null].raw_size - (cont_size+4);
+ oh->mesg[i].chunkno = oh->mesg[found_null].chunkno;
+
+ oh->mesg[found_null].dirty = TRUE;
+ oh->mesg[found_null].raw_size = cont_size;
+ }
+
+ /*
+ * Initialize the continuation message.
+ */
+ oh->mesg[found_null].type = H5O_CONT;
+ oh->mesg[found_null].dirty = TRUE;
+ cont = H5MM_xcalloc (1, sizeof(H5O_cont_t));
+ cont->addr = H5O_NO_ADDR;
+ cont->size = 0;
+ cont->chunkno = chunkno;
+ oh->mesg[found_null].native = cont;
+
+
+ FUNC_LEAVE (idx);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_alloc
+ *
+ * Purpose: Allocate enough space in the object header for this message.
+ *
+ * Return: Success: Index of message
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5O_alloc (hdf5_file_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
+{
+ intn chunkno;
+ intn idx;
+ intn null_idx;
+
+ FUNC_ENTER (H5O_alloc, NULL, FAIL);
+
+ /* check args */
+ assert (oh);
+ assert (type);
+ assert (size>=0);
+ H5O_ALIGN (size, oh->alignment);
+
+ /* look for a null message which is large enough */
+ for (idx=0; idx<oh->nmesgs; idx++) {
+ if (H5O_NULL_ID==oh->mesg[idx].type->id &&
+ oh->mesg[idx].raw_size>=size) break;
+ }
+
+ /* if we didn't find one, then allocate more header space */
+ if (idx>=oh->nmesgs) {
+
+ /*
+ * Look for a chunk which hasn't had disk space allocated yet
+ * since we can just increase the size of that chunk.
+ */
+ for (chunkno=0; chunkno<oh->nchunks; chunkno++) {
+ if ((idx=H5O_alloc_extend_chunk (oh, chunkno, size))>=0) break;
+ H5ECLEAR;
+ }
+
+ /*
+ * Create a new chunk
+ */
+ if (idx<0) {
+ if ((idx=H5O_alloc_new_chunk (f, oh, size))<0) {
+ HRETURN_ERROR (H5E_OHDR, H5E_NOSPACE, FAIL);
+ }
+ }
+ }
+
+ /* do we need to split the null message? */
+ if (oh->mesg[idx].raw_size > size) {
+ assert (oh->mesg[idx].raw_size - size >= 4); /*room for type & size */
+
+ if (oh->nmesgs >= oh->alloc_nmesgs) {
+ oh->alloc_nmesgs += H5O_NMESGS;
+ oh->mesg = H5MM_xrealloc (oh->mesg,
+ oh->alloc_nmesgs * sizeof(H5O_mesg_t));
+ }
+
+ null_idx = oh->nmesgs++;
+ oh->mesg[null_idx].type = H5O_NULL;
+ oh->mesg[null_idx].dirty = TRUE;
+ oh->mesg[null_idx].native = NULL;
+ oh->mesg[null_idx].raw = oh->mesg[idx].raw + size + 4;
+ oh->mesg[null_idx].raw_size = oh->mesg[idx].raw_size - (size + 4);
+ oh->mesg[null_idx].chunkno = oh->mesg[idx].chunkno;
+ oh->mesg[idx].raw_size = size;
+ }
+
+ /* initialize the new message */
+ oh->mesg[idx].type = type;
+ oh->mesg[idx].dirty = TRUE;
+ oh->mesg[idx].native = NULL;
+
+ oh->dirty = TRUE;
+ FUNC_LEAVE (idx);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_debug
+ *
+ * Purpose: Prints debugging info about an object header.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_debug (hdf5_file_t *f, haddr_t addr, FILE *stream,
+ intn indent, intn fwidth)
+{
+ H5O_t *oh = NULL;
+ intn i, chunkno;
+ size_t mesg_total=0, chunk_total=0;
+ int *sequence;
+
+ FUNC_ENTER (H5O_debug, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (addr>=0);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
+ HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
+ }
+
+ /* debug */
+ fprintf (stream, "%*sObject Header...\n", indent, "");
+
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Dirty:",
+ (int)(oh->dirty));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Version:",
+ (int)(oh->version));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Alignment:",
+ (int)(oh->alignment));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Number of links:",
+ (int)(oh->nlink));
+ fprintf (stream, "%*s%-*s %d (%d)\n", indent, "", fwidth,
+ "Number of messages (allocated):",
+ (int)(oh->nmesgs), (int)(oh->alloc_nmesgs));
+ fprintf (stream, "%*s%-*s %d (%d)\n", indent, "", fwidth,
+ "Number of chunks (allocated):",
+ (int)(oh->nchunks), (int)(oh->alloc_nchunks));
+
+ /* debug each chunk */
+ for (i=chunk_total=0; i<oh->nchunks; i++) {
+ chunk_total += oh->chunk[i].size;
+ fprintf (stream, "%*sChunk %d...\n", indent, "", i);
+
+ fprintf (stream, "%*s%-*s %d\n", indent+3, "", MAX(0,fwidth-3),
+ "Dirty:",
+ (int)(oh->chunk[i].dirty));
+ fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
+ "Address:",
+ (unsigned long)(oh->chunk[i].addr));
+ if (0==i && oh->chunk[i].addr!=addr+H5O_SIZEOF_HDR(f)) {
+ fprintf (stream, "*** WRONG ADDRESS!\n");
+ }
+ fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
+ "Size in bytes:",
+ (unsigned long)(oh->chunk[i].size));
+ }
+
+ /* debug each message */
+ sequence = H5MM_xcalloc (NELMTS(message_type_g), sizeof(int));
+ for (i=mesg_total=0; i<oh->nmesgs; i++) {
+ mesg_total += 4 + oh->mesg[i].raw_size;
+ fprintf (stream, "%*sMessage %d...\n", indent, "", i);
+
+ /* check for bad message id */
+ if (oh->mesg[i].type->id<0 ||
+ oh->mesg[i].type->id>=NELMTS(message_type_g)) {
+ fprintf (stream, "*** BAD MESSAGE ID 0x%04x\n",
+ oh->mesg[i].type->id);
+ continue;
+ }
+
+ /* message name and size */
+ fprintf (stream, "%*s%-*s 0x%04x %s(%d)\n",
+ indent+3, "", MAX (0, fwidth-3),
+ "Message ID:",
+ (unsigned)(oh->mesg[i].type->id),
+ oh->mesg[i].type->name,
+ sequence[oh->mesg[i].type->id]++);
+ fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MAX (0, fwidth-3),
+ "Raw size in bytes:",
+ (unsigned long)(oh->mesg[i].raw_size));
+
+ fprintf (stream, "%*s%-*s %d\n", indent+3, "", MAX(0,fwidth-3),
+ "Chunk number:",
+ (int)(oh->mesg[i].chunkno));
+ chunkno = oh->mesg[i].chunkno;
+ if (chunkno<0 || chunkno>=oh->nchunks) {
+ fprintf (stream, "*** BAD CHUNK NUMBER\n");
+ }
+
+ /* check the size */
+ if ((oh->mesg[i].raw + oh->mesg[i].raw_size >
+ oh->chunk[chunkno].image + oh->chunk[chunkno].size) ||
+ (oh->mesg[i].raw < oh->chunk[chunkno].image)) {
+ fprintf (stream, "*** BAD MESSAGE RAW ADDRESS\n");
+ }
+
+ /* decode the message */
+ if (NULL==oh->mesg[i].native && oh->mesg[i].type->decode) {
+ oh->mesg[i].native = (oh->mesg[i].type->decode)(f, oh->mesg[i].raw);
+ }
+
+ /* print the message */
+ if (oh->mesg[i].type->debug) {
+ (oh->mesg[i].type->debug)(f, oh->mesg[i].native, stream, indent+3,
+ MAX(0, fwidth-3));
+ } else {
+ fprintf (stream, "%*sNo info for this message.\n", indent+3, "");
+ }
+ }
+ sequence = H5MM_xfree (sequence);
+
+ if (mesg_total != chunk_total) {
+ fprintf (stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
new file mode 100644
index 0000000..068a768
--- /dev/null
+++ b/src/H5Ocont.c
@@ -0,0 +1,164 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5Ocont.c
+ * Aug 6 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: The object header continuation message. This
+ * message is only generated and read from within
+ * the H5O package. Therefore, do not change
+ * any definitions in this file!
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <assert.h>
+#include "hdf5.h"
+#include "H5private.h"
+#include "H5MMprivate.h"
+#include "H5Oprivate.h"
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_cont_decode (hdf5_file_t *f, const uint8 *p);
+static herr_t H5O_cont_encode (hdf5_file_t *f, size_t size, uint8 *p,
+ const void *_mesg);
+static herr_t H5O_cont_debug (hdf5_file_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_CONT[1] = {{
+ H5O_CONT_ID, /*message id number */
+ "hdr continuation", /*message name for debugging */
+ H5O_cont_decode, /*decode message */
+ H5O_cont_encode, /*encode message */
+ NULL, /*no fast method */
+ NULL, /*no cache method */
+ NULL, /*no copy method */
+ NULL, /*no size method */
+ NULL, /*default free method */
+ H5O_cont_debug, /*debugging */
+}};
+
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_cont_decode
+ *
+ * Purpose: Decode the raw header continuation message.
+ *
+ * Return: Success: Ptr to the new native message
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_cont_decode (hdf5_file_t *f, const uint8 *p)
+{
+ H5O_cont_t *cont = NULL;
+
+ FUNC_ENTER (H5O_cont_decode, NULL, NULL);
+
+ cont = H5MM_xcalloc (1, sizeof(H5O_cont_t));
+ H5F_decode_offset (f, p, cont->addr);
+ H5F_decode_length (f, p, cont->size);
+
+ FUNC_LEAVE ((void*)cont);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_cont_encode
+ *
+ * Purpose: Encodes a continuation message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 7 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_cont_encode (hdf5_file_t *f, size_t size, uint8 *p, const void *_mesg)
+{
+ const H5O_cont_t *cont = (const H5O_cont_t *)_mesg;
+
+ FUNC_ENTER (H5O_cont_encode, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (size == H5F_SIZEOF_OFFSET(f) + H5F_SIZEOF_SIZE(f));
+ assert (p);
+ assert (cont);
+
+ /* encode */
+ H5F_encode_offset (f, p, cont->addr);
+ H5F_encode_length (f, p, cont->size);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_cont_debug
+ *
+ * Purpose: Prints debugging info.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_cont_debug (hdf5_file_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth)
+{
+ const H5O_cont_t *cont = (const H5O_cont_t *)_mesg;
+
+ FUNC_ENTER (H5O_cont_debug, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (cont);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Continuation address:",
+ (unsigned long)(cont->addr));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Continuation size in bytes:",
+ (unsigned long)(cont->size));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Points to chunk number:",
+ (int)(cont->chunkno));
+
+ FUNC_LEAVE (SUCCEED);
+}
diff --git a/src/H5Onull.c b/src/H5Onull.c
new file mode 100644
index 0000000..97e1ff7
--- /dev/null
+++ b/src/H5Onull.c
@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5Onull.c
+ * Aug 6 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: The null message.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "hdf5.h"
+#include "H5private.h"
+#include "H5Oprivate.h"
+
+/* This message derives from H5O */
+const H5O_class_t H5O_NULL[1] = {{
+ H5O_NULL_ID, /*message id number */
+ "null", /*message name for debugging */
+ NULL, /*no decode method */
+ NULL, /*no encode method */
+ NULL, /*no fast method */
+ NULL, /*no cache method */
+ NULL, /*no copy method */
+ NULL, /*no size method */
+ NULL, /*no free method */
+ NULL, /*no debug method */
+}};
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
new file mode 100644
index 0000000..dfaa5b5
--- /dev/null
+++ b/src/H5Oprivate.h
@@ -0,0 +1,127 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5Oprivate.h
+ * Aug 5 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: Object header private include file.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _H5Oprivate_H
+#define _H5Oprivate_H
+#include "H5Oproto.h"
+
+#include "H5Fprivate.h"
+#include "H5Gprivate.h"
+
+#define H5O_MIN_SIZE 64 /*min obj header data size */
+#define H5O_NMESGS 64 /*initial number of messages */
+#define H5O_NCHUNKS 64 /*initial number of chunks */
+#define H5O_NEW_MESG (-1) /*new message */
+#define H5O_NO_ADDR (-1) /*no disk address yet */
+
+#define H5O_VERSION 1
+#define H5O_ALIGNMENT 4
+#define H5O_ALIGN(X,A) ((X)=(A)*(((X)+(A)-1)/(A)))
+
+#define H5O_SIZEOF_HDR(F) \
+ (1 + /*version number */ \
+ 1 + /*alignment */ \
+ 2 + /*number of messages */ \
+ 4 + /*reference count */ \
+ 4) /*header data size */
+
+typedef struct H5O_class_t {
+ intn id; /*message type ID on disk */
+ const char *name; /*message name for debugging */
+ void *(*decode)(hdf5_file_t*,const uint8*); /*decode mesg */
+ herr_t (*encode)(hdf5_file_t*,size_t,uint8*,const void*);
+ void *(*fast)(const H5G_entry_t*, void*); /*get from stab ent */
+ hbool_t (*cache)(H5G_entry_t*,const void*); /*put into entry */
+ void *(*copy)(const void*,void*); /*copy native value */
+ size_t (*size)(hdf5_file_t*,const void*); /*size of raw value */
+ void *(*free)(void*); /*free native data struct */
+ herr_t (*debug)(hdf5_file_t*,const void*, FILE*, intn, intn);
+} H5O_class_t;
+
+typedef struct H5O_mesg_t {
+ const H5O_class_t *type; /*type of message */
+ hbool_t dirty; /*raw out of date wrt native */
+ void *native; /*native format message */
+ uint8 *raw; /*ptr to raw data */
+ size_t raw_size; /*size with alignment */
+ intn chunkno; /*chunk number for this mesg */
+} H5O_mesg_t;
+
+typedef struct H5O_chunk_t {
+ hbool_t dirty; /*dirty flag */
+ haddr_t addr; /*chunk file address */
+ size_t size; /*chunk size */
+ uint8 *image; /*image of file */
+} H5O_chunk_t;
+
+typedef struct H5O_t {
+ hbool_t dirty; /*out of data wrt disk */
+ intn version; /*version number */
+ intn alignment; /*message alignment */
+ intn nlink; /*link count */
+ intn nmesgs; /*number of messages */
+ intn alloc_nmesgs; /*number of message slots */
+ H5O_mesg_t *mesg; /*array of messages */
+ intn nchunks; /*number of chunks */
+ intn alloc_nchunks; /*chunks allocated */
+ H5O_chunk_t *chunk; /*array of chunks */
+} H5O_t;
+
+/*
+ * Null message.
+ */
+#define H5O_NULL_ID 0x0000
+extern const H5O_class_t H5O_NULL[1];
+
+/*
+ * Object header continuation message.
+ */
+#define H5O_CONT_ID 0x0010
+extern const H5O_class_t H5O_CONT[1];
+
+typedef struct H5O_cont_t {
+ haddr_t addr; /*address of continuation block */
+ size_t size; /*size of continuation block */
+
+ /* the following field(s) do not appear on disk */
+ intn chunkno; /*chunk this mesg refers to */
+} H5O_cont_t;
+
+/*
+ * Symbol table message.
+ */
+#define H5O_STAB_ID 0x0011
+extern const H5O_class_t H5O_STAB[1];
+
+typedef struct H5O_stab_t {
+ haddr_t btree; /*address of B-tree */
+ haddr_t heap; /*address of name heap */
+} H5O_stab_t;
+
+
+haddr_t H5O_new (hdf5_file_t *f, intn nlink, size_t size_hint);
+intn H5O_link (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent, intn adjust);
+void *H5O_read (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
+ const H5O_class_t *type, intn sequence, void *mesg);
+const void *H5O_peek (hdf5_file_t *f, haddr_t addr, const H5O_class_t *type,
+ intn sequence);
+intn H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
+ hbool_t *ent_modified, const H5O_class_t *type,
+ intn overwrite, const void *mesg);
+herr_t H5O_debug (hdf5_file_t *f, haddr_t addr, FILE *stream,
+ intn indent, intn fwidth);
+
+#endif
diff --git a/src/H5Oproto.h b/src/H5Oproto.h
new file mode 100644
index 0000000..df94835
--- /dev/null
+++ b/src/H5Oproto.h
@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5Oproto.h
+ * Aug 5 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: Object header public prototypes
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _H5Oproto_H
+#define _H5Oproto_H
+
+#if defined c_plusplus || defined __cplusplus
+extern "C"
+{
+#endif
+
+#if defined c_plusplus || defined __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
new file mode 100644
index 0000000..ec6dd61
--- /dev/null
+++ b/src/H5Ostab.c
@@ -0,0 +1,328 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5Ostab.c
+ * Aug 6 1997
+ * Robb Matzke <matzke@llnl.gov>
+ *
+ * Purpose: Symbol table messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <assert.h>
+
+#include "hdf5.h"
+
+#include "H5private.h"
+#include "H5Gprivate.h"
+#include "H5MMprivate.h"
+#include "H5Oprivate.h"
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_stab_decode (hdf5_file_t *f, const uint8 *p);
+static herr_t H5O_stab_encode (hdf5_file_t *f, size_t size, uint8 *p,
+ const void *_mesg);
+static void *H5O_stab_fast (const H5G_entry_t *ent, void *_mesg);
+static hbool_t H5O_stab_cache (H5G_entry_t *ent, const void *_mesg);
+static void *H5O_stab_copy (const void *_mesg, void *_dest);
+static size_t H5O_stab_size (hdf5_file_t *f, const void *_mesg);
+static herr_t H5O_stab_debug (hdf5_file_t *f, const void *_mesg,
+ FILE *stream, intn indent, intn fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_STAB[1] = {{
+ H5O_STAB_ID, /*message id number */
+ "stab", /*message name for debugging */
+ H5O_stab_decode, /*decode message */
+ H5O_stab_encode, /*encode message */
+ H5O_stab_fast, /*get message from stab entry */
+ H5O_stab_cache, /*put message into stab entry */
+ H5O_stab_copy, /*copy the native value */
+ H5O_stab_size, /*size of symbol table entry */
+ NULL, /*default free method */
+ H5O_stab_debug, /*debug the message */
+}};
+
+/* Is the interface initialized? */
+static intn interface_initialize_g = FALSE;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_decode
+ *
+ * Purpose: Decode a symbol table message and return a pointer to
+ * a new one created with malloc().
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_stab_decode (hdf5_file_t *f, const uint8 *p)
+{
+ H5O_stab_t *stab;
+
+ FUNC_ENTER (H5O_stab_decode, NULL, NULL);
+
+ /* check args */
+ assert (f);
+ assert (p);
+
+ /* decode */
+ stab = H5MM_xcalloc (1, sizeof(H5O_stab_t));
+ H5F_decode_offset (f, p, stab->btree);
+ H5F_decode_offset (f, p, stab->heap);
+
+ FUNC_LEAVE (stab);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_encode
+ *
+ * Purpose: Encodes a symbol table entry.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_stab_encode (hdf5_file_t *f, size_t size, uint8 *p, const void *_mesg)
+{
+ const H5O_stab_t *stab = (const H5O_stab_t *)_mesg;
+
+ FUNC_ENTER (H5O_stab_encode, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (size == 2 * H5F_SIZEOF_OFFSET(f));
+ assert (p);
+ assert (stab);
+
+ /* encode */
+ H5F_encode_offset (f, p, stab->btree);
+ H5F_encode_offset (f, p, stab->heap);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_fast
+ *
+ * Purpose: Initializes a new message struct with info from a symbol
+ * table entry.
+ *
+ * Return: Success: Ptr to message struct, allocated if none
+ * supplied.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_stab_fast (const H5G_entry_t *ent, void *_mesg)
+{
+ H5O_stab_t *stab = (H5O_stab_t *)_mesg;
+
+ FUNC_ENTER (H5O_stab_fast, NULL, NULL);
+
+ /* check args */
+ assert (ent);
+
+ if (H5G_CACHED_STAB==ent->type) {
+ if (!stab) stab = H5MM_xcalloc (1, sizeof(H5O_stab_t));
+ stab->btree = ent->cache.stab.btree;
+ stab->heap = ent->cache.stab.heap;
+ } else {
+ stab = NULL;
+ }
+
+ FUNC_LEAVE (stab);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_cache
+ *
+ * Purpose: Copies a message into the cache portion of a symbol table
+ * entry.
+ *
+ * Return: Success: TRUE if modified.
+ * FALSE if not modified.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+H5O_stab_cache (H5G_entry_t *ent, const void *_mesg)
+{
+ const H5O_stab_t *stab = (const H5O_stab_t *)_mesg;
+ hbool_t modified = FALSE;
+
+ FUNC_ENTER (H5O_stab_cache, NULL, FAIL);
+
+ /* check args */
+ assert (ent);
+ assert (stab);
+
+ /* cache */
+ if (H5G_CACHED_STAB != ent->type) {
+ modified = TRUE;
+ ent->type = H5G_CACHED_STAB;
+ }
+
+ if (ent->cache.stab.btree != stab->btree) {
+ modified = TRUE;
+ ent->cache.stab.btree = stab->btree;
+ }
+
+ if (ent->cache.stab.heap != stab->heap) {
+ modified = TRUE;
+ ent->cache.stab.heap = stab->heap;
+ }
+
+ FUNC_LEAVE (modified);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_stab_copy (const void *_mesg, void *_dest)
+{
+ const H5O_stab_t *stab = (const H5O_stab_t *)_mesg;
+ H5O_stab_t *dest = (H5O_stab_t *)_dest;
+
+ FUNC_ENTER (H5O_stab_copy, NULL, NULL);
+
+ /* check args */
+ assert (stab);
+ if (!dest) dest = H5MM_xcalloc (1, sizeof(H5O_stab_t));
+
+ /* copy */
+ *dest = *stab;
+
+ FUNC_LEAVE ((void*)dest);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_stab_size (hdf5_file_t *f, const void *_mesg)
+{
+ FUNC_ENTER (H5O_stab_size, NULL, FAIL);
+ FUNC_LEAVE (2 * H5F_SIZEOF_OFFSET(f));
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_debug
+ *
+ * Purpose: Prints debugging info for a symbol table message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_stab_debug (hdf5_file_t *f, const void *_mesg, FILE *stream,
+ intn indent, intn fwidth)
+{
+ const H5O_stab_t *stab = (const H5O_stab_t *)_mesg;
+
+ FUNC_ENTER (H5O_stab_debug, NULL, FAIL);
+
+ /* check args */
+ assert (f);
+ assert (stab);
+ assert (stream);
+ assert (indent>=0);
+ assert (fwidth>=0);
+
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "B-tree address:",
+ (unsigned long)(stab->btree));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Name heap address:",
+ (unsigned long)(stab->heap));
+
+ FUNC_LEAVE (SUCCEED);
+}
+
diff --git a/src/Makefile b/src/Makefile
index 022f392..94dcd67 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -28,7 +28,7 @@ CFLAGS = -c $(MACHINE) $(DEFS)
INCL = hdf5.h
OBJ = H5.o H5E.o H5A.o H5F.o H5C.o H5M.o H5AC.o H5B.o H5MM.o H5MF.o H5T.o \
- H5Gnode.o H5H.o H5G.o H5P.o H5D.o
+ H5Gnode.o H5H.o H5G.o H5P.o H5D.o H5O.o H5Onull.o H5Ocont.o H5Ostab.o
$(TARGET): $(OBJ)
$(AR) $(ARFLAGS) $(TARGET) $(OBJ)
@@ -99,3 +99,15 @@ H5P.o: H5P.c $(INCL) H5Pprivate.h H5Pproto.h
H5D.o: H5D.c $(INCL) H5Dprivate.h H5Dproto.h
$(CC) $(CFLAGS) H5D.c
+
+H5O.o: H5O.c $(INCL) H5Oprivate.h H5Oproto.h
+ $(CC) $(CFLAGS) H5O.c
+
+H5Onull.o: H5Onull.c $(INCL) H5Oprivate.h H5Oproto.h
+ $(CC) $(CFLAGS) H5Onull.c
+
+H5Ocont.o: H5Ocont.c $(INCL) H5Oprivate.h H5Oproto.h
+ $(CC) $(CFLAGS) H5Ocont.c
+
+H5Ostab.o: H5Ostab.c $(INCL) H5Oprivate.h H5Oproto.h
+ $(CC) $(CFLAGS) H5Ostab.c
diff --git a/src/debug.c b/src/debug.c
index f061d4c..d07b2cb 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -6,7 +6,7 @@
*
* Created: debug.c
* Jul 18 1997
- * Robb Matzke <robb@maya.nuance.com>
+ * Robb Matzke <matzke@llnl.gov>
*
* Purpose: Debugs an existing HDF5 file at a low level.
*
@@ -21,6 +21,7 @@
#include "H5Fprivate.h"
#include "H5Gprivate.h"
#include "H5Hprivate.h"
+#include "H5Oprivate.h"
#define INDENT 3
#define VCOL 50
@@ -36,7 +37,7 @@
* Failure: exit (non-zero)
*
* Programmer: Robb Matzke
- * robb@maya.nuance.com
+ * matzke@llnl.gov
* Jul 18 1997
*
* Modifications:
@@ -51,6 +52,7 @@ main (int argc, char *argv[])
haddr_t addr = 0;
uint8 sig[16];
intn i;
+ herr_t status = SUCCEED;
/*
* Parse command arguments.
@@ -85,19 +87,19 @@ main (int argc, char *argv[])
/*
* Debug the boot block.
*/
- H5F_debug (f, 0, stdout, 0, VCOL);
+ status = H5F_debug (f, 0, stdout, 0, VCOL);
} else if (!memcmp (sig, H5H_MAGIC, H5H_SIZEOF_MAGIC)) {
/*
* Debug a heap.
*/
- H5H_debug (f, addr, stdout, 0, VCOL);
+ status = H5H_debug (f, addr, stdout, 0, VCOL);
} else if (!memcmp (sig, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC)) {
/*
* Debug a symbol table node.
*/
- H5G_node_debug (f, addr, stdout, 0, VCOL);
+ status = H5G_node_debug (f, addr, stdout, 0, VCOL);
} else if (!memcmp (sig, H5B_MAGIC, H5B_SIZEOF_MAGIC)) {
/*
@@ -108,13 +110,20 @@ main (int argc, char *argv[])
H5B_subid_t subtype = sig[H5B_SIZEOF_MAGIC];
switch (subtype) {
case H5B_SUBTYPE_SNODE:
- H5G_node_debug (f, addr, stdout, 0, VCOL);
+ status = H5G_node_debug (f, addr, stdout, 0, VCOL);
break;
default:
fprintf (stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype));
exit (4);
}
+
+ } else if (sig[0]==H5O_VERSION && sig[1]==H5O_ALIGNMENT) {
+ /*
+ * This could be an object header. Since they don't have a signature
+ * it's a somewhat "ify" detection.
+ */
+ status = H5O_debug (f, addr, stdout, 0, VCOL);
} else {
/*
@@ -137,6 +146,11 @@ main (int argc, char *argv[])
exit (4);
}
+ if (status<0) {
+ fprintf (stderr, "An error occurred\n");
+ exit (5);
+ }
+
H5Fclose (fid);
exit (0);
}
diff --git a/src/hdf5gen.h b/src/hdf5gen.h
index 39e3d05..628f5c3 100644
--- a/src/hdf5gen.h
+++ b/src/hdf5gen.h
@@ -15,6 +15,7 @@
/*
* This file contains general macros used throughout HDF5 library & interfaces
*/
+#include "hdf5pabl.h"
#ifndef HDF5GEN_H
#define HDF5GEN_H
@@ -36,6 +37,11 @@
# define TRUE (!FALSE)
#endif
+/* number of members in an array */
+#ifndef NELMTS
+# define NELMTS(X) (sizeof(X)/sizeof(X[0]))
+#endif
+
/*-------------------------------------------------------------------------
* Purpose: Register function entry for library initialization and code
* profiling.
@@ -77,9 +83,9 @@
*/
#define FUNC_ENTER(func_name,interface_init_func,err) \
CONSTR (FUNC, #func_name); \
- /* int pablo_func_id = ID_ ## func_name; */ \
+ PABLO_SAVE (ID_ ## func_name); \
\
- PABLO_TRACE_ON (PABLO_MASK, ID_ ## func_name); \
+ PABLO_TRACE_ON (PABLO_MASK, pablo_func_id); \
\
if (!library_initialize_g) { \
library_initialize_g = TRUE; \
@@ -120,10 +126,7 @@
*
*-------------------------------------------------------------------------
*/
-#define FUNC_LEAVE(return_value) { \
- PABLO_TRACE_OFF (PABLO_MASK, pablo_func_id); \
- return (return_value); \
-}
+#define FUNC_LEAVE(return_value) HRETURN(return_value)
#endif /* HDF5GEN_H */
diff --git a/src/hdf5meta.h b/src/hdf5meta.h
index 025b4e6..2716537 100644
--- a/src/hdf5meta.h
+++ b/src/hdf5meta.h
@@ -123,13 +123,13 @@
#else /* HDF5_HAVE_NATIVE_INT64 */
#error "Define int64 on platforms which don't support it"
#endif /* HDF5_HAVE_NATIVE_INT64 */
-# define INT16DECODE(p, i) { (i) = (int16)(*(int16 *)(p)); (p)+=2; }
-# define UINT16DECODE(p, i) { (i) = (uint16)(*(uint16 *)(p)); (p)+=2; }
-# define INT32DECODE(p, i) { (i) = (int32)(*(int32 *)(p)); (p)+=4; }
-# define UINT32DECODE(p, i) { (i) = (uint32)(*(uint32 *)(p)); (p)+=4; }
+# define INT16DECODE(p, i) { (i) = (int16)(*(const int16 *)(p)); (p)+=2; }
+# define UINT16DECODE(p, i) { (i) = (uint16)(*(const uint16 *)(p)); (p)+=2; }
+# define INT32DECODE(p, i) { (i) = (int32)(*(const int32 *)(p)); (p)+=4; }
+# define UINT32DECODE(p, i) { (i) = (uint32)(*(const uint32 *)(p)); (p)+=4; }
#ifdef HDF5_HAVE_NATIVE_INT64
-# define INT64DECODE(p, i) { (i) = (int64)(*(int64 *)(p)); (p)+=8; }
-# define UINT64DECODE(p, i) { (i) = (uint64)(*(uint64 *)(p)); (p)+=8; }
+# define INT64DECODE(p, i) { (i) = (int64)(*(const int64 *)(p)); (p)+=8; }
+# define UINT64DECODE(p, i) { (i) = (uint64)(*(const uint64 *)(p)); (p)+=8; }
#else /* HDF5_HAVE_NATIVE_INT64 */
#error "Define int64 on platforms which don't support it"
#endif /* HDF5_HAVE_NATIVE_INT64 */
diff --git a/src/hdf5pabl.h b/src/hdf5pabl.h
index 0df5913..008a265 100644
--- a/src/hdf5pabl.h
+++ b/src/hdf5pabl.h
@@ -20,11 +20,13 @@
#define HDF5PABL_H
#ifdef HAVE_PABLO
+#define PABLO_SAVE(func_id) int pablo_func_id = func_id
#define PABLO_TRACE_ON(m, f) TRACE_ON(m,f)
#define PABLO_TRACE_OFF(m, f) TRACE_OFF(m,f)
#else /* no Pablo tracing enabled */
-#define PABLO_TRACE_ON(m, f)
-#define PABLO_TRACE_OFF(m, f)
+#define PABLO_SAVE(func_id) /*void*/
+#define PABLO_TRACE_ON(m, f) /*void*/
+#define PABLO_TRACE_OFF(m, f) /*void*/
#endif /* HAVE_PABLO */
#endif /* HDF5PABL_H */