diff options
Diffstat (limited to 'src/H5O.c')
-rw-r--r-- | src/H5O.c | 2631 |
1 files changed, 1288 insertions, 1343 deletions
@@ -1,16 +1,16 @@ /*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. + * 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,52 +22,55 @@ #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 */ }; /* @@ -75,22 +78,20 @@ 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 + * Programmer: Robb Matzke * Tuesday, January 6, 1998 * * Modifications: @@ -98,123 +99,119 @@ static void *(*H5O_fast_g[H5G_NCACHED])(const H5G_cache_t*, *------------------------------------------------------------------------- */ static herr_t -H5O_init_interface (void) +H5O_init_interface(void) { - FUNC_ENTER (H5O_init_interface, FAIL); + FUNC_ENTER(H5O_init_interface, FAIL); - /* - * Initialize functions that decode messages from symbol table entries. - */ - H5O_fast_g[H5G_CACHED_STAB] = H5O_stab_fast; + /* + * Initialize functions that decode messages from symbol table entries. + */ + H5O_fast_g[H5G_CACHED_STAB] = H5O_stab_fast; - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * 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; - - FUNC_ENTER (H5O_create, FAIL); - - /* check args */ - 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); - - /* 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"); - } - - /* 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 */ - oh->nchunks = 1; - oh->alloc_nchunks = H5O_NCHUNKS; - oh->chunk = H5MM_xmalloc (oh->alloc_nchunks * sizeof (H5O_chunk_t)); - - tmp_addr = ent->header; - H5F_addr_inc (&tmp_addr, H5O_SIZEOF_HDR (f)); - oh->chunk[0].dirty = TRUE; - oh->chunk[0].addr = tmp_addr; - oh->chunk[0].size = size_hint; - oh->chunk[0].image = H5MM_xcalloc (1, 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, &(ent->header), oh)<0) { - 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"); - } - - FUNC_LEAVE (SUCCEED); + size_t size; /*total size of object header */ + H5O_t *oh = NULL; + haddr_t tmp_addr; + + FUNC_ENTER(H5O_create, FAIL); + + /* check args */ + 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); + + /* 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"); + } + /* 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 */ + oh->nchunks = 1; + oh->alloc_nchunks = H5O_NCHUNKS; + oh->chunk = H5MM_xmalloc(oh->alloc_nchunks * sizeof(H5O_chunk_t)); + + tmp_addr = ent->header; + H5F_addr_inc(&tmp_addr, H5O_SIZEOF_HDR(f)); + oh->chunk[0].dirty = TRUE; + oh->chunk[0].addr = tmp_addr; + oh->chunk[0].size = size_hint; + oh->chunk[0].image = H5MM_xcalloc(1, 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, &(ent->header), oh) < 0) { + 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"); + } + 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 + * Programmer: Robb Matzke * Monday, January 5, 1998 * * Modifications: @@ -222,37 +219,36 @@ H5O_create (H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) *------------------------------------------------------------------------- */ herr_t -H5O_open (H5F_t *f, H5G_entry_t *obj_ent) +H5O_open(H5F_t *f, H5G_entry_t *obj_ent) { - FUNC_ENTER (H5O_open, FAIL); + FUNC_ENTER(H5O_open, FAIL); - /* Check args */ - assert (f); - assert (obj_ent); + /* Check args */ + assert(f); + assert(obj_ent); #ifdef H5O_DEBUG - fprintf (stderr, ">"); - H5F_addr_print (stderr, &(obj_ent->header)); - fprintf (stderr, "\n"); + fprintf(stderr, ">"); + H5F_addr_print(stderr, &(obj_ent->header)); + fprintf(stderr, "\n"); #endif - /* Increment open-lock counters */ - obj_ent->file = f; - obj_ent->file->nopen++; - FUNC_LEAVE (SUCCEED); + /* Increment open-lock counters */ + obj_ent->file = f; + obj_ent->file->nopen++; + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- - * 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 + * Programmer: Robb Matzke * Monday, January 5, 1998 * * Modifications: @@ -260,1362 +256,1311 @@ H5O_open (H5F_t *f, H5G_entry_t *obj_ent) *------------------------------------------------------------------------- */ herr_t -H5O_close (H5G_entry_t *obj_ent) +H5O_close(H5G_entry_t *obj_ent) { - FUNC_ENTER (H5O_close, FAIL); - - /* Check args */ - assert (obj_ent); - assert (obj_ent->file); - assert (obj_ent->file->nopen>0); - - /* Decrement open-lock counters */ - --obj_ent->file->nopen; - - /* - * If the file open-lock count has reached zero and the file has a close - * pending then close the file. - */ - if (0==obj_ent->file->nopen && obj_ent->file->close_pending) { - H5F_close (obj_ent->file); - } - + FUNC_ENTER(H5O_close, FAIL); + + /* Check args */ + assert(obj_ent); + assert(obj_ent->file); + assert(obj_ent->file->nopen > 0); + + /* Decrement open-lock counters */ + --obj_ent->file->nopen; + + /* + * If the file open-lock count has reached zero and the file has a close + * pending then close the file. + */ + if (0 == obj_ent->file->nopen && obj_ent->file->close_pending) { + H5F_close(obj_ent->file); + } #ifdef H5O_DEBUG - fprintf (stderr, "<"); - H5F_addr_print (stderr, &(obj_ent->header)); - fprintf (stderr, "\n"); + fprintf(stderr, "<"); + H5F_addr_print(stderr, &(obj_ent->header)); + fprintf(stderr, "\n"); #endif - - FUNC_LEAVE (SUCCEED); -} + FUNC_LEAVE(SUCCEED); +} /*------------------------------------------------------------------------- - * 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 * -H5O_load (H5F_t *f, const haddr_t *addr, const void *_udata1, void *_udata2) +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? */ - - - FUNC_ENTER (H5O_load, NULL); - - /* check args */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - assert (!_udata1); - assert (!_udata2); - - /* 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) { - 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"); - } - - /* decode number of messages */ - UINT16DECODE (p, nmesgs); - - /* decode link count */ - UINT32DECODE (p, oh->nlink); - - /* decode first chunk info */ - chunk_addr = *addr; - H5F_addr_inc (&chunk_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 (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*/ - } - } - } - -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); - } - - FUNC_LEAVE (oh); + 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? */ + + FUNC_ENTER(H5O_load, NULL); + + /* check args */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + assert(!_udata1); + assert(!_udata2); + + /* 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) { + 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"); + } + /* decode number of messages */ + UINT16DECODE(p, nmesgs); + + /* decode link count */ + UINT32DECODE(p, oh->nlink); + + /* decode first chunk info */ + chunk_addr = *addr; + H5F_addr_inc(&chunk_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 (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 */ + } + } + } + + 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); + } + FUNC_LEAVE(oh); } - /*------------------------------------------------------------------------- - * 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) +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; - - FUNC_ENTER (H5O_flush, FAIL); - - /* check args */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - 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, - "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; - } - - - 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); - } - - FUNC_LEAVE (SUCCEED); + uint8 buf[16], *p; + intn i, id; + H5O_cont_t *cont = NULL; + + FUNC_ENTER(H5O_flush, FAIL); + + /* check args */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + 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, + "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; + } + 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); + } + 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: * *------------------------------------------------------------------------- */ herr_t -H5O_reset (const H5O_class_t *type, void *native) +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); - } - } - - FUNC_LEAVE (SUCCEED); + 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); + } + } + 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: * *------------------------------------------------------------------------- */ intn -H5O_link (H5G_entry_t *ent, intn adjust) +H5O_link(H5G_entry_t *ent, intn adjust) { - H5O_t *oh = NULL; - intn ret_value = FAIL; - - FUNC_ENTER (H5O_link, FAIL); - - /* check args */ - assert (ent); - assert (ent->file); - assert (H5F_addr_defined (&(ent->header))); - - /* 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"); - } - - /* 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; - } else { - oh->nlink += adjust; - } - - oh->dirty = TRUE; - ret_value = oh->nlink; - - 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"); - } - - FUNC_LEAVE (ret_value); + H5O_t *oh = NULL; + intn ret_value = FAIL; + + FUNC_ENTER(H5O_link, FAIL); + + /* check args */ + assert(ent); + assert(ent->file); + assert(H5F_addr_defined(&(ent->header))); + + /* 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"); + } + /* 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; + } else { + oh->nlink += adjust; + } + + oh->dirty = TRUE; + ret_value = oh->nlink; + + 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"); + } + 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 * -H5O_read (H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg) +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; - - FUNC_ENTER (H5O_read, NULL); - - /* check args */ - assert (ent); - assert (ent->file); - assert (H5F_addr_defined (&(ent->header))); - assert (type); - assert (sequence>=0); - - /* 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*/ - } - - /* 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"); - } - - /* 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"); - } - 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"); - } - oh = NULL; - - if (!retval) { - HRETURN_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, - "unable to copy object header message to user space"); - } - - FUNC_LEAVE (retval); + H5O_t *oh = NULL; + void *retval = NULL; + intn idx; + H5G_cache_t *cache = NULL; + H5G_type_t cache_type; + + FUNC_ENTER(H5O_read, NULL); + + /* check args */ + assert(ent); + assert(ent->file); + assert(H5F_addr_defined(&(ent->header))); + assert(type); + assert(sequence >= 0); + + /* 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 */ + } + /* 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"); + } + /* 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"); + } + 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"); + } + oh = NULL; + + if (!retval) { + 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: * *------------------------------------------------------------------------- */ static intn -H5O_find_in_ohdr (H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, - intn sequence) +H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, + intn sequence) { - H5O_t *oh = NULL; - int i; - - FUNC_ENTER (H5O_find_in_ohdr, FAIL); - - /* check args */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - assert (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"); - } - - /* 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, - "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"); - } - } - - /*return the message type */ - *type_p = oh->mesg[i].type; - - FUNC_LEAVE (i); + H5O_t *oh = NULL; + int i; + + FUNC_ENTER(H5O_find_in_ohdr, FAIL); + + /* check args */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + assert(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"); + } + /* 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, + "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"); + } + } + /*return the message type */ + *type_p = oh->mesg[i].type; + + FUNC_LEAVE(i); } - /*------------------------------------------------------------------------- - * 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) +H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, + uintn flags, const void *mesg) { - H5O_t *oh = NULL; - intn idx, sequence; - intn ret_value = FAIL; - size_t size; - - FUNC_ENTER (H5O_modify, FAIL); - - /* check args */ - assert (ent); - assert (ent->file); - assert (H5F_addr_defined (&(ent->header))); - assert (type); - 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"); - } - - /* 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; - } - - /* 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"); - } - } - - 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++; - - } else if (oh->mesg[idx].constant) { - 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"); - } - oh->mesg[idx].constant = (flags & H5O_FLAG_CONSTANT) ? TRUE : FALSE; - oh->mesg[idx].dirty = TRUE; - oh->dirty = TRUE; - ret_value = sequence; - - 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"); - } - - FUNC_LEAVE (ret_value); + H5O_t *oh = NULL; + intn idx, sequence; + intn ret_value = FAIL; + size_t size; + + FUNC_ENTER(H5O_modify, FAIL); + + /* check args */ + assert(ent); + assert(ent->file); + assert(H5F_addr_defined(&(ent->header))); + assert(type); + 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"); + } + /* 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; + } + + /* 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"); + } + } + 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++; + + } else if (oh->mesg[idx].constant) { + 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"); + } + oh->mesg[idx].constant = (flags & H5O_FLAG_CONSTANT) ? TRUE : FALSE; + oh->mesg[idx].dirty = TRUE; + oh->dirty = TRUE; + ret_value = sequence; + + 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"); + } + 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_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; - - FUNC_ENTER (H5O_remove, FAIL); - - /* check args */ - assert (ent); - assert (ent->file); - assert (H5F_addr_defined (&(ent->header))); - assert (type); - - /* 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"); - } - - 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; - } - } - - /* Fail if we tried to remove any constant messages */ - if (nfailed) { - 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"); - } - - FUNC_LEAVE (ret_value); + H5O_t *oh = NULL; + intn i, seq, nfailed = 0; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5O_remove, FAIL); + + /* check args */ + assert(ent); + assert(ent->file); + assert(H5F_addr_defined(&(ent->header))); + assert(type); + + /* 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"); + } + 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; + } + } + + /* Fail if we tried to remove any constant messages */ + if (nfailed) { + 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"); + } + 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: * *------------------------------------------------------------------------- */ static intn -H5O_alloc_extend_chunk (H5O_t *oh, intn chunkno, size_t size) +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, FAIL); - - /* check args */ - assert (oh); - assert (chunkno>=0 && chunkno<oh->nchunks); - assert (size>0); - - if (H5F_addr_defined (&(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; - - /* 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)); - } - - 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); + intn idx, i; + size_t delta; + uint8 *old_addr; + + FUNC_ENTER(H5O_alloc_extend_chunk, FAIL); + + /* check args */ + assert(oh); + assert(chunkno >= 0 && chunkno < oh->nchunks); + assert(size > 0); + + if (H5F_addr_defined(&(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; + + /* 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)); + } + 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 + * 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: * *------------------------------------------------------------------------- */ static intn -H5O_alloc_new_chunk (H5F_t *f, H5O_t *oh, size_t size) +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; - - FUNC_ENTER (H5O_alloc_new_chunk, 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_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); - - /* - * 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; - H5F_addr_undef (&(oh->chunk[chunkno].addr)); - oh->chunk[chunkno].size = size; - oh->chunk[chunkno].image = p = H5MM_xcalloc (1, 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)); - H5F_addr_undef (&(cont->addr)); - cont->size = 0; - cont->chunkno = chunkno; - oh->mesg[found_null].native = cont; - - - FUNC_LEAVE (idx); + 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); + + /* + * 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_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); + + /* + * 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; + H5F_addr_undef(&(oh->chunk[chunkno].addr)); + oh->chunk[chunkno].size = size; + oh->chunk[chunkno].image = p = H5MM_xcalloc(1, 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)); + H5F_addr_undef(&(cont->addr)); + cont->size = 0; + cont->chunkno = chunkno; + oh->mesg[found_null].native = cont; + + FUNC_LEAVE(idx); } - /*------------------------------------------------------------------------- - * 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: * *------------------------------------------------------------------------- */ static intn -H5O_alloc (H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) +H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) { - intn chunkno; - intn idx; - intn null_idx; - - FUNC_ENTER (H5O_alloc, FAIL); - - /* check args */ - assert (oh); - assert (type); - 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; - } + intn chunkno; + intn idx; + intn null_idx; + + FUNC_ENTER(H5O_alloc, FAIL); + + /* check args */ + assert(oh); + assert(type); + 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; + } #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 - * object header is read from disk the null messages are combined - * anyway. - */ + /* + * 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 + * object header is read from disk the null messages are combined + * anyway. + */ #endif - - /* 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"); - } - } - } - - /* 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); + + /* 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"); + } + } + } + /* 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 + * 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: * *------------------------------------------------------------------------- */ herr_t -H5O_debug (H5F_t *f, const haddr_t *addr, FILE *stream, intn indent, - intn fwidth) +H5O_debug(H5F_t *f, const 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; - haddr_t tmp_addr; - herr_t ret_value = FAIL; - - FUNC_ENTER (H5O_debug, FAIL); - - /* check args */ - assert (f); - assert (addr && H5F_addr_defined (addr)); - assert (stream); - assert (indent>=0); - 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"); - } - - /* 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 ", 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, ""); - } - } - sequence = H5MM_xfree (sequence); - - if (mesg_total != chunk_total) { - 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"); - } - - FUNC_LEAVE (ret_value); + 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); + + /* check args */ + assert(f); + assert(addr && H5F_addr_defined(addr)); + assert(stream); + assert(indent >= 0); + 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"); + } + /* 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 ", 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, ""); + } + } + sequence = H5MM_xfree(sequence); + + if (mesg_total != chunk_total) { + 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"); + } + FUNC_LEAVE(ret_value); } |