summaryrefslogtreecommitdiffstats
path: root/src/H5Z.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Z.c')
-rw-r--r--src/H5Z.c648
1 files changed, 584 insertions, 64 deletions
diff --git a/src/H5Z.c b/src/H5Z.c
index cb96be5..b4b63fd 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -12,11 +12,17 @@
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include "H5private.h"
-#include "H5Eprivate.h"
-#include "H5MMprivate.h"
-#include "H5Oprivate.h"
-#include "H5Zprivate.h"
+#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Dataset functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
+#include "H5Zpkg.h" /* Data filters */
/* Pablo mask */
#define PABLO_MASK H5Z_mask
@@ -26,12 +32,33 @@
static int interface_initialize_g = 0;
static herr_t H5Z_init_interface (void);
+/* Local typedefs */
+#ifdef H5Z_DEBUG
+typedef struct H5Z_stats_t {
+ struct {
+ hsize_t total; /*total number of bytes processed */
+ hsize_t errors; /*bytes of total attributable to errors */
+ H5_timer_t timer; /*execution time including errors */
+ } stats[2]; /*0=output, 1=input */
+} H5Z_stats_t;
+#endif /* H5Z_DEBUG */
+
+/* Enumerated type for dataset creation prelude callbacks */
+typedef enum {
+ H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */
+ H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */
+} H5Z_prelude_type_t;
+
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
static H5Z_class_t *H5Z_table_g = NULL;
+#ifdef H5Z_DEBUG
+static H5Z_stats_t *H5Z_stat_table_g = NULL;
+#endif /* H5Z_DEBUG */
/* Local functions */
+static int H5Z_find_idx(H5Z_filter_t id);
/*-------------------------------------------------------------------------
@@ -51,22 +78,31 @@ static H5Z_class_t *H5Z_table_g = NULL;
static herr_t
H5Z_init_interface (void)
{
+ herr_t ret_value=SUCCEED; /* Return value */
+
FUNC_ENTER_NOINIT(H5Z_init_interface);
#ifdef H5_HAVE_FILTER_DEFLATE
- H5Z_register (H5Z_FILTER_DEFLATE, "deflate", H5Z_filter_deflate);
+ if (H5Z_register (H5Z_DEFLATE)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register deflate filter");
#endif /* H5_HAVE_FILTER_DEFLATE */
#ifdef H5_HAVE_FILTER_SHUFFLE
- H5Z_register (H5Z_FILTER_SHUFFLE, "shuffle", H5Z_filter_shuffle);
+ if (H5Z_register (H5Z_SHUFFLE)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register shuffle filter");
#endif /* H5_HAVE_FILTER_SHUFFLE */
#ifdef H5_HAVE_FILTER_FLETCHER32
- H5Z_register (H5Z_FILTER_FLETCHER32, "fletcher32", H5Z_filter_fletcher32);
+ if (H5Z_register (H5Z_FLETCHER32)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register fletcher32 filter");
#endif /* H5_HAVE_FILTER_FLETCHER32 */
#ifdef H5_HAVE_FILTER_SZIP
- H5Z_register (H5Z_FILTER_SZIP, "szip", H5Z_filter_szip);
+ if (H5Z_register (H5Z_SZIP)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register szip filter");
#endif /* H5_HAVE_FILTER_SZIP */
- FUNC_LEAVE_NOAPI(SUCCEED);
+#if (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP)
+done:
+#endif /* (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP) */
+ FUNC_LEAVE_NOAPI(ret_value);
}
@@ -98,7 +134,7 @@ H5Z_term_interface (void)
if (H5DEBUG(Z)) {
for (i=0; i<H5Z_table_used_g; i++) {
for (dir=0; dir<2; dir++) {
- if (0==H5Z_table_g[i].stats[dir].total) continue;
+ if (0==H5Z_stat_table_g[i].stats[dir].total) continue;
if (0==nprint++) {
/* Print column headers */
@@ -125,34 +161,35 @@ H5Z_term_interface (void)
* the word `Inf' if the elapsed time is zero.
*/
H5_bandwidth(bandwidth,
- (double)(H5Z_table_g[i].stats[dir].total),
- H5Z_table_g[i].stats[dir].timer.etime);
+ (double)(H5Z_stat_table_g[i].stats[dir].total),
+ H5Z_stat_table_g[i].stats[dir].timer.etime);
/* Print the statistics */
HDfprintf (H5DEBUG(Z),
" %s%-15s %10Hd %10Hd %8.2f %8.2f %8.2f "
"%10s\n", dir?"<":">", comment,
- H5Z_table_g[i].stats[dir].total,
- H5Z_table_g[i].stats[dir].errors,
- H5Z_table_g[i].stats[dir].timer.utime,
- H5Z_table_g[i].stats[dir].timer.stime,
- H5Z_table_g[i].stats[dir].timer.etime,
+ H5Z_stat_table_g[i].stats[dir].total,
+ H5Z_stat_table_g[i].stats[dir].errors,
+ H5Z_stat_table_g[i].stats[dir].timer.utime,
+ H5Z_stat_table_g[i].stats[dir].timer.stime,
+ H5Z_stat_table_g[i].stats[dir].timer.etime,
bandwidth);
}
}
}
-#endif
- /* Free the table */
- for (i=0; i<H5Z_table_used_g; i++) {
- H5MM_xfree(H5Z_table_g[i].name);
- }
+#endif /* H5Z_DEBUG */
+ /* Free the table of filters */
H5Z_table_g = H5MM_xfree(H5Z_table_g);
+#ifdef H5Z_DEBUG
+ H5Z_stat_table_g = H5MM_xfree(H5Z_stat_table_g);
+#endif /* H5Z_DEBUG */
H5Z_table_used_g = H5Z_table_alloc_g = 0;
interface_initialize_g = 0;
}
return 0;
}
+#ifdef H5_WANT_H5_V1_4_COMPAT
/*-------------------------------------------------------------------------
* Function: H5Zregister
@@ -166,13 +203,16 @@ H5Z_term_interface (void)
* Thursday, April 16, 1998
*
* Modifications:
+ * Changed to pass H5Z_class_t struct to H5Z_register
+ * Quincey Koziol, April 5, 2003
*
*-------------------------------------------------------------------------
*/
herr_t
H5Zregister(H5Z_filter_t id, const char *comment, H5Z_func_t func)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ H5Z_class_t cls; /* Filter class used to bundle parameters */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Zregister, FAIL);
H5TRACE3("e","Zfsx",id,comment,func);
@@ -185,13 +225,62 @@ H5Zregister(H5Z_filter_t id, const char *comment, H5Z_func_t func)
if (!func)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no function specified");
+ /* Build class structure */
+ cls.id=id;
+ cls.name=comment;
+ cls.can_apply=cls.set_local=NULL;
+ cls.filter=func;
+
+ /* Do it */
+ if (H5Z_register (&cls)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+#else /* H5_WANT_H5_V1_4_COMPAT */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Zregister
+ *
+ * Purpose: This function registers new filter.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 16, 1998
+ *
+ * Modifications:
+ * Changed to pass in H5Z_class_t struct
+ * Quincey Koziol, April 5, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Zregister(const H5Z_class_t *cls)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Zregister, FAIL);
+
+ /* Check args */
+ if (cls==NULL)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter class");
+ if (cls->id<0 || cls->id>H5Z_FILTER_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number");
+ if (cls->id<H5Z_FILTER_RESERVED)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "unable to modify predefined filters");
+ if (cls->filter==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no filter function specified");
+
/* Do it */
- if (H5Z_register (id, comment, func)<0)
+ if (H5Z_register (cls)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter");
done:
FUNC_LEAVE_API(ret_value);
}
+#endif /* H5_WANT_H5_V1_4_COMPAT */
/*-------------------------------------------------------------------------
@@ -210,42 +299,54 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_register (H5Z_filter_t id, const char *comment, H5Z_func_t func)
+H5Z_register (const H5Z_class_t *cls)
{
size_t i;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_register, FAIL);
- assert (id>=0 && id<=H5Z_FILTER_MAX);
+ assert (cls);
+ assert (cls->id>=0 && cls->id<=H5Z_FILTER_MAX);
/* Is the filter already registered? */
- for (i=0; i<H5Z_table_used_g; i++) {
- if (H5Z_table_g[i].id==id) break;
- }
+ for (i=0; i<H5Z_table_used_g; i++)
+ if (H5Z_table_g[i].id==cls->id)
+ break;
+
+ /* Filter not already registered */
if (i>=H5Z_table_used_g) {
if (H5Z_table_used_g>=H5Z_table_alloc_g) {
size_t n = MAX(H5Z_MAX_NFILTERS, 2*H5Z_table_alloc_g);
H5Z_class_t *table = H5MM_realloc(H5Z_table_g,
n*sizeof(H5Z_class_t));
+#ifdef H5Z_DEBUG
+ H5Z_stats_t *stat_table = H5MM_realloc(H5Z_stat_table_g,
+ n*sizeof(H5Z_stats_t));
+#endif /* H5Z_DEBUG */
if (!table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter table");
H5Z_table_g = table;
+#ifdef H5Z_DEBUG
+ if (!stat_table)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter statistics table");
+ H5Z_stat_table_g = stat_table;
+#endif /* H5Z_DEBUG */
H5Z_table_alloc_g = n;
- }
+ } /* end if */
/* Initialize */
i = H5Z_table_used_g++;
- HDmemset(H5Z_table_g+i, 0, sizeof(H5Z_class_t));
- H5Z_table_g[i].id = id;
- H5Z_table_g[i].name = H5MM_xstrdup(comment);
- H5Z_table_g[i].func = func;
- } else {
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+#ifdef H5Z_DEBUG
+ HDmemset(H5Z_stat_table_g+i, 0, sizeof(H5Z_stats_t));
+#endif /* H5Z_DEBUG */
+ } /* end if */
+ /* Filter already registered */
+ else {
/* Replace old contents */
- H5MM_xfree(H5Z_table_g[i].name);
- H5Z_table_g[i].name = H5MM_xstrdup(comment);
- H5Z_table_g[i].func = func;
- }
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -310,7 +411,7 @@ H5Z_unregister (H5Z_filter_t id)
size_t i; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOINIT(H5Z_unregister);
+ FUNC_ENTER_NOAPI(H5Z_unregister,FAIL);
assert (id>=0 && id<=H5Z_FILTER_MAX);
@@ -326,6 +427,9 @@ H5Z_unregister (H5Z_filter_t id)
/* Remove filter from table */
/* Don't worry about shrinking table size (for now) */
HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class_t)*((H5Z_table_used_g-1)-i));
+#ifdef H5Z_DEBUG
+ HDmemmove(&H5Z_stat_table_g[i],&H5Z_stat_table_g[i+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-i));
+#endif /* H5Z_DEBUG */
H5Z_table_used_g--;
done:
@@ -373,6 +477,295 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_prelude_callback
+ *
+ * Purpose: Makes a dataset creation "prelude" callback for the "can_apply"
+ * or "set_local" routines.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 4, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5Z_prelude_callback);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Check if the property list is non-default */
+ if(dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ H5P_genplist_t *dc_plist; /* Dataset creation property list object */
+ H5D_layout_t dcpl_layout; /* Dataset's layout information */
+
+ /* Get dataset creation property list object */
+ if (NULL == (dc_plist = H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list");
+
+ /* Get layout information */
+ if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve layout");
+
+ /* Check if the dataset is chunked */
+ if(H5D_CHUNKED == dcpl_layout) {
+ H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */
+
+ /* Get I/O pipeline information */
+ if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter");
+
+ /* Check if the chunks have filters */
+ if(dcpl_pline.nfilters > 0) {
+ int chunk_ndims; /* # of chunk dimensions */
+ hsize_t chunk_size[H5O_LAYOUT_NDIMS]; /* Size of chunk dimensions */
+ H5S_t *space; /* Dataspace describing chunk */
+ hid_t space_id; /* ID for dataspace describing chunk */
+ size_t u; /* Local index variable */
+
+ /* Get chunk information */
+ if(H5P_get(dc_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk dimensions");
+ if(H5P_get(dc_plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk size");
+
+ /* Create a data space for a chunk & set the extent */
+ if(NULL == (space = H5S_create_simple(chunk_ndims,chunk_size,NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
+
+ /* Get ID for dataspace to pass to filter routines */
+ if ((space_id=H5I_register (H5I_DATASPACE, space))<0) {
+ H5S_close(space);
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID");
+ } /* end if */
+
+ /* Iterate over filters */
+ for (u=0; u<dcpl_pline.nfilters; u++) {
+ H5Z_class_t *fclass; /* Individual filter information */
+
+ /* Get filter information */
+ if (NULL==(fclass=H5Z_find(dcpl_pline.filter[u].id))) {
+ /* Ignore errors from optional filters */
+ if (dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL)
+ H5E_clear();
+ else
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located");
+ } /* end if */
+ else {
+ /* Make correct callback */
+ switch(prelude_type) {
+ case H5Z_PRELUDE_CAN_APPLY:
+ /* Check if there is a "can apply" callback */
+ if(fclass->can_apply) {
+ /* Make callback to filter's "can apply" function */
+ herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id);
+
+ /* Check return value */
+ if(status<=0) {
+ /* We're leaving, so close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+
+ /* Indicate filter can't apply to this combination of parameters */
+ if(status==0) {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate");
+ } /* end if */
+ /* Indicate error during filter callback */
+ else {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback");
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_SET_LOCAL:
+ /* Check if there is a "set local" callback */
+ if(fclass->set_local) {
+ /* Make callback to filter's "set local" function */
+ if((fclass->set_local)(dcpl_id, type_id, space_id)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback");
+ } /* end if */
+ } /* end if */
+ break;
+
+ default:
+ assert("invalid prelude type" && 0);
+ } /* end switch */
+ } /* end else */
+ } /* end for */
+
+ /* Close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_prelude_callback() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_can_apply
+ *
+ * Purpose: Checks if all the filters defined in the dataset creation
+ * property list can be applied to a particular combination of
+ * datatype and dataspace for a dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, April 3, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_can_apply (hid_t dcpl_id, hid_t type_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_can_apply,FAIL);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Make "can apply" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_can_apply() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_set_local
+ *
+ * Purpose: Makes callbacks to modify dataset creation list property
+ * settings for filters on a new dataset, based on the datatype
+ * and dataspace of that dataset (chunk).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 4, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_set_local (hid_t dcpl_id, hid_t type_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_set_local,FAIL);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Make "set local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_set_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_modify
+ *
+ * Purpose: Modify filter parameters for specified pipeline.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_modify(H5O_pline_t *pline, H5Z_filter_t filter, unsigned flags,
+ size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
+{
+ size_t idx; /* Index of filter in pipeline */
+ size_t i; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_modify, FAIL);
+
+ assert(pline);
+ assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+ assert(0==(flags & ~((unsigned)H5Z_FLAG_DEFMASK)));
+ assert(0==cd_nelmts || cd_values);
+
+ /* Locate the filter in the pipeline */
+ for(idx=0; idx<pline->nfilters; idx++)
+ if(pline->filter[idx].id==filter)
+ break;
+
+ /* Check if the filter was not already in the pipeline */
+ if(idx>pline->nfilters)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "filter not in pipeline");
+
+ /* Change parameters for filter */
+ pline->filter[idx].flags = flags;
+ pline->filter[idx].cd_nelmts = cd_nelmts;
+
+ /* Free any existing parameters */
+ if(pline->filter[idx].cd_values!=NULL)
+ H5MM_xfree(pline->filter[idx].cd_values);
+
+ /* Set parameters */
+ if (cd_nelmts>0) {
+ pline->filter[idx].cd_values = H5MM_malloc(cd_nelmts*sizeof(unsigned));
+ if (NULL==pline->filter[idx].cd_values)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for filter parameters");
+ for (i=0; i<cd_nelmts; i++)
+ pline->filter[idx].cd_values[i] = cd_values[i];
+ } /* end if */
+ else
+ pline->filter[idx].cd_values = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_modify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_append
*
* Purpose: Append another filter to the specified pipeline.
@@ -441,38 +834,74 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_find_idx
+ *
+ * Purpose: Given a filter ID return the offset in the global array
+ * that holds all the registered filters.
+ *
+ * Return: Success: Non-negative index of entry in global filter table.
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5Z_find_idx(H5Z_filter_t id)
+{
+ size_t i; /* Local index variable */
+ int ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5Z_find_idx);
+
+ for (i=0; i<H5Z_table_used_g; i++)
+ if (H5Z_table_g[i].id == id)
+ HGOTO_DONE((int)i);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_find_idx() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_find
*
* Purpose: Given a filter ID return a pointer to a global struct that
* defines the filter.
*
* Return: Success: Ptr to entry in global filter table.
- *
* Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, August 5, 1998
*
* Modifications:
+ * Use H5Z_find_idx now
+ * Quincey Koziol, April 5, 2003
*
*-------------------------------------------------------------------------
*/
H5Z_class_t *
H5Z_find(H5Z_filter_t id)
{
- size_t i;
- H5Z_class_t *ret_value=NULL; /* Return value */
+ int idx; /* Filter index in global table */
+ H5Z_class_t *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI(H5Z_find, NULL);
- for (i=0; i<H5Z_table_used_g; i++) {
- if (H5Z_table_g[i].id == id)
- HGOTO_DONE(H5Z_table_g+i);
- }
+ /* Get the index in the global table */
+ if((idx=H5Z_find_idx(id))<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "required filter is not registered");
+
+ /* Set return value */
+ ret_value=H5Z_table_g+idx;
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5Z_find() */
/*-------------------------------------------------------------------------
@@ -504,23 +933,24 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
+H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
unsigned *filter_mask/*in,out*/, H5Z_EDC_t edc_read,
H5Z_cb_t cb_struct, size_t *nbytes/*in,out*/,
size_t *buf_size/*in,out*/, void **buf/*in,out*/)
{
size_t i, idx, new_nbytes;
- H5Z_class_t *fclass=NULL;
- unsigned failed = 0;
- unsigned tmp_flags;
+ int fclass_idx; /* Index of filter class in global table */
+ H5Z_class_t *fclass=NULL; /* Filter class pointer */
#ifdef H5Z_DEBUG
+ H5Z_stats_t *fstats=NULL; /* Filter stats pointer */
H5_timer_t timer;
#endif
+ unsigned failed = 0;
+ unsigned tmp_flags;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_pipeline, FAIL);
- assert(f);
assert(0==(flags & ~((unsigned)H5Z_FLAG_INVMASK)));
assert(filter_mask);
assert(nbytes && *nbytes>0);
@@ -536,22 +966,24 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
failed |= (unsigned)1 << idx;
continue;/*filter excluded*/
}
- if (NULL==(fclass=H5Z_find(pline->filter[idx].id))) {
+ if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
failed |= (unsigned)1 << idx;
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter is not registered");
}
+ fclass=&H5Z_table_g[fclass_idx];
#ifdef H5Z_DEBUG
+ fstats=&H5Z_stat_table_g[fclass_idx];
H5_timer_begin(&timer);
#endif
tmp_flags=flags|(pline->filter[idx].flags);
tmp_flags|=(edc_read== H5Z_DISABLE_EDC) ? H5Z_FLAG_SKIP_EDC : 0;
- new_nbytes = (fclass->func)(tmp_flags, pline->filter[idx].cd_nelmts,
+ new_nbytes = (fclass->filter)(tmp_flags, pline->filter[idx].cd_nelmts,
pline->filter[idx].cd_values, *nbytes, buf_size, buf);
#ifdef H5Z_DEBUG
- H5_timer_end(&(fclass->stats[1].timer), &timer);
- fclass->stats[1].total += MAX(*nbytes, new_nbytes);
- if (0==new_nbytes) fclass->stats[1].errors += *nbytes;
+ H5_timer_end(&(fstats->stats[1].timer), &timer);
+ fstats->stats[1].total += MAX(*nbytes, new_nbytes);
+ if (0==new_nbytes) fstats->stats[1].errors += *nbytes;
#endif
if(0==new_nbytes) {
@@ -572,7 +1004,7 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
failed |= (unsigned)1 << idx;
continue; /*filter excluded*/
}
- if (NULL==(fclass=H5Z_find(pline->filter[idx].id))) {
+ if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
failed |= (unsigned)1 << idx;
if (pline->filter[idx].flags & H5Z_FLAG_OPTIONAL) {
H5E_clear();
@@ -581,15 +1013,17 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "required filter is not registered");
}
}
+ fclass=&H5Z_table_g[fclass_idx];
#ifdef H5Z_DEBUG
+ fstats=&H5Z_stat_table_g[fclass_idx];
H5_timer_begin(&timer);
#endif
- new_nbytes = (fclass->func)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts,
+ new_nbytes = (fclass->filter)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts,
pline->filter[idx].cd_values, *nbytes, buf_size, buf);
#ifdef H5Z_DEBUG
- H5_timer_end(&(fclass->stats[0].timer), &timer);
- fclass->stats[0].total += MAX(*nbytes, new_nbytes);
- if (0==new_nbytes) fclass->stats[0].errors += *nbytes;
+ H5_timer_end(&(fstats->stats[0].timer), &timer);
+ fstats->stats[0].total += MAX(*nbytes, new_nbytes);
+ if (0==new_nbytes) fstats->stats[0].errors += *nbytes;
#endif
if(0==new_nbytes) {
if (0==(pline->filter[idx].flags & H5Z_FLAG_OPTIONAL)) {
@@ -616,3 +1050,89 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_info
+ *
+ * Purpose: Get pointer to filter info for pipeline
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Z_filter_info_t *
+H5Z_filter_info(H5O_pline_t *pline, H5Z_filter_t filter)
+{
+ size_t idx; /* Index of filter in pipeline */
+ H5Z_filter_info_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_filter_info, NULL);
+
+ assert(pline);
+ assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+
+ /* Locate the filter in the pipeline */
+ for(idx=0; idx<pline->nfilters; idx++)
+ if(pline->filter[idx].id==filter)
+ break;
+
+ /* Check if the filter was not already in the pipeline */
+ if(idx>pline->nfilters)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "filter not in pipeline");
+
+ /* Set return value */
+ ret_value=&pline->filter[idx];
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_filter_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_all_filters_avail
+ *
+ * Purpose: Verify that all the filters in a pipeline are currently
+ * available (i.e. registered)
+ *
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 8, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Z_all_filters_avail(H5O_pline_t *pline)
+{
+ size_t i,j; /* Local index variable */
+ htri_t ret_value=TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_all_filters_avail, UFAIL);
+
+ /* Check args */
+ assert(pline);
+
+ /* Iterate through all the filters in pipeline */
+ for(i=0; i<pline->nfilters; i++) {
+
+ /* Look for each filter in the list of registered filters */
+ for(j=0; j<H5Z_table_used_g; j++)
+ if(H5Z_table_g[j].id==pline->filter[i].id)
+ break;
+
+ /* Check if we didn't find the filter */
+ if(j==H5Z_table_used_g)
+ HGOTO_DONE(FALSE);
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_all_filters_avail() */
+