diff options
Diffstat (limited to 'src/H5Ocomp.c')
-rw-r--r-- | src/H5Ocomp.c | 380 |
1 files changed, 258 insertions, 122 deletions
diff --git a/src/H5Ocomp.c b/src/H5Ocomp.c index 3f341ea..a30eb6f 100644 --- a/src/H5Ocomp.c +++ b/src/H5Ocomp.c @@ -5,48 +5,49 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Wednesday, April 15, 1998 * - * Purpose: Data compression message. + * Purpose: Data filter pipeline message. */ #include <H5private.h> #include <H5Eprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> -#define PABLO_MASK H5O_comp_mask +/* Interface initialization */ +#define PABLO_MASK H5O_pline_mask +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL -/* PRIVATE PROTOTYPES */ -static herr_t H5O_comp_encode (H5F_t *f, uint8 *p, const void *mesg); -static void *H5O_comp_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh); -static void *H5O_comp_copy (const void *_mesg, void *_dest); -static size_t H5O_comp_size (H5F_t *f, const void *_mesg); -static herr_t H5O_comp_reset (void *_mesg); -static herr_t H5O_comp_debug (H5F_t *f, const void *_mesg, - FILE * stream, intn indent, intn fwidth); +#define H5O_PLINE_VERSION 1 + +static herr_t H5O_pline_encode (H5F_t *f, uint8 *p, const void *mesg); +static void *H5O_pline_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh); +static void *H5O_pline_copy (const void *_mesg, void *_dest); +static size_t H5O_pline_size (H5F_t *f, const void *_mesg); +static herr_t H5O_pline_reset (void *_mesg); +static herr_t H5O_pline_debug (H5F_t *f, const void *_mesg, + FILE * stream, intn indent, intn fwidth); /* This message derives from H5O */ -const H5O_class_t H5O_COMPRESS[1] = {{ - H5O_COMPRESS_ID, /* message id number */ - "compression", /* message name for debugging */ - sizeof(H5O_compress_t), /* native message size */ - H5O_comp_decode, /* decode message */ - H5O_comp_encode, /* encode message */ - H5O_comp_copy, /* copy the native value */ - H5O_comp_size, /* size of raw message */ - H5O_comp_reset, /* reset method */ +const H5O_class_t H5O_PLINE[1] = {{ + H5O_PLINE_ID, /* message id number */ + "filter pipeline", /* message name for debugging */ + sizeof(H5O_pline_t), /* native message size */ + H5O_pline_decode, /* decode message */ + H5O_pline_encode, /* encode message */ + H5O_pline_copy, /* copy the native value */ + H5O_pline_size, /* size of raw message */ + H5O_pline_reset, /* reset method */ NULL, /* get share method */ NULL, /* set share method */ - H5O_comp_debug, /* debug the message */ + H5O_pline_debug, /* debug the message */ }}; -/* Interface initialization */ -static hbool_t interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL /*------------------------------------------------------------------------- - * Function: H5O_comp_decode + * Function: H5O_pline_decode * - * Purpose: Decodes a compression message. + * Purpose: Decodes a filter pipeline message. * * Return: Success: Ptr to the native message. * @@ -60,46 +61,97 @@ static hbool_t interface_initialize_g = FALSE; *------------------------------------------------------------------------- */ static void * -H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p, +H5O_pline_decode(H5F_t __unused__ *f, const uint8 *p, H5O_shared_t __unused__ *sh) { - H5O_compress_t *comp = NULL; + H5O_pline_t *pline = NULL; void *ret_value = NULL; + uintn version; + size_t i, j, n, name_length; - FUNC_ENTER(H5O_comp_decode, NULL); + FUNC_ENTER(H5O_pline_decode, NULL); /* check args */ assert(p); /* Decode */ - if (NULL==(comp = H5MM_calloc(sizeof *comp))) { + if (NULL==(pline = H5MM_calloc(sizeof *pline))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - comp->method = *p++; - comp->flags = *p++; - UINT16DECODE (p, comp->cd_size); - - if (comp->cd_size>0) { - if (NULL==(comp->client_data = H5MM_malloc (comp->cd_size))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + version = *p++; + if (version!=H5O_PLINE_VERSION) { + HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, + "bad version number for filter pipeline message"); + } + pline->nfilters = *p++; + if (pline->nfilters>32) { + HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, + "filter pipeline message has too many filters"); + } + p += 6; /*reserved*/ + pline->nalloc = pline->nfilters; + pline->filter = H5MM_calloc(pline->nalloc*sizeof(pline->filter[0])); + if (NULL==pline->filter) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + for (i=0; i<pline->nfilters; i++) { + UINT16DECODE(p, pline->filter[i].id); + UINT16DECODE(p, name_length); + if (name_length % 8) { + HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, + "filter name length is not a multiple of eight"); + } + UINT16DECODE(p, pline->filter[i].flags); + UINT16DECODE(p, pline->filter[i].cd_nelmts); + if (name_length) { + /* + * Get the name, allocating an extra byte for an extra null + * terminator just in case there isn't one in the file (there + * should be, but to be safe...) + */ + pline->filter[i].name = H5MM_malloc(name_length+1); + memcpy(pline->filter[i].name, p, name_length); + pline->filter[i].name[name_length] = '\0'; + p += name_length; + } + if ((n=pline->filter[i].cd_nelmts)) { + /* + * Read the client data values and the padding + */ + pline->filter[i].cd_values = H5MM_malloc(n*sizeof(uintn)); + if (NULL==pline->filter[i].cd_values) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for client data"); + } + for (j=0; j<pline->filter[i].cd_nelmts; j++) { + UINT32DECODE(p, pline->filter[i].cd_values[j]); + } + if (pline->filter[i].cd_nelmts % 2) { + p += 4; /*padding*/ + } } - HDmemcpy (comp->client_data, p, comp->cd_size); } - ret_value = comp; + ret_value = pline; done: - if (NULL==ret_value && comp) { - H5MM_xfree (comp->client_data); - H5MM_xfree (comp); + if (NULL==ret_value && pline) { + if (pline->filter) { + for (i=0; i<pline->nfilters; i++) { + H5MM_xfree(pline->filter[i].name); + H5MM_xfree(pline->filter[i].cd_values); + } + H5MM_xfree(pline->filter); + } + H5MM_xfree(pline); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_comp_encode + * Function: H5O_pline_encode * * Purpose: Encodes message MESG into buffer P. * @@ -115,21 +167,47 @@ H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p, *------------------------------------------------------------------------- */ static herr_t -H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg) +H5O_pline_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg) { - const H5O_compress_t *comp = (const H5O_compress_t*)mesg; + const H5O_pline_t *pline = (const H5O_pline_t*)mesg; + size_t i, j, name_length; - FUNC_ENTER (H5O_comp_encode, FAIL); + FUNC_ENTER (H5O_pline_encode, FAIL); /* Check args */ assert (p); assert (mesg); - *p++ = comp->method; - *p++ = comp->flags; - UINT16ENCODE (p, comp->cd_size); - if (comp->cd_size) { - HDmemcpy (p, comp->client_data, comp->cd_size); + *p++ = H5O_PLINE_VERSION; + *p++ = pline->nfilters; + *p++ = 0; /*reserved 1*/ + *p++ = 0; /*reserved 2*/ + *p++ = 0; /*reserved 3*/ + *p++ = 0; /*reserved 4*/ + *p++ = 0; /*reserved 5*/ + *p++ = 0; /*reserved 6*/ + + for (i=0; i<pline->nfilters; i++) { + if (pline->filter[i].name) { + name_length = strlen(pline->filter[i].name)+1; + } else { + name_length = 0; + } + UINT16ENCODE(p, pline->filter[i].id); + UINT16ENCODE(p, H5O_ALIGN(name_length)); + UINT16ENCODE(p, pline->filter[i].flags); + UINT16ENCODE(p, pline->filter[i].cd_nelmts); + if (name_length>0) { + memcpy(p, pline->filter[i].name, name_length); + p += name_length; + while (name_length++ % 8) *p++ = 0; + } + for (j=0; j<pline->filter[i].cd_nelmts; j++) { + UINT32ENCODE(p, pline->filter[i].cd_values[j]); + } + if (pline->filter[i].cd_nelmts % 2) { + UINT32ENCODE(p, 0); + } } FUNC_LEAVE (SUCCEED); @@ -137,10 +215,10 @@ H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg) /*------------------------------------------------------------------------- - * Function: H5O_comp_copy + * Function: H5O_pline_copy * - * Purpose: Copies a compression message from SRC to DST allocating DST - * if necessary. If DST is already allocated then we assume + * Purpose: Copies a filter pipeline message from SRC to DST allocating + * DST if necessary. If DST is already allocated then we assume * that it isn't initialized. * * Return: Success: Ptr to DST or allocated result. @@ -155,34 +233,70 @@ H5O_comp_encode (H5F_t __unused__ *f, uint8 *p/*out*/, const void *mesg) *------------------------------------------------------------------------- */ static void * -H5O_comp_copy (const void *_src, void *_dst/*out*/) +H5O_pline_copy (const void *_src, void *_dst/*out*/) { - const H5O_compress_t *src = (const H5O_compress_t *)_src; - H5O_compress_t *dst = (H5O_compress_t *)_dst; + const H5O_pline_t *src = (const H5O_pline_t *)_src; + H5O_pline_t *dst = (H5O_pline_t *)_dst; + size_t i; + H5O_pline_t *ret_value = NULL; - FUNC_ENTER (H5O_comp_copy, NULL); + FUNC_ENTER (H5O_pline_copy, NULL); if (!dst && NULL==(dst = H5MM_malloc (sizeof *dst))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } + *dst = *src; - if (src->cd_size>0) { - if (NULL==(dst->client_data = H5MM_malloc (src->cd_size))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + dst->nalloc = dst->nfilters; + if (dst->nalloc>0) { + dst->filter = H5MM_calloc(dst->nalloc * sizeof(dst->filter[0])); + if (NULL==dst->filter) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + } else { + dst->filter = NULL; + } + + for (i=0; i<src->nfilters; i++) { + dst->filter[i] = src->filter[i]; + if (src->filter[i].name) { + dst->filter[i].name = H5MM_xstrdup(src->filter[i].name); + } + if (src->filter[i].cd_nelmts>0) { + dst->filter[i].cd_values = H5MM_malloc(src->filter[i].cd_nelmts* + sizeof(uintn)); + if (NULL==dst->filter[i].cd_values) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + HDmemcpy (dst->filter[i].cd_values, src->filter[i].cd_values, + src->filter[i].cd_nelmts * sizeof(uintn)); } - HDmemcpy (dst->client_data, src->client_data, src->cd_size); } + ret_value = dst; - FUNC_LEAVE (dst); + done: + if (!ret_value && dst) { + if (dst->filter) { + for (i=0; i<dst->nfilters; i++) { + H5MM_xfree(dst->filter[i].name); + H5MM_xfree(dst->filter[i].cd_values); + } + H5MM_xfree(dst->filter); + } + if (!_dst) H5MM_xfree(dst); + } + + FUNC_LEAVE (ret_value); } /*------------------------------------------------------------------------- - * Function: H5O_comp_size + * Function: H5O_pline_size * - * Purpose: Determines the size of a raw compression message. + * Purpose: Determines the size of a raw filter pipeline message. * * Return: Success: Size of message. * @@ -196,20 +310,39 @@ H5O_comp_copy (const void *_src, void *_dst/*out*/) *------------------------------------------------------------------------- */ static size_t -H5O_comp_size (H5F_t __unused__ *f, const void *mesg) +H5O_pline_size (H5F_t __unused__ *f, const void *mesg) { - const H5O_compress_t *comp = (const H5O_compress_t*)mesg; - - FUNC_ENTER (H5O_comp_size, 0); - FUNC_LEAVE (4+comp->cd_size); + const H5O_pline_t *pline = (const H5O_pline_t*)mesg; + size_t i, size; + + FUNC_ENTER (H5O_pline_size, 0); + + size = 1 + /*version */ + 1 + /*number of filters */ + 6; /*reserved */ + + for (i=0; i<pline->nfilters; i++) { + size += 2 + /*filter identification number */ + 2 + /*name length */ + 2 + /*flags */ + 2; /*number of client data values */ + if (pline->filter[i].name) { + size_t n = strlen(pline->filter[i].name) + 1; + size += H5O_ALIGN(n); + } + size += pline->filter[i].cd_nelmts * 4; + if (pline->filter[i].cd_nelmts % 2) size += 4; + } + + FUNC_LEAVE (size); } /*------------------------------------------------------------------------- - * Function: H5O_comp_reset + * Function: H5O_pline_reset * - * Purpose: Resets a compression message by freeing the client data and - * setting all fields to zero. The MESG buffer is not freed. + * Purpose: Resets a filter pipeline message by clearing all filters. + * The MESG buffer is not freed. * * Return: Success: SUCCEED * @@ -223,25 +356,30 @@ H5O_comp_size (H5F_t __unused__ *f, const void *mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_comp_reset (void *mesg) +H5O_pline_reset (void *mesg) { - H5O_compress_t *comp = (H5O_compress_t*)mesg; + H5O_pline_t *pline = (H5O_pline_t*)mesg; + size_t i; - FUNC_ENTER (H5O_comp_reset, FAIL); + FUNC_ENTER (H5O_pline_reset, FAIL); - assert (comp); - H5MM_xfree (comp->client_data); - HDmemset (comp, 0, sizeof *comp); + assert (pline); + for (i=0; i<pline->nfilters; i++) { + H5MM_xfree(pline->filter[i].name); + H5MM_xfree(pline->filter[i].cd_values); + } + H5MM_xfree(pline->filter); + HDmemset(pline, 0, sizeof *pline); FUNC_LEAVE (SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5O_comp_debug + * Function: H5O_pline_debug * - * Purpose: Prints debugging information for compression message MESG on - * output stream STREAM. Each line is indented INDENT + * Purpose: Prints debugging information for filter pipeline message MESG + * on output stream STREAM. Each line is indented INDENT * characters and the field name takes up FWIDTH characters. * * Return: Success: SUCCEED @@ -256,56 +394,54 @@ H5O_comp_reset (void *mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_comp_debug (H5F_t __unused__ *f, const void *mesg, FILE *stream, +H5O_pline_debug (H5F_t __unused__ *f, const void *mesg, FILE *stream, intn indent, intn fwidth) { - const H5O_compress_t *comp = (const H5O_compress_t *)mesg; - size_t i, j; + const H5O_pline_t *pline = (const H5O_pline_t *)mesg; + size_t i, j; - FUNC_ENTER(H5O_comp_debug, FAIL); + FUNC_ENTER(H5O_pline_debug, FAIL); /* check args */ assert(f); - assert(comp); + assert(pline); assert(stream); assert(indent >= 0); assert(fwidth >= 0); - fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth, - "Method:", - (int)(comp->method)); - fprintf (stream, "%*s%-*s 0x%02x\n", indent, "", fwidth, - "Flags:", - (unsigned)(comp->flags)); - fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Size of client data:", - (unsigned long)(comp->cd_size)); - - if (comp->cd_size>0) { - fprintf (stream, "%*s%s\n", indent, "", "Client Data:"); - for (i=0; i<comp->cd_size; i+=16) { - fprintf (stream, "%*s%04d: ", indent+3, "", i); - for (j=0; j<16; j++) { - if (8==j) putc (' ', stream); - if (i+j<comp->cd_size) { - fprintf (stream, "%02x ", comp->client_data[i+j]); - } else { - fputs (" ", stream); - } - } - for (j=0; j<16 && i+j<comp->cd_size; j++) { - if (8==j) putc (' ', stream); - if (comp->client_data[i+j]>' ' && - comp->client_data[i+j]<='~') { - putc (comp->client_data[i+j], stream); - } else { - putc ('.', stream); - } - putc ('\n', stream); - } + fprintf(stream, "%*s%-*s %lu/%lu\n", indent, "", fwidth, + "Number of filters:", + (unsigned long)(pline->nfilters), + (unsigned long)(pline->nalloc)); + + for (i=0; i<pline->nfilters; i++) { + char name[32]; + sprintf(name, "Filter at position %lu", (unsigned long)i); + fprintf(stream, "%*s%-*s\n", indent, "", fwidth, name); + fprintf(stream, "%*s%-*s 0x%04x\n", indent+3, "", MAX(0, fwidth-3), + "Filter identification:", + (unsigned)(pline->filter[i].id)); + if (pline->filter[i].name) { + fprintf(stream, "%*s%-*s \"%s\"\n", indent+3, "", MAX(0, fwidth-3), + "Filter name:", + pline->filter[i].name); + } else { + fprintf(stream, "%*s%-*s NONE\n", indent+3, "", MAX(0, fwidth-3), + "Filter name:"); + } + fprintf(stream, "%*s%-*s 0x%04x\n", indent+3, "", MAX(0, fwidth-3), + "Flags:", + (unsigned)(pline->filter[i].flags)); + fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth-3), + "Num CD values:", + (unsigned long)(pline->filter[i].cd_nelmts)); + for (j=0; j<pline->filter[i].cd_nelmts; j++) { + char field_name[32]; + sprintf(field_name, "CD value %d", j); + fprintf(stream, "%*s%-*s %lu\n", indent+6, "", MAX(0, fwidth-6), + field_name, + (unsigned long)(pline->filter[i].cd_values[j])); } - } else { - fprintf (stream, "%*s%-*s None\n", indent, "", fwidth, "Client Data:"); } FUNC_LEAVE(SUCCEED); |