diff options
Diffstat (limited to 'src/H5Oefl.c')
-rw-r--r-- | src/H5Oefl.c | 322 |
1 files changed, 221 insertions, 101 deletions
diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 49c6c44..eb82c30 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -1,16 +1,17 @@ /* * Copyright (C) 1997 NCSA - * All rights reserved. + * All rights reserved. * * Programmer: Robb Matzke <matzke@llnl.gov> - * Tuesday, November 25, 1997 + * Tuesday, November 25, 1997 */ #include <H5private.h> #include <H5Eprivate.h> +#include <H5Hprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> -#define PABLO_MASK H5O_efl_mask +#define PABLO_MASK H5O_efl_mask /* PRIVATE PROTOTYPES */ static void *H5O_efl_decode(H5F_t *f, size_t raw_size, const uint8 *p); @@ -23,34 +24,35 @@ static herr_t H5O_efl_debug(H5F_t *f, const void *_mesg, FILE * stream, intn indent, intn fwidth); /* This message derives from H5O */ -const H5O_class_t H5O_EFL[1] = {{ - H5O_EFL_ID, /*message id number */ +const H5O_class_t H5O_EFL[1] = {{ + H5O_EFL_ID, /*message id number */ "external file list", /*message name for debugging */ - sizeof(H5O_efl_t), /*native message size */ - H5O_efl_decode, /*decode message */ - H5O_efl_encode, /*encode message */ - H5O_efl_copy, /*copy native value */ - H5O_efl_size, /*size of message on disk */ - H5O_efl_reset, /*reset method */ - H5O_efl_debug, /*debug the message */ + sizeof(H5O_efl_t), /*native message size */ + H5O_efl_decode, /*decode message */ + H5O_efl_encode, /*encode message */ + H5O_efl_copy, /*copy native value */ + H5O_efl_size, /*size of message on disk */ + H5O_efl_reset, /*reset method */ + H5O_efl_debug, /*debug the message */ }}; /* Interface initialization */ static hbool_t interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL +#define INTERFACE_INIT NULL + /*------------------------------------------------------------------------- - * Function: H5O_efl_decode + * Function: H5O_efl_decode * - * Purpose: Decode an external file list message and return a pointer to - * the message (and some other data). + * Purpose: Decode an external file list message and return a pointer to + * the message (and some other data). * - * Return: Success: Ptr to a new message struct. + * Return: Success: Ptr to a new message struct. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * @@ -59,42 +61,61 @@ static hbool_t interface_initialize_g = FALSE; static void * H5O_efl_decode(H5F_t *f, size_t raw_size, const uint8 *p) { - H5O_efl_t *mesg = NULL; - int i; + H5O_efl_t *mesg = NULL; + int i; + const char *s = NULL; FUNC_ENTER(H5O_efl_decode, NULL); - /* check args */ + /* Check args */ assert(f); assert(p); - /* decode */ + /* Decode the header */ mesg = H5MM_xcalloc(1, sizeof(H5O_efl_t)); H5F_addr_decode(f, &p, &(mesg->heap_addr)); - UINT32DECODE(p, mesg->nalloc); - assert(mesg->nalloc > 0); - UINT32DECODE(p, mesg->nused); +#ifndef NDEBUG + assert (H5F_addr_defined (&(mesg->heap_addr))); + s = H5H_peek (f, &(mesg->heap_addr), 0); + assert (s && !*s); +#endif + UINT16DECODE(p, mesg->nalloc); + assert(mesg->nalloc>0); + UINT16DECODE(p, mesg->nused); assert(mesg->nused <= mesg->nalloc); + p += 4; /*reserved*/ - mesg->offset = H5MM_xmalloc(mesg->nalloc * sizeof(size_t)); - for (i = 0; i < mesg->nused; i++) { - UINT32DECODE(p, mesg->offset[i]); + /* Decode the file list */ + mesg->slot = H5MM_xcalloc(mesg->nalloc, sizeof(H5O_efl_entry_t)); + for (i=0; i<mesg->nused; i++) { + /* Name */ + H5F_decode_length (f, p, mesg->slot[i].name_offset); + s = H5H_peek (f, &(mesg->heap_addr), mesg->slot[i].name_offset); + assert (s && *s); + mesg->slot[i].name = H5MM_xstrdup (s); + + /* File offset */ + H5F_decode_length (f, p, mesg->slot[i].offset); + + /* Size */ + H5F_decode_length (f, p, mesg->slot[i].size); + assert (mesg->slot[i].size>0); } FUNC_LEAVE(mesg); } /*------------------------------------------------------------------------- - * Function: H5O_efl_encode + * Function: H5O_efl_encode * - * Purpose: Encodes a message + * Purpose: Encodes a message. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * @@ -103,8 +124,10 @@ H5O_efl_decode(H5F_t *f, size_t raw_size, const uint8 *p) static herr_t H5O_efl_encode(H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg) { - const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; - int i; + const H5O_efl_t *mesg = (const H5O_efl_t *)_mesg; + int i; + size_t offset; + FUNC_ENTER(H5O_efl_encode, FAIL); @@ -114,76 +137,106 @@ H5O_efl_encode(H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg) assert(raw_size == H5O_ALIGN (H5O_efl_size(f, _mesg))); assert(p); - /* encode */ + /* Encode header */ + assert (H5F_addr_defined (&(mesg->heap_addr))); H5F_addr_encode(f, &p, &(mesg->heap_addr)); - UINT32ENCODE(p, mesg->nalloc); - UINT32ENCODE(p, mesg->nused); - for (i = 0; i < mesg->nused; i++) { - UINT32ENCODE(p, mesg->offset[i]); + assert (mesg->nalloc>0); + UINT16ENCODE(p, mesg->nused); /*yes, twice*/ + assert (mesg->nused>0 && mesg->nused<=mesg->nalloc); + UINT16ENCODE(p, mesg->nused); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + /* Encode file list */ + for (i=0; i<mesg->nused; i++) { + /* + * If the name has not been added to the heap yet then do so now. + */ + if (0==mesg->slot[i].name_offset) { + offset = H5H_insert (f, &(mesg->heap_addr), + strlen (mesg->slot[i].name)+1, + mesg->slot[i].name); + if ((size_t)(-1)==offset) { + HRETURN_ERROR (H5E_EFL, H5E_CANTINIT, FAIL, + "unable to insert URL into name heap"); + } + mesg->slot[i].name_offset = offset; + } + + /* Encode the file info */ + H5F_encode_length (f, p, mesg->slot[i].name_offset); + H5F_encode_length (f, p, mesg->slot[i].offset); + H5F_encode_length (f, p, mesg->slot[i].size); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5O_efl_copy + * Function: H5O_efl_copy * - * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if - * necessary. + * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if + * necessary. * - * Return: Success: Ptr to _DEST + * Return: Success: Ptr to _DEST * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static void * +static void * H5O_efl_copy(const void *_mesg, void *_dest) { - const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; - H5O_efl_t *dest = (H5O_efl_t *) _dest; - int i; + const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; + H5O_efl_t *dest = (H5O_efl_t *) _dest; + int i; FUNC_ENTER(H5O_efl_copy, NULL); /* check args */ assert(mesg); if (!dest) { - dest = H5MM_xcalloc(1, sizeof(H5O_efl_t)); - dest->offset = H5MM_xmalloc(mesg->nalloc * sizeof(size_t)); - } else if (dest->nalloc < mesg->nalloc) { - H5MM_xfree(dest->offset); - dest->offset = H5MM_xmalloc(mesg->nalloc * sizeof(size_t)); + dest = H5MM_xcalloc(1, sizeof(H5O_efl_t)); + dest->slot = H5MM_xmalloc(mesg->nalloc * sizeof(H5O_efl_entry_t)); + } else if (NULL==dest->slot || dest->nalloc<mesg->nalloc) { + H5MM_xfree(dest->slot); + dest->slot = H5MM_xmalloc(mesg->nalloc * sizeof(H5O_efl_entry_t)); } dest->heap_addr = mesg->heap_addr; dest->nalloc = mesg->nalloc; dest->nused = mesg->nused; for (i = 0; i < mesg->nused; i++) { - dest->offset[i] = mesg->offset[i]; + dest->slot[i] = mesg->slot[i]; + dest->slot[i].name = H5MM_xstrdup (mesg->slot[i].name); } - FUNC_LEAVE((void *) dest); + FUNC_LEAVE((void *)dest); } + /*------------------------------------------------------------------------- - * Function: H5O_efl_size + * Function: H5O_efl_size * - * Purpose: Returns the size of the raw message in bytes not counting the - * message type or size fields, but only the data fields. This - * function doesn't take into account message alignment. + * Purpose: Returns the size of the raw message in bytes not counting the + * message type or size fields, but only the data fields. This + * function doesn't take into account message alignment. This + * function doesn't count unused slots. * - * Return: Success: Message data size in bytes. + * Return: Success: Message data size in bytes. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * @@ -192,8 +245,8 @@ H5O_efl_copy(const void *_mesg, void *_dest) static size_t H5O_efl_size(H5F_t *f, const void *_mesg) { - const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; - size_t ret_value = FAIL; + const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; + size_t ret_value = FAIL; FUNC_ENTER(H5O_efl_size, FAIL); @@ -201,26 +254,30 @@ H5O_efl_size(H5F_t *f, const void *_mesg) assert(f); assert(mesg); - ret_value = H5F_SIZEOF_ADDR(f) + /*heap address */ - 4 + /*num slots allocated */ - 4 + /*num slots used */ - mesg->nalloc * 4; /*name offsets in heap */ + ret_value = H5F_SIZEOF_ADDR(f) + /*heap address */ + 2 + /*slots allocated*/ + 2 + /*num slots used*/ + 4 + /*reserved */ + mesg->nused * (H5F_SIZEOF_SIZE(f) + /*name offset */ + H5F_SIZEOF_SIZE(f) + /*file offset */ + H5F_SIZEOF_SIZE(f)); /*file size */ FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5O_efl_reset + * Function: H5O_efl_reset * - * Purpose: Frees internal pointers and resets the message to an - * initialial state. + * Purpose: Frees internal pointers and resets the message to an + * initialial state. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * @@ -229,7 +286,9 @@ H5O_efl_size(H5F_t *f, const void *_mesg) static herr_t H5O_efl_reset(void *_mesg) { - H5O_efl_t *mesg = (H5O_efl_t *) _mesg; + H5O_efl_t *mesg = (H5O_efl_t *) _mesg; + int i; + FUNC_ENTER(H5O_efl_reset, FAIL); @@ -237,23 +296,70 @@ H5O_efl_reset(void *_mesg) assert(mesg); /* reset */ + for (i=0; i<mesg->nused; i++) { + mesg->slot[i].name = H5MM_xfree (mesg->slot[i].name); + } + H5F_addr_undef (&(mesg->heap_addr)); mesg->nused = mesg->nalloc = 0; - mesg->offset = H5MM_xfree(mesg->offset); + mesg->slot = H5MM_xfree(mesg->slot); FUNC_LEAVE(SUCCEED); } + + +/*------------------------------------------------------------------------- + * Function: H5O_efl_total_size + * + * Purpose: Return the total size of the external file list by summing + * the sizes of all of the files. + * + * Return: Success: Total reserved size for external data. + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Tuesday, March 3, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5O_efl_total_size (H5O_efl_t *efl) +{ + int i; + size_t ret_value = 0, tmp; + + FUNC_ENTER (H5O_efl_total_size, 0); + + if (efl->nused>0 && + H5O_EFL_UNLIMITED==efl->slot[efl->nused-1].size) { + ret_value = H5O_EFL_UNLIMITED; + } else { + for (i=0; i<efl->nused; i++, ret_value=tmp) { + tmp = ret_value + efl->slot[i].size; + if (tmp<=ret_value) { + HRETURN_ERROR (H5E_EFL, H5E_OVERFLOW, 0, + "total external storage size overflowed"); + } + } + } + + FUNC_LEAVE (ret_value); +} + /*------------------------------------------------------------------------- - * Function: H5O_efl_debug + * Function: H5O_efl_debug * - * Purpose: Prints debugging info for a message. + * Purpose: Prints debugging info for a message. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, November 25, 1997 + * Programmer: Robb Matzke + * Tuesday, November 25, 1997 * * Modifications: * @@ -261,11 +367,11 @@ H5O_efl_reset(void *_mesg) */ static herr_t H5O_efl_debug(H5F_t *f, const void *_mesg, FILE * stream, intn indent, - intn fwidth) + intn fwidth) { - const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; - char buf[64]; - intn i; + const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; + char buf[64]; + intn i; FUNC_ENTER(H5O_efl_debug, FAIL); @@ -277,19 +383,33 @@ H5O_efl_debug(H5F_t *f, const void *_mesg, FILE * stream, intn indent, assert(fwidth >= 0); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Heap address:"); + "Heap address:"); H5F_addr_print(stream, &(mesg->heap_addr)); fprintf(stream, "\n"); fprintf(stream, "%*s%-*s %u/%u\n", indent, "", fwidth, - "Slots used/allocated:", - mesg->nused, mesg->nalloc); + "Slots used/allocated:", + mesg->nused, mesg->nalloc); for (i = 0; i < mesg->nused; i++) { - sprintf(buf, "Name %d:", i + 1); - fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, - buf, - (unsigned long) (mesg->offset[i])); + sprintf (buf, "File %d", i); + fprintf (stream, "%*s%s:\n", indent, "", buf); + + fprintf(stream, "%*s%-*s \"%s\"\n", indent+3, "", MAX (fwidth-3, 0), + "Name:", + mesg->slot[i].name); + + fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0), + "Name offset:", + (unsigned long)(mesg->slot[i].name_offset)); + + fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0), + "Offset of data in file:", + (unsigned long)(mesg->slot[i].offset)); + + fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0), + "Bytes reserved for data:", + (unsigned long)(mesg->slot[i].size)); } FUNC_LEAVE(SUCCEED); |