summaryrefslogtreecommitdiffstats
path: root/src/H5Pdxpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Pdxpl.c')
-rw-r--r--src/H5Pdxpl.c287
1 files changed, 278 insertions, 9 deletions
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 70fc982..46dc94c 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -68,7 +68,7 @@
#define H5D_XFER_BTREE_SPLIT_RATIO_SIZE sizeof(double[3])
#define H5D_XFER_BTREE_SPLIT_RATIO_DEF \
{ \
- 0.1f, 0.5f, 0.9f \
+ 0.1, 0.5, 0.9 \
}
#define H5D_XFER_BTREE_SPLIT_RATIO_ENC H5P__dxfr_btree_split_ratio_enc
#define H5D_XFER_BTREE_SPLIT_RATIO_DEC H5P__dxfr_btree_split_ratio_dec
@@ -159,6 +159,16 @@
#define H5D_XFER_XFORM_COPY H5P__dxfr_xform_copy
#define H5D_XFER_XFORM_CMP H5P__dxfr_xform_cmp
#define H5D_XFER_XFORM_CLOSE H5P__dxfr_xform_close
+/* Definitions for dataset I/O selection property */
+#define H5D_XFER_DSET_IO_SEL_SIZE sizeof(H5S_t *)
+#define H5D_XFER_DSET_IO_SEL_DEF NULL
+#define H5D_XFER_DSET_IO_SEL_COPY H5P__dxfr_dset_io_hyp_sel_copy
+#define H5D_XFER_DSET_IO_SEL_CMP H5P__dxfr_dset_io_hyp_sel_cmp
+#define H5D_XFER_DSET_IO_SEL_CLOSE H5P__dxfr_dset_io_hyp_sel_close
+#ifdef QAK
+#define H5D_XFER_DSET_IO_SEL_ENC H5P__dxfr_edc_enc
+#define H5D_XFER_DSET_IO_SEL_DEC H5P__dxfr_edc_dec
+#endif /* QAK */
/******************/
/* Local Typedefs */
@@ -196,6 +206,9 @@ static herr_t H5P__dxfr_xform_del(hid_t prop_id, const char *name, size_t size,
static herr_t H5P__dxfr_xform_copy(const char *name, size_t size, void *value);
static int H5P__dxfr_xform_cmp(const void *value1, const void *value2, size_t size);
static herr_t H5P__dxfr_xform_close(const char *name, size_t size, void *value);
+static herr_t H5P__dxfr_dset_io_hyp_sel_copy(const char *name, size_t size, void *value);
+static int H5P__dxfr_dset_io_hyp_sel_cmp(const void *value1, const void *value2, size_t size);
+static herr_t H5P__dxfr_dset_io_hyp_sel_close(const char *name, size_t size, void *value);
/*********************/
/* Package Variables */
@@ -262,7 +275,9 @@ static const H5Z_EDC_t H5D_def_enable_edc_g = H5D_XFER_EDC_DEF; /* Default
static const H5Z_cb_t H5D_def_filter_cb_g = H5D_XFER_FILTER_CB_DEF; /* Default value for filter callback */
static const H5T_conv_cb_t H5D_def_conv_cb_g =
H5D_XFER_CONV_CB_DEF; /* Default value for datatype conversion callback */
-static const void *H5D_def_xfer_xform_g = H5D_XFER_XFORM_DEF; /* Default value for data transform */
+static const void * H5D_def_xfer_xform_g = H5D_XFER_XFORM_DEF; /* Default value for data transform */
+static const H5S_t *H5D_def_dset_io_sel_g =
+ H5D_XFER_DSET_IO_SEL_DEF; /* Default value for dataset I/O selection */
/*-------------------------------------------------------------------------
* Function: H5P__dxfr_reg_prop
@@ -420,6 +435,13 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
H5D_XFER_XFORM_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the dataset I/O selection property */
+ if (H5P__register_real(pclass, H5D_XFER_DSET_IO_SEL_NAME, H5D_XFER_DSET_IO_SEL_SIZE,
+ &H5D_def_dset_io_sel_g, NULL, NULL, NULL, NULL, NULL, NULL,
+ H5D_XFER_DSET_IO_SEL_COPY, H5D_XFER_DSET_IO_SEL_CMP,
+ H5D_XFER_DSET_IO_SEL_CLOSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dxfr_reg_prop() */
@@ -894,7 +916,7 @@ H5P__dxfr_xform_cmp(const void *_xform1, const void *_xform2, size_t H5_ATTR_UNU
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P__dxfr_xform_copy() */
+} /* end H5P__dxfr_xform_cmp() */
/*-------------------------------------------------------------------------
* Function: H5P__dxfr_xform_close
@@ -965,7 +987,7 @@ H5Pset_data_transform(hid_t plist_id, const char *expression)
/* Create data transform info from expression */
if (NULL == (data_xform_prop = H5Z_xform_create(expression)))
- HGOTO_ERROR(H5E_PLINE, H5E_NOSPACE, FAIL, "unable to create data transform info")
+ HGOTO_ERROR(H5E_PLIST, H5E_NOSPACE, FAIL, "unable to create data transform info")
/* Update property list (takes ownership of transform) */
if (H5P_poke(plist, H5D_XFER_XFORM_NAME, &data_xform_prop) < 0)
@@ -974,7 +996,7 @@ H5Pset_data_transform(hid_t plist_id, const char *expression)
done:
if (ret_value < 0)
if (data_xform_prop && H5Z_xform_destroy(data_xform_prop) < 0)
- HDONE_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "unable to release data transform expression")
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release data transform expression")
FUNC_LEAVE_API(ret_value)
} /* end H5Pset_data_transform() */
@@ -1030,7 +1052,7 @@ H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size)
/* Copy into application buffer */
len = HDstrlen(pexp);
if (expression) {
- HDstrncpy(expression, pexp, MIN(len + 1, size));
+ HDstrncpy(expression, pexp, size);
if (len >= size)
expression[size - 1] = '\0';
} /* end if */
@@ -1486,9 +1508,8 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right)
H5TRACE4("e", "iddd", plist_id, left, middle, right);
/* Check arguments */
- if (left < (double)0.0f || left > (double)1.0f || middle < (double)0.0f || middle > (double)1.0f ||
- right < (double)0.0f || right > (double)1.0f)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0<=X<=1.0")
+ if (left < 0.0 || left > 1.0 || middle < 0.0 || middle > 1.0 || right < 0.0 || right > 1.0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0 <= X <= 1.0")
/* Get the plist structure */
if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER)))
@@ -2110,3 +2131,251 @@ H5P__dxfr_edc_dec(const void **_pp, void *_value)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__dxfr_edc_dec() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__dxfr_dset_io_hyp_sel_copy
+ *
+ * Purpose: Creates a copy of the dataset I/O selection.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, January 31, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dxfr_dset_io_hyp_sel_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
+{
+ H5S_t *orig_space = *(H5S_t **)value; /* Original dataspace for property */
+ H5S_t *new_space = NULL; /* New dataspace for property */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* If there's a dataspace I/O selection set, copy it */
+ if (orig_space) {
+ /* Make copy of dataspace */
+ if (NULL == (new_space = H5S_copy(orig_space, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "error copying the dataset I/O selection")
+
+ /* Set new value for property */
+ *(void **)value = new_space;
+ } /* end if */
+
+done:
+ /* Cleanup on error */
+ if (ret_value < 0)
+ if (new_space && H5S_close(new_space) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "error closing dataset I/O selection dataspace")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dxfr_dset_io_hyp_sel_copy() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__dxfr_dset_io_hyp_sel_cmp
+ *
+ * Purpose: Compare two dataset I/O selections.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if VALUE2 is
+ * greater than VALUE1 and zero if VALUE1 and VALUE2 are equal.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, January 31, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P__dxfr_dset_io_hyp_sel_cmp(const void *_space1, const void *_space2, size_t H5_ATTR_UNUSED size)
+{
+ const H5S_t *const *space1 = (const H5S_t *const *)_space1; /* Create local aliases for values */
+ const H5S_t *const *space2 = (const H5S_t *const *)_space2; /* Create local aliases for values */
+ herr_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(space1);
+ HDassert(space1);
+ HDassert(size == sizeof(H5S_t *));
+
+ /* Check for a property being set */
+ if (*space1 == NULL && *space2 != NULL)
+ HGOTO_DONE(-1);
+ if (*space1 != NULL && *space2 == NULL)
+ HGOTO_DONE(1);
+
+ if (*space1) {
+ HDassert(*space2);
+
+ /* Compare the extents of the dataspaces */
+ /* (Error & not-equal count the same) */
+ if (TRUE != H5S_extent_equal(*space1, *space2))
+ HGOTO_DONE(-1);
+
+ /* Compare the selection "shape" of the dataspaces */
+ /* (Error & not-equal count the same) */
+ if (TRUE != H5S_select_shape_same(*space1, *space2))
+ HGOTO_DONE(-1);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dxfr_dset_io_hyp_sel_cmp() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__dxfr_dset_io_hyp_sel_close
+ *
+ * Purpose: Frees resources for dataset I/O selection
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, January 31, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dxfr_dset_io_hyp_sel_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *_value)
+{
+ H5S_t *space = *(H5S_t **)_value; /* Dataspace for property */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Release any dataspace */
+ if (space && H5S_close(space) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "error closing dataset I/O selection dataspace")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dxfr_dset_io_hyp_sel_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dataset_io_hyperslab_selection
+ *
+ * Purpose: H5Pset_dataset_io_hyperslab_selection() is designed to be used
+ * in conjunction with using H5S_PLIST for the file dataspace
+ * ID when making a call to H5Dread() or H5Dwrite(). When used
+ * with H5S_PLIST, the selection created by one or more calls to
+ * this routine is used for determining which dataset elements to
+ * access.
+ *
+ * 'rank' is the dimensionality of the selection and determines
+ * the size of the 'start', 'stride', 'count', and 'block' arrays.
+ * 'rank' must be between 1 and H5S_MAX_RANK, inclusive.
+ *
+ * The 'op', 'start', 'stride', 'count', and 'block' parameters
+ * behave identically to their behavior for H5Sselect_hyperslab(),
+ * please see the documentation for that routine for details about
+ * their use.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, January 30, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, const hsize_t start[],
+ const hsize_t stride[], const hsize_t count[], const hsize_t block[])
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ H5S_t * space; /* Dataspace to hold selection */
+ hbool_t space_created = FALSE; /* Whether a new dataspace has been created */
+ hbool_t reset_prop_on_error = FALSE; /* Whether to reset the property on failure */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "iIuSs*h*h*h*h", plist_id, rank, op, start, stride, count, block);
+
+ /* Check arguments */
+ if (rank < 1 || rank > H5S_MAX_RANK)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank value: %u", rank)
+ if (!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID))
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ if (start == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "'count' pointer is NULL")
+ if (stride != NULL) {
+ unsigned u; /* Local index variable */
+
+ /* Check for 0-sized strides */
+ for (u = 0; u < rank; u++)
+ if (stride[u] == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value - stride[%u]==0", u)
+ } /* end if */
+ if (count == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "'start' pointer is NULL")
+ /* block is allowed to be NULL, and will be assumed to be all '1's when NULL */
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID")
+
+ /* See if a dataset I/O selection is already set, and free it if it is */
+ if (H5P_peek(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting dataset I/O selection")
+
+ /* Check for operation on existing dataspace selection */
+ if (NULL != space) {
+ int sndims; /* Rank of existing dataspace */
+
+ /* Get dimensions from current dataspace for selection */
+ if ((sndims = H5S_GET_EXTENT_NDIMS(space)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection's dataspace rank")
+
+ /* Check for different # of dimensions */
+ if ((unsigned)sndims != rank) {
+ /* Set up new dataspace for 'set' operation, otherwise fail */
+ if (op == H5S_SELECT_SET) {
+ /* Close previous dataspace */
+ if (H5S_close(space) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
+
+ /* Reset 'space' pointer, so it's re-created */
+ space = NULL;
+
+ /* Set flag to reset property list on error */
+ reset_prop_on_error = TRUE;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "different rank for previous and new selections")
+ } /* end if */
+ } /* end if */
+
+ /* Check for first time called */
+ if (NULL == space) {
+ hsize_t dims[H5S_MAX_RANK]; /* Dimensions for new dataspace */
+ unsigned u; /* Local index variable */
+
+ /* Initialize dimensions to largest possible actual size */
+ for (u = 0; u < rank; u++)
+ dims[u] = (H5S_UNLIMITED - 1);
+
+ /* Create dataspace of the correct dimensionality, with maximum dimensions */
+ if (NULL == (space = H5S_create_simple(rank, dims, NULL)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create dataspace for selection")
+ space_created = TRUE;
+ } /* end if */
+
+ /* Set selection for dataspace */
+ if (H5S_select_hyperslab(space, op, start, stride, count, block) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSELECT, FAIL, "can't create selection")
+
+ /* Update property list (takes ownership of dataspace, if new) */
+ if (H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection")
+ space_created = FALSE; /* Reset now that property owns the dataspace */
+
+done:
+ /* Cleanup on failure */
+ if (ret_value < 0) {
+ if (reset_prop_on_error && plist && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection")
+ if (space_created && H5S_close(space) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dataset_io_hyperslab_selection() */