diff options
author | Albert Cheng <acheng@hdfgroup.org> | 1998-02-09 19:37:40 (GMT) |
---|---|---|
committer | Albert Cheng <acheng@hdfgroup.org> | 1998-02-09 19:37:40 (GMT) |
commit | 7e8e3eec42254a6988b2739b621b1412963d590c (patch) | |
tree | cc7d01adda3675d67d35c8cb2edaf7a1dc469f40 /src/H5O.c | |
parent | 35e7a062e26c1a65e571202a6fda0b475e42da00 (diff) | |
download | hdf5-7e8e3eec42254a6988b2739b621b1412963d590c.zip hdf5-7e8e3eec42254a6988b2739b621b1412963d590c.tar.gz hdf5-7e8e3eec42254a6988b2739b621b1412963d590c.tar.bz2 |
[svn-r230] Changes were actually made by Robb. I am commiting them for him
while he is visiting LLNL. I changed the default creation template
offset and length to 4. Will fix the problem later.
Changes since 19980205
----------------------
./src/H5H.c
./src/H5Hprivate.h
./src/H5O.c
./src/H5Ocont.c
./src/H5Odtype.c
./src/H5Oefl.c
./src/H5Olayout.c
./src/H5Oname.c
./src/H5Onull.c
./src/H5Oprivate.h
./src/H5Odspace.c
./src/H5Ostab.c
./src/debug.c
./html/H5.format.html
Added an extra 4-byte field after the heap magic number for
alignment on the DEC alpha. Changed object header message
alignment to 8-bytes.
./src/H5F.c
./src/H5Farray.c
./src/H5Ffamily.c
./src/H5Fistore.c
./src/H5Flow.c
./src/H5Fprivate.h
./src/H5Fsec2.c
./src/H5Fstdio.c
./src/H5Gnode.c
./src/H5O.c
./src/H5Odtype.c
./src/H5P.c
./src/H5Pprivate.h
./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
./src/H5Tpublic.h
./src/H5V.c
./src/H5detect.c
./test/cmpd_dset.c
./test/dsets.c
./test/dtypes.c
./test/extend.c
./test/hyperslab.c
./test/istore.c
./test/th5p.c
./test/theap.c
Fixed a few irix64 warnings regarding size_t vs. int,
variables set but not used, printf formats
./config/irix64
Added `-woff 1196' to get rid of errors about __vfork() being
implicitly defined in a system header file.
./src/H5B.c
Fixed a stack alignment problem.
Diffstat (limited to 'src/H5O.c')
-rw-r--r-- | src/H5O.c | 1679 |
1 files changed, 852 insertions, 827 deletions
@@ -1,16 +1,16 @@ /*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. - * All rights reserved. + * Copyright (C) 1997 National Center for Supercomputing Applications. + * All rights reserved. * *------------------------------------------------------------------------- * - * Created: H5O.c - * Aug 5 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: H5O.c + * Aug 5 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Object header virtual functions. + * Purpose: Object header virtual functions. * - * Modifications: + * Modifications: * *------------------------------------------------------------------------- */ @@ -22,55 +22,52 @@ #include <H5MMprivate.h> #include <H5Oprivate.h> -#define PABLO_MASK H5O_mask +#define PABLO_MASK H5O_mask /* PRIVATE PROTOTYPES */ -static herr_t H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, - H5O_t *oh); -static H5O_t *H5O_load(H5F_t *f, const haddr_t *addr, const void *_udata1, - void *_udata2); -static intn H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, - const H5O_class_t **type_p, intn sequence); -static intn H5O_alloc(H5F_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(H5F_t *f, H5O_t *oh, size_t size); +static herr_t H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, + H5O_t *oh); +static H5O_t *H5O_load(H5F_t *f, const haddr_t *addr, const void *_udata1, + void *_udata2); +static intn H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, + const H5O_class_t **type_p, intn sequence); +static intn H5O_alloc(H5F_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(H5F_t *f, H5O_t *oh, size_t size); /* H5O inherits cache-like properties from H5AC */ -static const H5AC_class_t H5AC_OHDR[1] = -{ - { - H5AC_OHDR_ID, - (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5O_load, - (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5O_flush, - }}; +static const H5AC_class_t H5AC_OHDR[1] = {{ + H5AC_OHDR_ID, + (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5O_load, + (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5O_flush, +}}; /* Interface initialization */ -static intn interface_initialize_g = FALSE; -#define INTERFACE_INIT H5O_init_interface -static herr_t H5O_init_interface(void); +static intn interface_initialize_g = FALSE; +#define INTERFACE_INIT H5O_init_interface +static herr_t H5O_init_interface(void); /* ID to type mapping */ -static const H5O_class_t *const message_type_g[] = -{ - H5O_NULL, /*0x0000 Null */ - H5O_SDSPACE, /*0x0001 Simple Dimensionality */ - NULL, /*0x0002 Data space (fiber bundle?) */ - H5O_DTYPE, /*0x0003 Data Type */ - NULL, /*0x0004 Not assigned */ - NULL, /*0x0005 Not assigned */ - NULL, /*0x0006 Data storage -- compact object */ - NULL, /*0x0007 Data storage -- external object */ - H5O_LAYOUT, /*0x0008 Data Layout */ - H5O_EFL, /*0x0009 External File List */ - NULL, /*0x000A Not assigned */ - NULL, /*0x000B Data storage -- compressed object */ - NULL, /*0x000C Attribute list */ - H5O_NAME, /*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 */ +static const H5O_class_t *const message_type_g[] = { + H5O_NULL, /*0x0000 Null */ + H5O_SDSPACE, /*0x0001 Simple Dimensionality */ + NULL, /*0x0002 Data space (fiber bundle?) */ + H5O_DTYPE, /*0x0003 Data Type */ + NULL, /*0x0004 Not assigned */ + NULL, /*0x0005 Not assigned */ + NULL, /*0x0006 Data storage -- compact object */ + NULL, /*0x0007 Data storage -- external object */ + H5O_LAYOUT, /*0x0008 Data Layout */ + H5O_EFL, /*0x0009 External File List */ + NULL, /*0x000A Not assigned */ + NULL, /*0x000B Data storage -- compressed object */ + NULL, /*0x000C Attribute list */ + H5O_NAME, /*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 */ }; /* @@ -78,21 +75,21 @@ static const H5O_class_t *const message_type_g[] = * (H5G_type_t) that are called to retrieve constant messages cached in the * symbol table entry. */ -static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *, - const H5O_class_t *, - void *); +static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *, + const H5O_class_t *, + void *); /*------------------------------------------------------------------------- - * Function: H5O_init_interface + * Function: H5O_init_interface * - * Purpose: Initialize the H5O interface. + * Purpose: Initialize the H5O interface. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, January 6, 1998 + * Programmer: Robb Matzke + * Tuesday, January 6, 1998 * * Modifications: * @@ -112,33 +109,33 @@ H5O_init_interface(void) } /*------------------------------------------------------------------------- - * Function: H5O_create + * Function: H5O_create * - * Purpose: Creates a new object header, sets the link count - * to 0, and caches the header. The object header is opened for - * write access and should eventually be closed by calling - * H5O_close(). + * Purpose: Creates a new object header, sets the link count + * to 0, and caches the header. The object header is opened for + * write access and should eventually be closed by calling + * H5O_close(). * - * Return: Success: SUCCEED, the ENT argument contains - * information about the object header, - * including its address. + * Return: Success: SUCCEED, the ENT argument contains + * information about the object header, + * including its address. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 5 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 5 1997 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent /*out */ ) +H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) { - size_t size; /*total size of object header */ - H5O_t *oh = NULL; - haddr_t tmp_addr; + size_t size; /*total size of object header */ + H5O_t *oh = NULL; + haddr_t tmp_addr; FUNC_ENTER(H5O_create, FAIL); @@ -146,21 +143,19 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent /*out */ ) assert(f); assert(ent); HDmemset(ent, 0, sizeof(H5G_entry_t)); - if (size_hint < H5O_MIN_SIZE) - size_hint = H5O_MIN_SIZE; - H5O_ALIGN(size_hint, H5O_ALIGNMENT); + size_hint = H5O_ALIGN (MAX (H5O_MIN_SIZE, size_hint)); /* allocate disk space for header and first chunk */ size = H5O_SIZEOF_HDR(f) + size_hint; - if (H5MF_alloc(f, H5MF_META, size, &(ent->header) /*out */ ) < 0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate file space for object header hdr"); + if (H5MF_alloc(f, H5MF_META, size, &(ent->header)/*out*/) < 0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate file space for object header hdr"); } + /* allocate the object header and fill in header fields */ oh = H5MM_xcalloc(1, sizeof(H5O_t)); oh->dirty = TRUE; oh->version = H5O_VERSION; - oh->alignment = H5O_ALIGNMENT; oh->nlink = 0; /* create the chunk list and initialize the first chunk */ @@ -183,36 +178,37 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent /*out */ ) 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].raw = oh->chunk[0].image + H5O_SIZEOF_MSGHDR(f); + oh->mesg[0].raw_size = size_hint - H5O_SIZEOF_MSGHDR(f); oh->mesg[0].chunkno = 0; /* cache it */ if (H5AC_set(f, H5AC_OHDR, &(ent->header), oh) < 0) { - H5MM_xfree(oh); - HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "unable to cache object header"); + H5MM_xfree(oh); + HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, + "unable to cache object header"); } + /* open it */ if (H5O_open(f, ent) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, - "unable to open object header"); + HRETURN_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, + "unable to open object header"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5O_open + * Function: H5O_open * - * Purpose: Opens an object header which is described by the symbol table - * entry OBJ_ENT. + * Purpose: Opens an object header which is described by the symbol table + * entry OBJ_ENT. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, January 5, 1998 + * Programmer: Robb Matzke + * Monday, January 5, 1998 * * Modifications: * @@ -240,16 +236,16 @@ H5O_open(H5F_t *f, H5G_entry_t *obj_ent) } /*------------------------------------------------------------------------- - * Function: H5O_close + * Function: H5O_close * - * Purpose: Closes an object header that was previously open. + * Purpose: Closes an object header that was previously open. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Monday, January 5, 1998 + * Programmer: Robb Matzke + * Monday, January 5, 1998 * * Modifications: * @@ -273,7 +269,7 @@ H5O_close(H5G_entry_t *obj_ent) * pending then close the file. */ if (0 == obj_ent->file->nopen && obj_ent->file->close_pending) { - H5F_close(obj_ent->file); + H5F_close(obj_ent->file); } #ifdef H5O_DEBUG fprintf(stderr, "<"); @@ -285,41 +281,41 @@ H5O_close(H5G_entry_t *obj_ent) } /*------------------------------------------------------------------------- - * Function: H5O_load + * Function: H5O_load * - * Purpose: Loads an object header from disk. + * Purpose: Loads an object header from disk. * - * Return: Success: Pointer to the new object header. + * Return: Success: Pointer to the new object header. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 5 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 5 1997 * * Modifications: * - * Robb Matzke, 30 Aug 1997 - * Plugged memory leaks that occur during error handling. + * Robb Matzke, 30 Aug 1997 + * Plugged memory leaks that occur during error handling. * - * Robb Matzke, 7 Jan 1998 - * Able to distinguish between constant and variable messages. + * Robb Matzke, 7 Jan 1998 + * Able to distinguish between constant and variable messages. * *------------------------------------------------------------------------- */ -static H5O_t * +static H5O_t * H5O_load(H5F_t *f, const haddr_t *addr, const void *_udata1, void *_udata2) { - H5O_t *oh = NULL; - H5O_t *ret_value = (void *) 1; /*kludge for HGOTO_ERROR */ - 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; - hbool_t constant; /*is message a constant mesg? */ + H5O_t *oh = NULL; + H5O_t *ret_value = 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; + hbool_t constant; /*is message a constant mesg? */ FUNC_ENTER(H5O_load, NULL); @@ -335,23 +331,21 @@ H5O_load(H5F_t *f, const haddr_t *addr, const void *_udata1, void *_udata2) /* read fixed-lenth part of object header */ hdr_size = H5O_SIZEOF_HDR(f); if (H5F_block_read(f, addr, hdr_size, buf) < 0) { - HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, - "unable to read object header"); + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, + "unable to read object header"); } p = buf; /* decode version */ oh->version = *p++; if (H5O_VERSION != oh->version) { - HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, - "bad object header version number"); - } - /* decode alignment */ - oh->alignment = *p++; - if (4 != oh->alignment) { - HGOTO_ERROR(H5E_OHDR, H5E_ALIGNMENT, NULL, - "unsupported object header alignment"); + HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, + "bad object header version number"); } + + /* reserved */ + p++; + /* decode number of messages */ UINT16DECODE(p, nmesgs); @@ -370,126 +364,131 @@ H5O_load(H5F_t *f, const haddr_t *addr, const void *_udata1, void *_udata2) /* read each chunk from disk */ while (H5F_addr_defined(&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) { - HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, - "unable to read object header data"); - } - /* 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); - - /* - * The message ID field actually contains some bits near the - * high-order end that are not part of the ID. - */ - constant = (id & H5O_FLAG_CONSTANT) ? TRUE : FALSE; - id &= ~H5O_FLAG_BITS; - - if (id >= NELMTS(message_type_g) || NULL == message_type_g[id]) { - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, - "corrupt object header"); - } - if (p + mesg_size > oh->chunk[chunkno].image + chunk_size) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, - "corrupt object header"); - } - if (H5O_NULL_ID == id && oh->nmesgs > 0 && - H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && - oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { - /* combine adjacent null messages */ - mesgno = oh->nmesgs - 1; - oh->mesg[mesgno].raw_size += 4 + mesg_size; - } else { - /* new message */ - if (oh->nmesgs >= nmesgs) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, - "corrupt object header"); - } - mesgno = oh->nmesgs++; - oh->mesg[mesgno].type = message_type_g[id]; - oh->mesg[mesgno].dirty = FALSE; - oh->mesg[mesgno].constant = constant; - 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 (H5F_addr_undef(&chunk_addr); - !H5F_addr_defined(&chunk_addr) && curmesg < oh->nmesgs; - curmesg++) { - if (H5O_CONT_ID == oh->mesg[curmesg].type->id) { - uint8 *p2 = oh->mesg[curmesg].raw; - cont = (H5O_CONT->decode) (f, oh->mesg[curmesg].raw_size, p2); - oh->mesg[curmesg].native = cont; - chunk_addr = cont->addr; - chunk_size = cont->size; - cont->chunkno = oh->nchunks; /*the next chunk to allocate */ - } - } + /* 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) { + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, + "unable to read object header data"); + } + + /* 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); + assert (mesg_size==H5O_ALIGN (mesg_size)); + p += 4; /*reserved*/ + + /* + * The message ID field actually contains some bits near the + * high-order end that are not part of the ID. + */ + constant = (id & H5O_FLAG_CONSTANT) ? TRUE : FALSE; + id &= ~H5O_FLAG_BITS; + + if (id >= NELMTS(message_type_g) || NULL == message_type_g[id]) { + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, + "corrupt object header"); + } + if (p + mesg_size > oh->chunk[chunkno].image + chunk_size) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, + "corrupt object header"); + } + if (H5O_NULL_ID == id && oh->nmesgs > 0 && + H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id && + oh->mesg[oh->nmesgs - 1].chunkno == chunkno) { + /* combine adjacent null messages */ + mesgno = oh->nmesgs - 1; + oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR(f) + mesg_size; + } else { + /* new message */ + if (oh->nmesgs >= nmesgs) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, + "corrupt object header"); + } + mesgno = oh->nmesgs++; + oh->mesg[mesgno].type = message_type_g[id]; + oh->mesg[mesgno].dirty = FALSE; + oh->mesg[mesgno].constant = constant; + 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 (H5F_addr_undef(&chunk_addr); + !H5F_addr_defined(&chunk_addr) && curmesg < oh->nmesgs; + curmesg++) { + if (H5O_CONT_ID == oh->mesg[curmesg].type->id) { + uint8 *p2 = oh->mesg[curmesg].raw; + cont = (H5O_CONT->decode) (f, oh->mesg[curmesg].raw_size, p2); + oh->mesg[curmesg].native = cont; + chunk_addr = cont->addr; + chunk_size = cont->size; + cont->chunkno = oh->nchunks; /*the next chunk to allocate */ + } + } } + ret_value = oh; done: if (!ret_value && oh) { - /* - * Free resources. - */ - int i; - for (i = 0; i < oh->nchunks; i++) { - oh->chunk[i].image = H5MM_xfree(oh->chunk[i].image); - } - oh->chunk = H5MM_xfree(oh->chunk); - oh->mesg = H5MM_xfree(oh->mesg); - oh = H5MM_xfree(oh); + /* + * Free resources. + */ + int i; + for (i = 0; i < oh->nchunks; i++) { + oh->chunk[i].image = H5MM_xfree(oh->chunk[i].image); + } + oh->chunk = H5MM_xfree(oh->chunk); + oh->mesg = H5MM_xfree(oh->mesg); + oh = H5MM_xfree(oh); } - FUNC_LEAVE(oh); + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_flush + * Function: H5O_flush * - * Purpose: Flushes (and destroys) an object header. + * Purpose: Flushes (and destroys) an object header. * - * Return: Success: SUCCESS + * Return: Success: SUCCESS * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 5 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 5 1997 * * Modifications: * - * Robb Matzke, 7 Jan 1998 - * Handles constant vs non-constant messages. + * Robb Matzke, 7 Jan 1998 + * Handles constant vs non-constant messages. * *------------------------------------------------------------------------- */ static herr_t H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5O_t *oh) { - uint8 buf[16], *p; - intn i, id; - H5O_cont_t *cont = NULL; + uint8 buf[16], *p; + intn i, id; + H5O_cont_t *cont = NULL; FUNC_ENTER(H5O_flush, FAIL); @@ -500,125 +499,134 @@ H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5O_t *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, - "unable to write object header hdr to disk"); - } - /* encode messages */ - for (i = 0; i < oh->nmesgs; i++) { - if (oh->mesg[i].dirty) { - p = oh->mesg[i].raw - 4; - - /* The message id has some flags in the high-order bits. */ - id = oh->mesg[i].type->id; - id |= oh->mesg[i].constant ? H5O_FLAG_CONSTANT : 0; - UINT16ENCODE(p, 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 && - !H5F_addr_defined(&(((H5O_cont_t *) - (oh->mesg[i].native))->addr))) { - cont = (H5O_cont_t *) (oh->mesg[i].native); - assert(cont->chunkno >= 0); - assert(cont->chunkno < oh->nchunks); - assert(!H5F_addr_defined(&(oh->chunk[cont->chunkno].addr))); - cont->size = oh->chunk[cont->chunkno].size; - if (H5MF_alloc(f, H5MF_META, cont->size, - &(cont->addr) /*out */ ) < 0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate space for object " - "header data"); - } - 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, - "unable to encode object header message"); - } - } - 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(H5F_addr_defined(&(oh->chunk[i].addr))); - 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, - "unable to write object header data to disk"); - } - oh->chunk[i].dirty = FALSE; - } - } - oh->dirty = FALSE; + p = buf; + + /* encode version */ + *p++ = oh->version; + + /* reserved */ + *p++ = 0; + + /* 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, + "unable to write object header hdr to disk"); + } + + /* encode messages */ + for (i = 0; i < oh->nmesgs; i++) { + if (oh->mesg[i].dirty) { + p = oh->mesg[i].raw - H5O_SIZEOF_MSGHDR(f); + + /* The message id has some flags in the high-order bits. */ + id = oh->mesg[i].type->id; + id |= oh->mesg[i].constant ? H5O_FLAG_CONSTANT : 0; + UINT16ENCODE(p, id); + UINT16ENCODE(p, oh->mesg[i].raw_size); + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + + 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 && + !H5F_addr_defined(&(((H5O_cont_t *) + (oh->mesg[i].native))->addr))) { + cont = (H5O_cont_t *) (oh->mesg[i].native); + assert(cont->chunkno >= 0); + assert(cont->chunkno < oh->nchunks); + assert(!H5F_addr_defined(&(oh->chunk[cont->chunkno].addr))); + cont->size = oh->chunk[cont->chunkno].size; + if (H5MF_alloc(f, H5MF_META, cont->size, + &(cont->addr)/*out*/) < 0) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate space for object " + "header data"); + } + 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_size == + H5O_ALIGN (oh->mesg[i].raw_size)); + 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, + "unable to encode object header message"); + } + } + 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(H5F_addr_defined(&(oh->chunk[i].addr))); + 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, + "unable to write object header data to disk"); + } + 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++) { - H5O_reset(oh->mesg[i].type, oh->mesg[i].native); - oh->mesg[i].native = H5MM_xfree(oh->mesg[i].native); - } - oh->mesg = H5MM_xfree(oh->mesg); - - /* destroy object header */ - H5MM_xfree(oh); + /* 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++) { + H5O_reset(oh->mesg[i].type, oh->mesg[i].native); + 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_reset + * Function: H5O_reset * - * Purpose: Some message data structures have internal fields that - * need to be freed. This function does that if appropriate - * but doesn't free NATIVE. + * Purpose: Some message data structures have internal fields that + * need to be freed. This function does that if appropriate + * but doesn't free NATIVE. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 12 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 12 1997 * * Modifications: * @@ -630,31 +638,31 @@ H5O_reset(const H5O_class_t *type, void *native) FUNC_ENTER(H5O_reset, FAIL); if (native) { - if (type->reset) { - if ((type->reset) (native) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "reset method failed"); - } - } else { - HDmemset(native, 0, type->native_size); - } + if (type->reset) { + if ((type->reset) (native) < 0) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, + "reset method failed"); + } + } else { + HDmemset(native, 0, type->native_size); + } } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5O_link + * Function: H5O_link * - * Purpose: Adjust the link count for an object header by adding - * ADJUST to the link count. + * Purpose: Adjust the link count for an object header by adding + * ADJUST to the link count. * - * Return: Success: New link count + * Return: Success: New link count * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 5 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 5 1997 * * Modifications: * @@ -663,8 +671,8 @@ H5O_reset(const H5O_class_t *type, void *native) intn H5O_link(H5G_entry_t *ent, intn adjust) { - H5O_t *oh = NULL; - intn ret_value = FAIL; + H5O_t *oh = NULL; + intn ret_value = FAIL; FUNC_ENTER(H5O_link, FAIL); @@ -675,19 +683,20 @@ H5O_link(H5G_entry_t *ent, intn adjust) /* get header */ if (NULL == (oh = H5AC_protect(ent->file, H5AC_OHDR, &(ent->header), - NULL, NULL))) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, - "unable to load object header"); + NULL, NULL))) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); } + /* adjust link count */ if (adjust < 0) { - if (oh->nlink + adjust < 0) { - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, - "link count would be negative"); - } - oh->nlink += adjust; + if (oh->nlink + adjust < 0) { + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, + "link count would be negative"); + } + oh->nlink += adjust; } else { - oh->nlink += adjust; + oh->nlink += adjust; } oh->dirty = TRUE; @@ -695,41 +704,41 @@ H5O_link(H5G_entry_t *ent, intn adjust) done: if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, - "unable to release object header"); + HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, + "unable to release object header"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_read + * 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. + * 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. + * Return: Success: Ptr to message in native format. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 6 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 6 1997 * * Modifications: * *------------------------------------------------------------------------- */ -void * +void * H5O_read(H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg) { - H5O_t *oh = NULL; - void *retval = NULL; - intn idx; - H5G_cache_t *cache = NULL; - H5G_type_t cache_type; + H5O_t *oh = NULL; + void *retval = NULL; + intn idx; + H5G_cache_t *cache = NULL; + H5G_type_t cache_type; FUNC_ENTER(H5O_read, NULL); @@ -743,50 +752,52 @@ H5O_read(H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg) /* can we get it from the symbol table entry? */ cache = H5G_ent_cache(ent, &cache_type); if (H5O_fast_g[cache_type]) { - retval = (H5O_fast_g[cache_type]) (cache, type, mesg); - if (retval) - HRETURN(retval); - H5ECLEAR; /*don't care, try reading from header */ + retval = (H5O_fast_g[cache_type]) (cache, type, mesg); + if (retval) + HRETURN(retval); + H5ECLEAR; /*don't care, try reading from header */ } + /* can we get it from the object header? */ if ((idx = H5O_find_in_ohdr(ent->file, &(ent->header), &type, - sequence)) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, - "unable to find message in object header"); + sequence)) < 0) { + HRETURN_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, + "unable to find message in object header"); } + /* copy the message to the user-supplied buffer */ if (NULL == (oh = H5AC_protect(ent->file, H5AC_OHDR, &(ent->header), - NULL, NULL))) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, - "unable to load object header"); + NULL, NULL))) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, + "unable to load object header"); } retval = (type->copy) (oh->mesg[idx].native, mesg); if (H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, NULL, - "unable to release object header"); + HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, NULL, + "unable to release object header"); } oh = NULL; if (!retval) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, - "unable to copy object header message to user space"); + HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, + "unable to copy object header message to user space"); } FUNC_LEAVE(retval); } /*------------------------------------------------------------------------- - * Function: H5O_find_in_ohdr + * Function: H5O_find_in_ohdr * - * Purpose: Find a message in the object header without consulting - * a symbol table entry. + * Purpose: Find a message in the object header without consulting + * a symbol table entry. * - * Return: Success: Index number of message. + * Return: Success: Index number of message. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 6 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 6 1997 * * Modifications: * @@ -794,10 +805,10 @@ H5O_read(H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg) */ static intn H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, - intn sequence) + intn sequence) { - H5O_t *oh = NULL; - int i; + H5O_t *oh = NULL; + int i; FUNC_ENTER(H5O_find_in_ohdr, FAIL); @@ -808,31 +819,33 @@ H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, /* load the object header */ if (NULL == (oh = H5AC_find(f, H5AC_OHDR, addr, NULL, NULL))) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, - "unable to load object header"); + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); } + /* 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 (*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, - "unable to find object header message"); + HRETURN_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, + "unable to find object header message"); } + /* 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_size, - oh->mesg[i].raw); - if (NULL == oh->mesg[i].native) { - HRETURN_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, - "unable to decode message"); - } + assert(oh->mesg[i].type->decode); + assert (oh->mesg[i].raw_size==H5O_ALIGN (oh->mesg[i].raw_size)); + oh->mesg[i].native = (oh->mesg[i].type->decode) (f, + oh->mesg[i].raw_size, + oh->mesg[i].raw); + if (NULL == oh->mesg[i].native) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, + "unable to decode message"); + } } + /*return the message type */ *type_p = oh->mesg[i].type; @@ -840,50 +853,50 @@ H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, } /*------------------------------------------------------------------------- - * Function: H5O_modify + * Function: H5O_modify * - * Purpose: Modifies an existing message or creates a new message. - * The cache fields in that symbol table entry ENT are *not* - * updated, you must do that separately because they often - * depend on multiple object header messages. Besides, we - * don't know which messages will be constant and which will - * not. + * Purpose: Modifies an existing message or creates a new message. + * The cache fields in that symbol table entry ENT are *not* + * updated, you must do that separately because they often + * depend on multiple object header messages. Besides, we + * don't know which messages will be constant and which will + * not. * - * 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. If the message to overwrite doesn't exist then - * it is created (but only if it can be inserted so its sequence - * number is OVERWRITE; that is, you can create a message with - * the sequence number 5 if there is no message with sequence - * number 4). + * 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. If the message to overwrite doesn't exist then + * it is created (but only if it can be inserted so its sequence + * number is OVERWRITE; that is, you can create a message with + * the sequence number 5 if there is no message with sequence + * number 4). * - * Return: Success: The sequence number of the message that - * was modified or created. + * Return: Success: The sequence number of the message that + * was modified or created. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 6 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 6 1997 * * Modifications: * - * Robb Matzke, 7 Jan 1998 - * Handles constant vs non-constant messages. Once a message is made - * constant it can never become non-constant. Constant messages cannot - * be modified. + * Robb Matzke, 7 Jan 1998 + * Handles constant vs non-constant messages. Once a message is made + * constant it can never become non-constant. Constant messages cannot + * be modified. * *------------------------------------------------------------------------- */ intn H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, - uintn flags, const void *mesg) + uintn flags, const void *mesg) { - H5O_t *oh = NULL; - intn idx, sequence; - intn ret_value = FAIL; - size_t size; + H5O_t *oh = NULL; + intn idx, sequence; + intn ret_value = FAIL; + size_t size; FUNC_ENTER(H5O_modify, FAIL); @@ -895,49 +908,49 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, assert(mesg); if (NULL == (oh = H5AC_protect(ent->file, H5AC_OHDR, &(ent->header), - NULL, NULL))) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, - "unable to load object header"); + NULL, NULL))) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); } + /* Count similar messages */ for (idx = 0, sequence = -1; idx < oh->nmesgs; idx++) { - if (type->id != oh->mesg[idx].type->id) - continue; - if (++sequence == overwrite) - break; + if (type->id != oh->mesg[idx].type->id) continue; + if (++sequence == overwrite) break; } /* Was the right message found? */ if (overwrite >= 0 && - (idx >= oh->nmesgs || sequence != overwrite)) { - - /* But can we insert a new one with this sequence number? */ - if (overwrite == sequence + 1) { - overwrite = -1; - } else { - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found"); - } + (idx >= oh->nmesgs || sequence != overwrite)) { + + /* But can we insert a new one with this sequence number? */ + if (overwrite == sequence + 1) { + overwrite = -1; + } else { + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found"); + } } if (overwrite < 0) { - /* Allocate space for the new message */ - size = (type->raw_size) (ent->file, mesg); - H5O_ALIGN(size, oh->alignment); - idx = H5O_alloc(ent->file, oh, type, size); - if (idx < 0) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "unable to allocate object header space for message"); - } - sequence++; + /* Allocate space for the new message */ + size = (type->raw_size) (ent->file, mesg); + size = H5O_ALIGN(size); + idx = H5O_alloc(ent->file, oh, type, size); + if (idx < 0) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, + "unable to allocate object header space for message"); + } + sequence++; } else if (oh->mesg[idx].constant) { - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, - "unable to modify constant message"); + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, + "unable to modify constant message"); } + /* 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) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "unable to copy message to object header"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, + "unable to copy message to object header"); } oh->mesg[idx].constant = (flags & H5O_FLAG_CONSTANT) ? TRUE : FALSE; oh->mesg[idx].dirty = TRUE; @@ -946,45 +959,45 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, done: if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, - "unable to release object header"); + HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, + "unable to release object header"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_remove + * Function: H5O_remove * - * Purpose: Removes the specified message from the object header. - * If sequence is H5O_ALL (-1) then all messages of the - * specified type are removed. Removing a message causes - * the sequence numbers to change for subsequent messages of - * the same type. + * Purpose: Removes the specified message from the object header. + * If sequence is H5O_ALL (-1) then all messages of the + * specified type are removed. Removing a message causes + * the sequence numbers to change for subsequent messages of + * the same type. * - * No attempt is made to join adjacent free areas of the - * object header into a single larger free area. + * No attempt is made to join adjacent free areas of the + * object header into a single larger free area. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 28 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 28 1997 * * Modifications: * - * Robb Matzke, 7 Jan 1998 - * Does not remove constant messages. + * Robb Matzke, 7 Jan 1998 + * Does not remove constant messages. * *------------------------------------------------------------------------- */ herr_t H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) { - H5O_t *oh = NULL; - intn i, seq, nfailed = 0; - herr_t ret_value = FAIL; + H5O_t *oh = NULL; + intn i, seq, nfailed = 0; + herr_t ret_value = FAIL; FUNC_ENTER(H5O_remove, FAIL); @@ -996,68 +1009,67 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) /* load the object header */ if (NULL == (oh = H5AC_protect(ent->file, H5AC_OHDR, &(ent->header), - NULL, NULL))) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, - "unable to load object header"); + NULL, NULL))) { + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); } for (i = seq = 0; i < oh->nmesgs; i++) { - if (type->id != oh->mesg[i].type->id) - continue; - if (seq++ == sequence || H5O_ALL == sequence) { - - /* - * Keep track of how many times we failed trying to remove constant - * messages. - */ - if (oh->mesg[i].constant) { - nfailed++; - continue; - } - /* change message type to nil and zero it */ - oh->mesg[i].type = H5O_NULL; - HDmemset(oh->mesg[i].raw, 0, oh->mesg[i].raw_size); - H5O_reset(type, oh->mesg[i].native); - oh->mesg[i].native = H5MM_xfree(oh->mesg[i].native); - - oh->mesg[i].dirty = TRUE; - oh->dirty = TRUE; - } + if (type->id != oh->mesg[i].type->id) continue; + if (seq++ == sequence || H5O_ALL == sequence) { + /* + * Keep track of how many times we failed trying to remove constant + * messages. + */ + if (oh->mesg[i].constant) { + nfailed++; + continue; + } + + /* change message type to nil and zero it */ + oh->mesg[i].type = H5O_NULL; + HDmemset(oh->mesg[i].raw, 0, oh->mesg[i].raw_size); + H5O_reset(type, oh->mesg[i].native); + oh->mesg[i].native = H5MM_xfree(oh->mesg[i].native); + + oh->mesg[i].dirty = TRUE; + oh->dirty = TRUE; + } } /* Fail if we tried to remove any constant messages */ if (nfailed) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, - "unable to remove constant message(s)"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, + "unable to remove constant message(s)"); } ret_value = SUCCEED; done: if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, - "unable to release object header"); + HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, + "unable to release object header"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_alloc_extend_chunk + * 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. + * 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. + * 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. + * Return: Success: Message index for null message which + * is large enough to hold SIZE bytes. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 7 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 7 1997 * * Modifications: * @@ -1066,9 +1078,9 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) static intn H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) { - intn idx, i; - size_t delta; - uint8 *old_addr; + intn idx, i; + size_t delta; + uint8 *old_addr; FUNC_ENTER(H5O_alloc_extend_chunk, FAIL); @@ -1076,97 +1088,101 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) assert(oh); assert(chunkno >= 0 && chunkno < oh->nchunks); assert(size > 0); + assert (size==H5O_ALIGN (size)); if (H5F_addr_defined(&(oh->chunk[chunkno].addr))) { - HRETURN_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "chunk is on disk"); + 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; - - /* Be careful not to indroduce garbage */ - oh->chunk[chunkno].image = H5MM_xrealloc(old_addr, - (oh->chunk[chunkno].size + - delta)); - HDmemset(oh->chunk[chunkno].image + oh->chunk[chunkno].size, - 0, delta); - oh->chunk[chunkno].size += delta; - - /* 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); - } + 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); + assert (delta=H5O_ALIGN (delta)); + oh->mesg[idx].dirty = TRUE; + oh->mesg[idx].raw_size += delta; + + old_addr = oh->chunk[chunkno].image; + + /* Be careful not to indroduce garbage */ + oh->chunk[chunkno].image = H5MM_xrealloc(old_addr, + (oh->chunk[chunkno].size + + delta)); + HDmemset(oh->chunk[chunkno].image + oh->chunk[chunkno].size, + 0, delta); + oh->chunk[chunkno].size += delta; + + /* 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)); + 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); + delta = MAX(H5O_MIN_SIZE, size+H5O_SIZEOF_MSGHDR(f)); + delta = H5O_ALIGN(delta); 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].raw = oh->chunk[chunkno].image + + oh->chunk[chunkno].size + + H5O_SIZEOF_MSGHDR(f); + oh->mesg[idx].raw_size = delta - H5O_SIZEOF_MSGHDR(f); 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); + 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); - } - } + 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 + * 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. + * 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. + * 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 + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 7 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 7 1997 * * Modifications: * @@ -1175,19 +1191,20 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) static intn H5O_alloc_new_chunk(H5F_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; + 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, FAIL); /* check args */ - assert(oh); - assert(size > 0); + assert (oh); + assert (size > 0); + assert (size == H5O_ALIGN (size)); /* * Find the smallest null message that will hold an object @@ -1195,24 +1212,25 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * 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_ADDR(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; - } + cont_size = H5O_ALIGN (H5F_SIZEOF_ADDR(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); @@ -1222,23 +1240,23 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * other message. */ if (found_null < 0) - size += 4 + oh->mesg[found_other].raw_size; + size += H5O_SIZEOF_MSGHDR(f) + 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 + * 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); + size = MAX(H5O_MIN_SIZE, size + H5O_SIZEOF_MSGHDR(f)); + assert (size == H5O_ALIGN (size)); /* * 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)); + 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; @@ -1251,34 +1269,35 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * 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)); + 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; + 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 + H5O_SIZEOF_MSGHDR(f); + oh->mesg[found_other].chunkno = chunkno; + p += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size; + size -= H5O_SIZEOF_MSGHDR(f) + 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].raw = p + H5O_SIZEOF_MSGHDR(f); + oh->mesg[idx].raw_size = size - H5O_SIZEOF_MSGHDR(f); oh->mesg[idx].chunkno = chunkno; /* @@ -1287,17 +1306,21 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) * 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; + 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 + + H5O_SIZEOF_MSGHDR(f); + oh->mesg[i].raw_size = oh->mesg[found_null].raw_size - + (cont_size + H5O_SIZEOF_MSGHDR(f)); + 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. */ @@ -1313,17 +1336,17 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) } /*------------------------------------------------------------------------- - * Function: H5O_alloc + * Function: H5O_alloc * - * Purpose: Allocate enough space in the object header for this message. + * Purpose: Allocate enough space in the object header for this message. * - * Return: Success: Index of message + * Return: Success: Index of message * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 6 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 6 1997 * * Modifications: * @@ -1332,29 +1355,29 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) static intn H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) { - intn chunkno; - intn idx; - intn null_idx; + intn chunkno; + intn idx; + intn null_idx; FUNC_ENTER(H5O_alloc, FAIL); /* check args */ - assert(oh); - assert(type); - H5O_ALIGN(size, oh->alignment); + assert (oh); + assert (type); + assert (size == H5O_ALIGN (size)); /* 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 (H5O_NULL_ID == oh->mesg[idx].type->id && + oh->mesg[idx].raw_size >= size) + break; } #ifdef LATER /* * Perhaps if we join adjacent null messages we could make one * large enough... we leave this as an exercise for future - * programmers :-) This isn't a high priority because when an + * programmers :-) This isn't a high priority because when an * object header is read from disk the null messages are combined * anyway. */ @@ -1362,44 +1385,48 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) /* 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, - "unable to create a new object header data chunk"); - } - } + /* + * 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, + "unable to create a new object header data chunk"); + } + } } + /* 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; + assert(oh->mesg[idx].raw_size - size >= H5O_SIZEOF_MSGHDR(f)); + + 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 + + H5O_SIZEOF_MSGHDR(f); + oh->mesg[null_idx].raw_size = oh->mesg[idx].raw_size - + (size + H5O_SIZEOF_MSGHDR(f)); + oh->mesg[null_idx].chunkno = oh->mesg[idx].chunkno; + oh->mesg[idx].raw_size = size; } /* initialize the new message */ oh->mesg[idx].type = type; @@ -1411,17 +1438,17 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) } /*------------------------------------------------------------------------- - * Function: H5O_debug + * Function: H5O_debug * - * Purpose: Prints debugging info about an object header. + * Purpose: Prints debugging info about an object header. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 6 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 6 1997 * * Modifications: * @@ -1429,14 +1456,14 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) */ herr_t H5O_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, - intn fwidth) + intn fwidth) { - H5O_t *oh = NULL; - intn i, chunkno; - size_t mesg_total = 0, chunk_total = 0; - int *sequence; - haddr_t tmp_addr; - herr_t ret_value = FAIL; + H5O_t *oh = NULL; + intn i, chunkno; + size_t mesg_total = 0, chunk_total = 0; + int *sequence; + haddr_t tmp_addr; + herr_t ret_value = FAIL; FUNC_ENTER(H5O_debug, FAIL); @@ -1448,119 +1475,117 @@ H5O_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, assert(fwidth >= 0); if (NULL == (oh = H5AC_protect(f, H5AC_OHDR, addr, NULL, NULL))) { - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, - "unable to load object header"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); } + /* 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)); + "Dirty:", + (int) (oh->dirty)); fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, - "Alignment:", - (int) (oh->alignment)); + "Version:", + (int) (oh->version)); fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, - "Number of links:", - (int) (oh->nlink)); + "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)); + "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)); + "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 ", indent + 3, "", MAX(0, fwidth - 3), - "Address:"); - H5F_addr_print(stream, &(oh->chunk[i].addr)); - fprintf(stream, "\n"); - - tmp_addr = *addr; - H5F_addr_inc(&tmp_addr, H5O_SIZEOF_HDR(f)); - if (0 == i && H5F_addr_ne(&(oh->chunk[i].addr), &tmp_addr)) { - 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)); + for (i=0, 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 ", indent + 3, "", MAX(0, fwidth - 3), + "Address:"); + H5F_addr_print(stream, &(oh->chunk[i].addr)); + fprintf(stream, "\n"); + + tmp_addr = *addr; + H5F_addr_inc(&tmp_addr, H5O_SIZEOF_HDR(f)); + if (0 == i && H5F_addr_ne(&(oh->chunk[i].addr), &tmp_addr)) { + 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 %s\n", indent + 3, "", MAX(0, fwidth - 3), - "Constant:", - oh->mesg[i].constant ? "Yes" : "No"); - 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_size, - 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, ""); - } + for (i=0, mesg_total=0; i<oh->nmesgs; i++) { + mesg_total += H5O_SIZEOF_MSGHDR(f) + 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 %s\n", indent + 3, "", MAX(0, fwidth - 3), + "Constant:", + oh->mesg[i].constant ? "Yes" : "No"); + 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_size, + 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"); + fprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n"); } ret_value = SUCCEED; done: if (oh && H5AC_unprotect(f, H5AC_OHDR, addr, oh) < 0) { - HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, - "unable to release object header"); + HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, + "unable to release object header"); } FUNC_LEAVE(ret_value); } |