summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Dchunk.c67
-rw-r--r--src/H5Dprivate.h11
-rw-r--r--src/H5Oattribute.c45
-rw-r--r--src/H5Pdxpl.c278
-rw-r--r--src/H5S.c51
-rw-r--r--src/H5Sprivate.h1
-rw-r--r--src/H5Spublic.h8
-rw-r--r--src/H5VLnative_dataset.c154
-rw-r--r--src/H5private.h13
-rw-r--r--src/H5system.c6
10 files changed, 465 insertions, 169 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index d6eb715..5fc7abb 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -604,8 +604,6 @@ H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage
HDassert(offset);
HDassert(storage_size);
- *storage_size = 0;
-
/* Allocate dataspace and initialize it if it hasn't been. */
if (!(*layout->ops->is_space_alloc)(&layout->storage))
HGOTO_DONE(SUCCEED)
@@ -5031,7 +5029,7 @@ H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info,
* order of offset in the file.
*/
if (need_addr_sort)
- HDqsort(chunk_disp_array, blocks, sizeof(MPI_Aint), H5D__chunk_cmp_addr);
+ HDqsort(chunk_disp_array, (size_t)blocks, sizeof(MPI_Aint), H5D__chunk_cmp_addr);
/* MSC - should use this if MPI_type_create_hindexed block is working:
* mpi_code = MPI_Type_create_hindexed_block(blocks, block_len, chunk_disp_array, MPI_BYTE,
@@ -6066,6 +6064,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
if (udata->chunk_in_cache) {
HDassert(H5F_addr_defined(chunk_rec->chunk_addr));
+ HDassert(ent);
HDassert(H5F_addr_defined(ent->chunk_block.offset));
H5_CHECKED_ASSIGN(nbytes, size_t, shared_fo->layout.u.chunk.size, uint32_t);
@@ -7499,6 +7498,36 @@ done:
} /* end H5D__get_chunk_info_by_coord() */
/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_iter_cb
+ *
+ * Purpose: Call the user-defined function with the chunk data. The iterator continues if
+ * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is
+ * returned.
+ *
+ * Return: Success: H5_ITER_CONT or H5_ITER_STOP
+ * Failure: Negative (H5_ITER_ERROR)
+ *
+ * Programmer: Gaute Hope
+ * August 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata)
+{
+ int ret_value = 0;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata;
+
+ ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr,
+ chunk_rec->nbytes, data->op_data);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__chunk_iter_cb */
+
+/*-------------------------------------------------------------------------
* Function: H5D__chunk_iter
*
* Purpose: Iterate over all the chunks in the dataset with given callbak.
@@ -7537,7 +7566,7 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data)
for (ent = rdcc->head; ent; ent = ent->next)
/* Flush the chunk out to disk, to make certain the size is correct later */
if (H5D__chunk_flush_entry(dset, ent, FALSE) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "cannot flush indexed storage buffer")
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
@@ -7559,33 +7588,3 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data)
done:
FUNC_LEAVE_NOAPI_TAG(ret_value)
} /* end H5D__chunk_iter() */
-
-/*-------------------------------------------------------------------------
- * Function: H5D__chunk_iter_cb
- *
- * Purpose: Call the user-defined function with the chunk data. The iterator continues if
- * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is
- * returned.
- *
- * Return: Success: H5_ITER_CONT or H5_ITER_STOP
- * Failure: Negative (H5_ITER_ERROR)
- *
- * Programmer: Gaute Hope
- * August 2020
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata)
-{
- int ret_value = 0;
-
- FUNC_ENTER_STATIC_NOERR
-
- const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata;
-
- ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr,
- chunk_rec->nbytes, data->op_data);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__chunk_iter_cb */
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index f9ef772..ad9794d 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -79,11 +79,12 @@
#define H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME \
"local_no_collective_cause" /* cause of broken collective I/O in each process */
#define H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME \
- "global_no_collective_cause" /* cause of broken collective I/O in all processes */
-#define H5D_XFER_EDC_NAME "err_detect" /* EDC */
-#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */
-#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */
-#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */
+ "global_no_collective_cause" /* cause of broken collective I/O in all processes */
+#define H5D_XFER_EDC_NAME "err_detect" /* EDC */
+#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */
+#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */
+#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */
+#define H5D_XFER_DSET_IO_SEL_NAME "dset_io_selection" /* Dataset I/O selection */
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
/* Collective chunk instrumentation properties */
#define H5D_XFER_COLL_CHUNK_LINK_HARD_NAME "coll_chunk_link_hard"
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 0fc4cc6..56f7145 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -1901,48 +1901,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O__attr_bh_info() */
-
-#ifndef H5_NO_DEPRECATED_SYMBOLS
-
-/*-------------------------------------------------------------------------
- * Function: H5O__attr_count
- *
- * Purpose: Determine the # of attributes on an object
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Quincey Koziol
- * Monday, December 11, 2006
- *
- *-------------------------------------------------------------------------
- */
-int
-H5O__attr_count(const H5O_loc_t *loc)
-{
- H5O_t * oh = NULL; /* Pointer to actual object header */
- hsize_t nattrs; /* Number of attributes */
- int ret_value = -1; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
- /* Check arguments */
- HDassert(loc);
-
- /* Protect the object header to iterate over */
- if (NULL == (oh = H5O_protect(loc, H5AC__READ_ONLY_FLAG, FALSE)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header")
-
- /* Retrieve # of attributes on object */
- if (H5O__attr_count_real(loc->file, oh, &nattrs) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count")
-
- /* Set return value */
- ret_value = (int)nattrs;
-
-done:
- if (oh && H5O_unprotect(loc, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O__attr_count */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index de67dfd..046b046 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -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() */
@@ -2109,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; /* 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 && 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() */
diff --git a/src/H5S.c b/src/H5S.c
index 747d297..13d32cf 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -84,7 +84,7 @@ H5FL_ARR_DEFINE(hsize_t, H5S_MAX_RANK);
static const H5I_class_t H5I_DATASPACE_CLS[1] = {{
H5I_DATASPACE, /* ID class value */
0, /* Class flags */
- 2, /* # of reserved IDs for class */
+ 3, /* # of reserved IDs for class */
(H5I_free_t)H5S__close_cb /* Callback routine for closing objects of this class */
}};
@@ -277,55 +277,6 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S_get_validiated_dataspace
- PURPOSE
- Get a pointer to a validated H5S_t pointer
- USAGE
- H5S_t *H5S_get_validated_space(dataspace_id, space)
- hid_t space_id; IN: The ID of the dataspace
- const H5S_t * space; OUT: A pointer to the dataspace
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- Gets a pointer to a dataspace struct after validating it. The pointer
- can be NULL (if the ID is H5S_ALL, for example).
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5S_get_validated_dataspace(hid_t space_id, const H5S_t **space)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
-
- HDassert(space);
-
- /* Check for invalid ID */
- if (space_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid space_id (ID cannot be a negative number)")
-
- /* No special dataspace struct for H5S_ALL */
- if (H5S_ALL == space_id)
- *space = NULL;
- else {
- /* Get the dataspace pointer */
- if (NULL == (*space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "space_id is not a dataspace ID")
-
- /* Check for valid selection */
- if (H5S_SELECT_VALID(*space) != TRUE)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection + offset not within extent")
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_get_validated_dataspace() */
-
-/*--------------------------------------------------------------------------
- NAME
H5S_create
PURPOSE
Create empty, typed dataspace
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 56c1646..51a98a6 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -217,7 +217,6 @@ H5_DLL htri_t H5S_set_extent(H5S_t *space, const hsize_t *size);
H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size);
H5_DLL herr_t H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, const hsize_t *max);
H5_DLL H5S_t *H5S_create(H5S_class_t type);
-H5_DLL herr_t H5S_get_validated_dataspace(hid_t space_id, const H5S_t **space /*out*/);
H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], const hsize_t maxdims[/*rank*/]);
H5_DLL herr_t H5S_set_version(H5F_t *f, H5S_t *ds);
H5_DLL herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc);
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index c2c0aef..7962035 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -21,8 +21,12 @@
#include "H5public.h"
#include "H5Ipublic.h"
-/* Define atomic datatypes */
-#define H5S_ALL 0 /* (hid_t) */
+/* Define special dataspaces for dataset I/O operations */
+#define H5S_ALL 0 /* (hid_t) */
+#define H5S_BLOCK 1 /* (hid_t) */
+#define H5S_PLIST 2 /* (hid_t) */
+
+/* Define value for 'unlimited' dimensions */
#define H5S_UNLIMITED HSIZE_UNDEF
/* Define user-level maximum number of dimensions */
diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c
index 978ecb3..3a7f105 100644
--- a/src/H5VLnative_dataset.c
+++ b/src/H5VLnative_dataset.c
@@ -49,6 +49,10 @@
/* Local Prototypes */
/********************/
+/* Helper routines for read/write API calls */
+static herr_t H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id,
+ hid_t mem_space_id, H5S_t **file_space, H5S_t **mem_space);
+
/*********************/
/* Package Variables */
/*********************/
@@ -62,6 +66,100 @@
/*******************/
/*-------------------------------------------------------------------------
+ * Function: H5VL__native_dataset_io_setup
+ *
+ * Purpose: Set up file and memory dataspaces for dataset I/O operation
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id, hid_t mem_space_id,
+ H5S_t **file_space, H5S_t **mem_space)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(dset);
+ HDassert(file_space && NULL == *file_space);
+ HDassert(mem_space && NULL == *mem_space);
+
+ /* Set up file dataspace */
+ if (H5S_ALL == file_space_id)
+ /* Use dataspace for dataset */
+ *file_space = dset->shared->space;
+ else if (H5S_BLOCK == file_space_id)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_BLOCK is not allowed for file dataspace")
+ else if (H5S_PLIST == file_space_id) {
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5S_t * space; /* Dataspace to hold selection */
+
+ /* Get the plist structure */
+ if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADID, FAIL, "bad dataset transfer property list")
+
+ /* 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_DATASET, H5E_CANTGET, FAIL, "error getting dataset I/O selection")
+
+ /* Use dataspace for dataset */
+ *file_space = dset->shared->space;
+
+ /* Copy, but share, selection from property list to dataset's dataspace */
+ if (H5S_SELECT_COPY(*file_space, space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataset I/O selection")
+ } /* end else-if */
+ else {
+ /* Get the dataspace pointer */
+ if (NULL == (*file_space = (H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "file_space_id is not a dataspace ID")
+ } /* end else */
+
+ /* Get dataspace for memory buffer */
+ if (H5S_ALL == mem_space_id)
+ *mem_space = *file_space;
+ else if (H5S_BLOCK == mem_space_id) {
+ hsize_t nelmts; /* # of selected elements in file */
+
+ /* Get the # of elements selected */
+ nelmts = H5S_GET_SELECT_NPOINTS(*file_space);
+
+ /* Check for any elements */
+ if (nelmts > 0) {
+ /* Create a 1-D dataspace of the same # of elements */
+ if (NULL == (*mem_space = H5S_create_simple(1, &nelmts, NULL)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create simple memory dataspace")
+ } /* end if */
+ else {
+ /* Create a NULL dataspace of the same # of elements */
+ if (NULL == (*mem_space = H5S_create(H5S_NULL)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create NULL memory dataspace")
+ } /* end else */
+ } /* end if */
+ else if (H5S_PLIST == mem_space_id)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_PLIST is not allowed for memory dataspace")
+ else {
+ /* Get the dataspace pointer */
+ if (NULL == (*mem_space = (H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "mem_space_id is not a dataspace ID")
+ } /* end else */
+
+ /* Check for valid selections */
+ if (H5S_SELECT_VALID(*file_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
+ "selection + offset not within extent for file dataspace")
+ if (H5S_SELECT_VALID(*mem_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
+ "selection + offset not within extent for memory dataspace")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__native_dataset_io_setup() */
+
+/*-------------------------------------------------------------------------
* Function: H5VL__native_dataset_create
*
* Purpose: Handles the dataset create callback
@@ -172,10 +270,10 @@ herr_t
H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
hid_t dxpl_id, void *buf, void H5_ATTR_UNUSED **req)
{
- H5D_t * dset = (H5D_t *)obj;
- const H5S_t *mem_space = NULL;
- const H5S_t *file_space = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_t *dset = (H5D_t *)obj;
+ H5S_t *mem_space = NULL;
+ H5S_t *file_space = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -183,11 +281,10 @@ H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_
if (NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file")
- /* Get validated dataspace pointers */
- if (H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id")
- if (H5S_get_validated_dataspace(file_space_id, &file_space) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id")
+ /* Get file & memory dataspaces */
+ if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces")
/* Set DXPL for operation */
H5CX_set_dxpl(dxpl_id);
@@ -197,6 +294,17 @@ H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
done:
+ /* Clean up */
+ if (H5S_BLOCK == mem_space_id && mem_space) {
+ if (H5S_close(mem_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
+ "unable to release temporary memory dataspace for H5S_BLOCK")
+ } /* end if */
+ else if (H5S_PLIST == file_space_id && file_space)
+ if (H5S_select_all(file_space, TRUE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
+ "unable to release file dataspace selection for H5S_PLIST")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL__native_dataset_read() */
@@ -213,10 +321,10 @@ herr_t
H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
hid_t dxpl_id, const void *buf, void H5_ATTR_UNUSED **req)
{
- H5D_t * dset = (H5D_t *)obj;
- const H5S_t *mem_space = NULL;
- const H5S_t *file_space = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_t *dset = (H5D_t *)obj;
+ H5S_t *mem_space = NULL;
+ H5S_t *file_space = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -224,11 +332,10 @@ H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid
if (NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file")
- /* Get validated dataspace pointers */
- if (H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id")
- if (H5S_get_validated_dataspace(file_space_id, &file_space) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id")
+ /* Get file & memory dataspaces */
+ if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces")
/* Set DXPL for operation */
H5CX_set_dxpl(dxpl_id);
@@ -238,6 +345,17 @@ H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
done:
+ /* Clean up */
+ if (H5S_BLOCK == mem_space_id && mem_space) {
+ if (H5S_close(mem_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
+ "unable to release temporary memory dataspace for H5S_BLOCK")
+ } /* end if */
+ else if (H5S_PLIST == file_space_id && file_space)
+ if (H5S_select_all(file_space, TRUE) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
+ "unable to release file dataspace selection for H5S_PLIST")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL__native_dataset_write() */
diff --git a/src/H5private.h b/src/H5private.h
index 0e2cdec..bb416ef 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -113,22 +113,21 @@
#define H5_DEFAULT_VOL H5VL_NATIVE
#ifdef H5_HAVE_WIN32_API
+
/* The following two defines must be before any windows headers are included */
#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
#define NOGDI /* Exclude Graphic Display Interface macros */
-#ifdef H5_HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
+#include <windows.h>
+
+#include <direct.h> /* For _getcwd() */
+#include <io.h> /* POSIX I/O */
+#include <winsock2.h> /* For GetUserName() */
#ifdef H5_HAVE_THREADSAFE
#include <process.h> /* For _beginthread() */
#endif
-#include <windows.h>
-#include <direct.h> /* For _getcwd() */
-#include <io.h> /* POSIX I/O */
-
#endif /*H5_HAVE_WIN32_API*/
#ifndef F_OK
diff --git a/src/H5system.c b/src/H5system.c
index dcb77dd..adfb758 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -365,7 +365,7 @@ Wsetenv(const char *name, const char *value, int overwrite)
return (int)_putenv_s(name, value);
} /* end Wsetenv() */
-#ifdef H5_HAVE_WINSOCK2_H
+#ifdef H5_HAVE_WIN32_API
#pragma comment(lib, "advapi32.lib")
#endif
@@ -450,12 +450,12 @@ char *
Wgetlogin(void)
{
-#ifdef H5_HAVE_WINSOCK2_H
+#ifdef H5_HAVE_WIN32_API
DWORD bufferCount = WloginBuffer_count;
if (GetUserName(Wlogin_buffer, &bufferCount) != 0)
return (Wlogin_buffer);
else
-#endif /* H5_HAVE_WINSOCK2_H */
+#endif
return NULL;
}