summaryrefslogtreecommitdiffstats
path: root/src/H5Sselect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Sselect.c')
-rw-r--r--src/H5Sselect.c2400
1 files changed, 1784 insertions, 616 deletions
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 91aed1e..c2fb7fa 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -1,46 +1,81 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
- * Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
- * the files COPYING and Copyright.html. COPYING can be found at the root *
- * of the source code distribution tree; Copyright.html can be found at the *
- * root level of an installed copy of the electronic HDF5 document set and *
- * is linked from the top-level documents page. It can also be found at *
- * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
- * access to either file, you may request a copy from help@hdfgroup.org. *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.ued>
+/* Programmer: Quincey Koziol
* Friday, May 29, 1998
*
* Purpose: Dataspace selection functions.
*/
-#define H5S_PACKAGE /*suppress error about including H5Spkg */
+/****************/
+/* Module Setup */
+/****************/
+#include "H5Smodule.h" /* This source code file is part of the H5S module */
-#include "H5private.h" /* Generic Functions */
-#include "H5Dprivate.h" /* Datasets */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* IDs */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5Spkg.h" /* Dataspaces */
-#include "H5Vprivate.h" /* Vector and array functions */
-#include "H5WBprivate.h" /* Wrapped Buffers */
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Spkg.h" /* Dataspaces */
+#include "H5VMprivate.h" /* Vector and array functions */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* All the valid public flags to H5Ssel_iter_create() */
+#define H5S_SEL_ITER_ALL_PUBLIC_FLAGS (H5S_SEL_ITER_GET_SEQ_LIST_SORTED | H5S_SEL_ITER_SHARE_WITH_DATASPACE)
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Local Prototypes */
+/********************/
-/* Local functions */
#ifdef LATER
-static herr_t H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);
-static htri_t H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter);
-static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
+static herr_t H5S__select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);
+static htri_t H5S__select_iter_has_next_block(const H5S_sel_iter_t *iter);
+static herr_t H5S__select_iter_next_block(H5S_sel_iter_t *iter);
#endif /* LATER */
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Declare a free list to manage the H5S_sel_iter_t struct */
+H5FL_DEFINE(H5S_sel_iter_t);
+
+/* Declare extern free list to manage sequences of size_t */
+H5FL_SEQ_EXTERN(size_t);
+
+/* Declare extern free list to manage sequences of hsize_t */
+H5FL_SEQ_EXTERN(hsize_t);
+
+/*******************/
+/* Local Variables */
+/*******************/
-
/*--------------------------------------------------------------------------
NAME
H5S_select_offset
@@ -67,28 +102,115 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset)
/* Check args */
HDassert(space);
- HDassert(space->extent.rank);
+ HDassert(0 < space->extent.rank && space->extent.rank <= H5S_MAX_RANK);
HDassert(offset);
/* Copy the offset over */
- HDmemcpy(space->select.offset, offset, sizeof(hssize_t)*space->extent.rank);
+ H5MM_memcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank);
/* Indicate that the offset was changed */
space->select.offset_changed = TRUE;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5S_select_offset() */
+} /* end H5S_select_offset() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Soffset_simple
+ PURPOSE
+ Changes the offset of a selection within a simple dataspace extent
+ USAGE
+ herr_t H5Soffset_simple(space_id, offset)
+ hid_t space_id; IN: Dataspace object to reset
+ const hssize_t *offset; IN: Offset to position the selection at
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function creates an offset for the selection within an extent, allowing
+ the same shaped selection to be moved to different locations within a
+ dataspace without requiring it to be re-defined.
+--------------------------------------------------------------------------*/
+herr_t
+H5Soffset_simple(hid_t space_id, const hssize_t *offset)
+{
+ H5S_t *space; /* Dataspace to modify */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Hs", space_id, offset);
+
+ /* Check args */
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "not a dataspace")
+ if (space->extent.rank == 0 ||
+ (H5S_GET_EXTENT_TYPE(space) == H5S_SCALAR || H5S_GET_EXTENT_TYPE(space) == H5S_NULL))
+ HGOTO_ERROR(H5E_ID, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace")
+ if (offset == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no offset specified")
+
+ /* Set the selection offset */
+ if (H5S_select_offset(space, offset) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Soffset_simple() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_copy
+ PURPOSE
+ Copy a selection from one dataspace to another
+ USAGE
+ herr_t H5Sselect_copy(dst, src)
+ hid_t dst; OUT: ID of the destination dataspace
+ hid_t src; IN: ID of the source dataspace
+
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Copies all the selection information (including offset) from the source
+ dataspace to the destination dataspace.
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Sselect_copy(hid_t dst_id, hid_t src_id)
+{
+ H5S_t *src;
+ H5S_t *dst;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", dst_id, src_id);
+
+ /* Check args */
+ if (NULL == (src = (H5S_t *)H5I_object_verify(src_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == (dst = (H5S_t *)H5I_object_verify(dst_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Copy */
+ if (H5S_select_copy(dst, src, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_copy() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_copy
PURPOSE
Copy a selection from one dataspace to another
USAGE
- herr_t H5S_select_copy(dst, src)
+ herr_t H5S_select_copy(dst, src, share_selection)
H5S_t *dst; OUT: Pointer to the destination dataspace
H5S_t *src; IN: Pointer to the source dataspace
+ hbool_t; IN: Whether to share the selection between the dataspaces
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -105,28 +227,31 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
+H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Check args */
- assert(dst);
- assert(src);
+ HDassert(dst);
+ HDassert(src);
+
+ /* Release the current selection */
+ if (H5S_SELECT_RELEASE(dst) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection")
/* Copy regular fields */
- dst->select=src->select;
+ dst->select = src->select;
/* Perform correct type of copy based on the type of selection */
- if((ret_value=(*src->select.type->copy)(dst,src,share_selection))<0)
+ if ((ret_value = (*src->select.type->copy)(dst, src, share_selection)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_copy() */
+} /* end H5S_select_copy() */
-
/*-------------------------------------------------------------------------
* Function: H5S_select_release
*
@@ -141,63 +266,25 @@ done:
* pattern, don't call it directly, use the appropriate macro
* defined in H5Sprivate.h.
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5S_select_release(H5S_t *ds)
{
- herr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_NOAPI_NOINIT
- assert(ds);
+ HDassert(ds);
/* Call the selection type's release function */
- ret_value=(*ds->select.type->release)(ds);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_release() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5S_select_get_seq_list
- *
- * Purpose: Retrieves the next sequence of offset/length pairs for an
- * iterator on a dataspace
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, May 18, 2004
- *
- * Note: This routine participates in the "Inlining C function pointers"
- * pattern, don't call it directly, use the appropriate macro
- * defined in H5Sprivate.h.
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
- H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
- size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len)
-{
- herr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- HDassert(space);
-
- /* Call the selection type's get_seq_list function */
- ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len);
+ if ((ds->select.type) && ((ret_value = (*ds->select.type->release)(ds)) < 0))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection")
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_get_seq_list() */
+} /* end H5S_select_release() */
-
/*-------------------------------------------------------------------------
* Function: H5S_select_serial_size
*
@@ -213,35 +300,34 @@ H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
* pattern, don't call it directly, use the appropriate macro
* defined in H5Sprivate.h.
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
hssize_t
-H5S_select_serial_size(const H5S_t *space)
+H5S_select_serial_size(H5S_t *space)
{
- hssize_t ret_value; /* Return value */
+ hssize_t ret_value = -1; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- assert(space);
+ HDassert(space);
/* Call the selection type's serial_size function */
- ret_value=(*space->select.type->serial_size)(space);
+ ret_value = (*space->select.type->serial_size)(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_serial_size() */
+} /* end H5S_select_serial_size() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_serialize
PURPOSE
Serialize the selection for a dataspace into a buffer
USAGE
- herr_t H5S_select_serialize(space, buf)
+ herr_t H5S_select_serialize(space, p)
const H5S_t *space; IN: Dataspace with selection to serialize
- uint8_t *buf; OUT: Buffer to put serialized selection
+ uint8_t **p; OUT: Pointer to buffer to put serialized
+ selection. Will be advanced to end of
+ serialized selection.
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -256,22 +342,21 @@ H5S_select_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_serialize(const H5S_t *space, uint8_t *buf)
+H5S_select_serialize(H5S_t *space, uint8_t **p)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- assert(space);
- assert(buf);
+ HDassert(space);
+ HDassert(p);
/* Call the selection type's serialize function */
- ret_value=(*space->select.type->serialize)(space,buf);
+ ret_value = (*space->select.type->serialize)(space, p);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_serialize() */
+} /* end H5S_select_serialize() */
-
/*--------------------------------------------------------------------------
NAME
H5Sget_select_npoints
@@ -292,30 +377,29 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf)
hssize_t
H5Sget_select_npoints(hid_t spaceid)
{
- H5S_t *space; /* Dataspace to modify selection of */
- hssize_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ hssize_t ret_value; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("Hs", "i", spaceid);
/* Check args */
- if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space);
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Sget_select_npoints() */
+} /* H5Sget_select_npoints() */
-
/*--------------------------------------------------------------------------
NAME
H5S_get_select_npoints
PURPOSE
Get the number of elements in current selection
USAGE
- hssize_t H5Sget_select_npoints(space)
+ hsize_t H5Sget_select_npoints(space)
H5S_t *space; IN: Dataspace of selection to query
RETURNS
The number of elements in selection on success, 0 on failure
@@ -329,7 +413,7 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hssize_t
+H5_ATTR_PURE hsize_t
H5S_get_select_npoints(const H5S_t *space)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -337,10 +421,9 @@ H5S_get_select_npoints(const H5S_t *space)
/* Check args */
HDassert(space);
- FUNC_LEAVE_NOAPI((hssize_t)space->select.num_elem)
-} /* H5S_get_select_npoints() */
+ FUNC_LEAVE_NOAPI(space->select.num_elem)
+} /* end H5S_get_select_npoints() */
-
/*--------------------------------------------------------------------------
NAME
H5Sselect_valid
@@ -354,35 +437,32 @@ H5S_get_select_npoints(const H5S_t *space)
TRUE if the selection fits within the extent, FALSE if it does not and
Negative on an error.
DESCRIPTION
- Determines if the current selection at the current offet fits within the
+ Determines if the current selection at the current offset fits within the
extent for the dataspace.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
- Christian Chilan 01/17/2007
- Changed the error return value from 0 to FAIL.
--------------------------------------------------------------------------*/
htri_t
H5Sselect_valid(hid_t spaceid)
{
- H5S_t *space; /* Dataspace to modify selection of */
- htri_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ htri_t ret_value; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("t", "i", spaceid);
/* Check args */
- if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
ret_value = H5S_SELECT_VALID(space);
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Sselect_valid() */
+} /* end H5Sselect_valid() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_valid
@@ -396,7 +476,7 @@ done:
TRUE if the selection fits within the extent, FALSE if it does not and
Negative on an error.
DESCRIPTION
- Determines if the current selection at the current offet fits within the
+ Determines if the current selection at the current offset fits within the
extent for the dataspace.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
@@ -409,18 +489,17 @@ done:
htri_t
H5S_select_valid(const H5S_t *space)
{
- htri_t ret_value; /* Return value */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- assert(space);
+ HDassert(space);
ret_value = (*space->select.type->is_valid)(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_valid() */
+} /* end H5S_select_valid() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_deserialize
@@ -428,9 +507,13 @@ H5S_select_valid(const H5S_t *space)
Deserialize the current selection from a user-provided buffer into a real
selection in the dataspace.
USAGE
- herr_t H5S_select_deserialize(space, buf)
- H5S_t *space; IN/OUT: Dataspace pointer to place selection into
- uint8 *buf; IN: Buffer to retrieve serialized selection from
+ herr_t H5S_select_deserialize(space, p)
+ H5S_t **space; IN/OUT: Dataspace pointer to place
+ selection into. Will be allocated if not
+ provided.
+ uint8 **p; OUT: Pointer to buffer holding serialized
+ selection. Will be advanced to end of
+ serialized selection.
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -444,46 +527,49 @@ H5S_select_valid(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
+H5S_select_deserialize(H5S_t **space, const uint8_t **p)
{
- const uint8_t *tbuf; /* Temporary pointer to the selection type */
- uint32_t sel_type; /* Pointer to the selection type */
- herr_t ret_value=FAIL; /* return value */
+ uint32_t sel_type; /* Pointer to the selection type */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- assert(space);
+ HDassert(space);
+
+ /* Selection-type specific coding is moved to the callbacks. */
+
+ /* Decode selection type */
+ UINT32DECODE(*p, sel_type);
- tbuf=buf;
- UINT32DECODE(tbuf, sel_type);
- switch(sel_type) {
- case H5S_SEL_POINTS: /* Sequence of points selected */
- ret_value=(*H5S_sel_point->deserialize)(space,buf);
+ /* Make routine for selection type */
+ switch (sel_type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value = (*H5S_sel_point->deserialize)(space, p);
break;
- case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
- ret_value=(*H5S_sel_hyper->deserialize)(space,buf);
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value = (*H5S_sel_hyper->deserialize)(space, p);
break;
- case H5S_SEL_ALL: /* Entire extent selected */
- ret_value=(*H5S_sel_all->deserialize)(space,buf);
+ case H5S_SEL_ALL: /* Entire extent selected */
+ ret_value = (*H5S_sel_all->deserialize)(space, p);
break;
- case H5S_SEL_NONE: /* Nothing selected */
- ret_value=(*H5S_sel_none->deserialize)(space,buf);
+ case H5S_SEL_NONE: /* Nothing selected */
+ ret_value = (*H5S_sel_none->deserialize)(space, p);
break;
default:
break;
}
- if(ret_value<0)
+
+ if (ret_value < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_deserialize() */
+} /* end H5S_select_deserialize() */
-
/*--------------------------------------------------------------------------
NAME
H5Sget_select_bounds
@@ -515,27 +601,26 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
+H5Sget_select_bounds(hid_t spaceid, hsize_t start[] /*out*/, hsize_t end[] /*out*/)
{
- H5S_t *space; /* Dataspace to modify selection of */
- herr_t ret_value; /* return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* return value */
FUNC_ENTER_API(FAIL)
- H5TRACE3("e", "i*h*h", spaceid, start, end);
+ H5TRACE3("e", "ixx", spaceid, start, end);
/* Check args */
- if(start == NULL || end == NULL)
+ if (start == NULL || end == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
- if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
+ if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
ret_value = H5S_SELECT_BOUNDS(space, start, end);
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Sget_select_bounds() */
+} /* end H5Sget_select_bounds() */
-
/*--------------------------------------------------------------------------
NAME
H5S_get_select_bounds
@@ -566,21 +651,20 @@ done:
herr_t
H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(space);
- assert(start);
- assert(end);
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
- ret_value = (*space->select.type->bounds)(space,start,end);
+ ret_value = (*space->select.type->bounds)(space, start, end);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_get_select_bounds() */
+} /* end H5S_get_select_bounds() */
-
/*--------------------------------------------------------------------------
NAME
H5S_get_select_offset
@@ -607,7 +691,7 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
herr_t
H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -618,9 +702,89 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
ret_value = (*space->select.type->offset)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_get_select_offset() */
+} /* end H5S_get_select_offset() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_get_select_unlim_dim
+ PURPOSE
+ Gets the unlimited dimension in the selection, or -1 if there is no
+ unlimited dimension.
+ USAGE
+ int H5S_get_select_unlim_dim(space)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ RETURNS
+ Unlimited dimension in the selection, or -1 if there is no unlimited
+ dimension (never fails)
+ DESCRIPTION
+ Gets the unlimited dimension in the selection, or -1 if there is no
+ unlimited dimension.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Currently only implemented for hyperslab selections, all others
+ simply return -1.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5S_get_select_unlim_dim(const H5S_t *space)
+{
+ herr_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check args */
+ HDassert(space);
+
+ ret_value = (*space->select.type->unlim_dim)(space);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_select_unlim_dim() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_get_select_num_elem_non_unlim
+ PURPOSE
+ Gets the number of elements in the non-unlimited dimensions
+ USAGE
+ herr_t H5S_get_select_num_elem_non_unlim(space,num_elem_non_unlim)
+ H5S_t *space; IN: Dataspace pointer to check
+ hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Returns the number of elements in a slice through the non-unlimited
+ dimensions of the selection. Fails if the selection has no unlimited
+ dimension.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_get_select_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim)
+{
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(num_elem_non_unlim);
+
+ /* Check for selection callback */
+ if (!space->select.type->num_elem_non_unlim)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type has no num_elem_non_unlim callback")
+
+ /* Make selection callback */
+ if ((*space->select.type->num_elem_non_unlim)(space, num_elem_non_unlim) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL,
+ "can't get number of elements in non-unlimited dimension")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_select_unlim_dim() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_is_contiguous
@@ -645,19 +809,18 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
htri_t
H5S_select_is_contiguous(const H5S_t *space)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(space);
+ HDassert(space);
ret_value = (*space->select.type->is_contiguous)(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_is_contiguous() */
+} /* end H5S_select_is_contiguous() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_is_single
@@ -682,19 +845,18 @@ H5S_select_is_contiguous(const H5S_t *space)
htri_t
H5S_select_is_single(const H5S_t *space)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(space);
+ HDassert(space);
ret_value = (*space->select.type->is_single)(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_is_single() */
+} /* end H5S_select_is_single() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_is_regular
@@ -717,21 +879,20 @@ H5S_select_is_single(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_select_is_regular(const H5S_t *space)
+H5S_select_is_regular(H5S_t *space)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(space);
+ HDassert(space);
ret_value = (*space->select.type->is_regular)(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_is_regular() */
+} /* end H5S_select_is_regular() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_adjust_u
@@ -756,19 +917,107 @@ H5S_select_is_regular(const H5S_t *space)
herr_t
H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
HDassert(space);
+ HDassert(offset);
+ /* Perform operation */
ret_value = (*space->select.type->adjust_u)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_adjust_u() */
+} /* end H5S_select_adjust_u() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_adjust_s
+ PURPOSE
+ Adjust a selection by subtracting an offset
+ USAGE
+ herr_t H5S_select_adjust_u(space, offset)
+ H5S_t *space; IN/OUT: Pointer to dataspace to adjust
+ const hssize_t *offset; IN: Offset to subtract
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Moves a selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ This routine participates in the "Inlining C function pointers"
+ pattern, don't call it directly, use the appropriate macro
+ defined in H5Sprivate.h.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_adjust_s(H5S_t *space, const hssize_t *offset)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check args */
+ HDassert(space);
+ HDassert(offset);
+
+ /* Perform operation */
+ ret_value = (*space->select.type->adjust_s)(space, offset);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_select_adjust_s() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_adjust
+ PURPOSE
+ Adjust a selection by subtracting an offset
+ USAGE
+ herr_t H5Sselect_adjust_u(space_id, offset)
+ hid_t space_id; IN: ID of dataspace to adjust
+ const hsize_t *offset; IN: Offset to subtract
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Moves a selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Sselect_adjust(hid_t space_id, const hssize_t *offset)
+{
+ H5S_t *space;
+ hsize_t low_bounds[H5S_MAX_RANK];
+ hsize_t high_bounds[H5S_MAX_RANK];
+ unsigned u;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Hs", space_id, offset);
+
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == offset)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "NULL offset pointer")
+
+ /* Check bounds */
+ if (H5S_SELECT_BOUNDS(space, low_bounds, high_bounds) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds")
+ for (u = 0; u < space->extent.rank; u++)
+ if (offset[u] > (hssize_t)low_bounds[u])
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjustment would move selection below zero offset")
+
+ if (H5S_select_adjust_s(space, offset) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_adjust() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_project_scalar
@@ -794,7 +1043,7 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
herr_t
H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
{
- herr_t ret_value; /* Return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -805,9 +1054,8 @@ H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
ret_value = (*space->select.type->project_scalar)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_project_scalar() */
+} /* end H5S_select_project_scalar() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_project_simple
@@ -834,7 +1082,7 @@ H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
herr_t
H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
{
- herr_t ret_value; /* Return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -846,20 +1094,20 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
ret_value = (*space->select.type->project_simple)(space, new_space, offset);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_project_simple() */
+} /* end H5S_select_project_simple() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_iter_init
PURPOSE
Initializes iteration information for a selection.
USAGE
- herr_t H5S_select_iter_init(sel_iter, space, elmt_size)
+ herr_t H5S_select_iter_init(sel_iter, space, elmt_size, flags)
H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize.
H5S_t *space; IN: Dataspace object containing selection to
iterate over
size_t elmt_size; IN: Size of elements in the selection
+ unsigned flags; IN: Flags to control iteration behavior
RETURNS
Non-negative on success, negative on failure.
DESCRIPTION
@@ -867,9 +1115,9 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
in the dataspace's selection.
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size)
+H5S_select_iter_init(H5S_sel_iter_t *sel_iter, H5S_t *space, size_t elmt_size, unsigned flags)
{
- herr_t ret_value; /* Return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -882,23 +1130,28 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
/* Save the dataspace's rank */
sel_iter->rank = space->extent.rank;
- /* Point to the dataspace dimensions, if there are any */
- if(sel_iter->rank > 0)
- sel_iter->dims = space->extent.size;
- else
- sel_iter->dims = NULL;
+ /* If dims > 0, copy the dataspace dimensions & selection offset */
+ if (sel_iter->rank > 0) {
+ H5MM_memcpy(sel_iter->dims, space->extent.size, sizeof(hsize_t) * space->extent.rank);
+ H5MM_memcpy(sel_iter->sel_off, space->select.offset, sizeof(hsize_t) * space->extent.rank);
+ }
/* Save the element size */
sel_iter->elmt_size = elmt_size;
+ /* Initialize the number of elements to iterate over */
+ sel_iter->elmt_left = space->select.num_elem;
+
+ /* Set the flags for the iterator */
+ sel_iter->flags = flags;
+
/* Call initialization routine for selection type */
- ret_value = (*space->select.type->iter_init)(sel_iter, space);
+ ret_value = (*space->select.type->iter_init)(space, sel_iter);
HDassert(sel_iter->type);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_init() */
+} /* end H5S_select_iter_init() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_iter_coords
@@ -922,31 +1175,31 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hsize_t *coords)
+H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(sel_iter);
- assert(coords);
+ HDassert(sel_iter);
+ HDassert(coords);
/* Call iter_coords routine for selection type */
- ret_value = (*sel_iter->type->iter_coords)(sel_iter,coords);
+ ret_value = (*sel_iter->type->iter_coords)(sel_iter, coords);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_coords() */
+} /* end H5S_select_iter_coords() */
#ifdef LATER
-
+
/*--------------------------------------------------------------------------
NAME
- H5S_select_iter_block
+ H5S__select_iter_block
PURPOSE
Get the block of the current iterator position
USAGE
- herr_t H5S_select_iter_block(sel_iter,start,end)
+ herr_t H5S__select_iter_block(sel_iter,start,end)
const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
hsize_t *start; OUT: Array to place iterator start block coordinates
hsize_t *end; OUT: Array to place iterator end block coordinates
@@ -964,25 +1217,24 @@ H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hsize_t *coords)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
+H5S__select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR
+ FUNC_ENTER_PACKAGE_NOERR
/* Check args */
- assert(iter);
- assert(start);
- assert(end);
+ HDassert(iter);
+ HDassert(start);
+ HDassert(end);
/* Call iter_block routine for selection type */
- ret_value = (*iter->type->iter_block)(iter,start,end);
+ ret_value = (*iter->type->iter_block)(iter, start, end);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_block() */
+} /* end H5S__select_iter_block() */
#endif /* LATER */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_iter_nelmts
@@ -1004,30 +1256,30 @@ H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
REVISION LOG
--------------------------------------------------------------------------*/
hsize_t
-H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter)
{
- hsize_t ret_value; /* return value */
+ hsize_t ret_value = 0; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(sel_iter);
+ HDassert(sel_iter);
/* Call iter_nelmts routine for selection type */
ret_value = (*sel_iter->type->iter_nelmts)(sel_iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_nelmts() */
+} /* end H5S_select_iter_nelmts() */
#ifdef LATER
-
+
/*--------------------------------------------------------------------------
NAME
- H5S_select_iter_has_next_block
+ H5S__select_iter_has_next_block
PURPOSE
Check if there is another block available in the selection iterator
USAGE
- htri_t H5S_select_iter_has_next_block(sel_iter)
+ htri_t H5S__select_iter_has_next_block(sel_iter)
const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
RETURNS
Non-negative on success, negative on failure.
@@ -1043,23 +1295,22 @@ H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter)
+H5S__select_iter_has_next_block(const H5S_sel_iter_t *iter)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR
+ FUNC_ENTER_PACKAGE_NOERR
/* Check args */
- assert(iter);
+ HDassert(iter);
/* Call iter_has_next_block routine for selection type */
ret_value = (*iter->type->iter_has_next_block)(iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_has_next_block() */
+} /* end H5S__select_iter_has_next_block() */
#endif /* LATER */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_iter_next
@@ -1085,32 +1336,32 @@ H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter)
herr_t
H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(iter);
- assert(nelem>0);
+ HDassert(iter);
+ HDassert(nelem > 0);
/* Call iter_next routine for selection type */
- ret_value = (*iter->type->iter_next)(iter,nelem);
+ ret_value = (*iter->type->iter_next)(iter, nelem);
/* Decrement the number of elements left in selection */
- iter->elmt_left-=nelem;
+ iter->elmt_left -= nelem;
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_next() */
+} /* end H5S_select_iter_next() */
#ifdef LATER
-
+
/*--------------------------------------------------------------------------
NAME
- H5S_select_iter_next_block
+ H5S__select_iter_next_block
PURPOSE
Advance selection iterator to next block
USAGE
- herr_t H5S_select_iter_next_block(iter)
+ herr_t H5S__select_iter_next_block(iter)
H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
RETURNS
Non-negative on success, negative on failure.
@@ -1128,30 +1379,65 @@ H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_select_iter_next_block(H5S_sel_iter_t *iter)
+H5S__select_iter_next_block(H5S_sel_iter_t *iter)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_PACKAGE_NOERR
/* Check args */
- assert(iter);
+ HDassert(iter);
/* Call iter_next_block routine for selection type */
ret_value = (*iter->type->iter_next_block)(iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_next_block() */
+} /* end H5S__select_iter_next_block() */
#endif /* LATER */
-
+/*-------------------------------------------------------------------------
+ * Function: H5S_select_iter_get_seq_list
+ *
+ * Purpose: Retrieves the next sequence of offset/length pairs for an
+ * iterator on a dataspace
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 18, 2004
+ *
+ * Note: This routine participates in the "Inlining C function pointers"
+ * pattern, don't call it directly, use the appropriate macro
+ * defined in H5Sprivate.h.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_select_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelmts, size_t *nseq,
+ size_t *nelmts, hsize_t *off, size_t *len)
+{
+ herr_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert(iter);
+
+ /* Call the selection type's get_seq_list function */
+ if ((ret_value = (*iter->type->iter_get_seq_list)(iter, maxseq, maxelmts, nseq, nelmts, off, len)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_select_iter_get_seq_list() */
+
/*--------------------------------------------------------------------------
NAME
H5S_select_iter_release
PURPOSE
Release a selection iterator's resources.
USAGE
- hssize_t H5S_select_iter_release(sel_iter)
+ herr_t H5S_select_iter_release(sel_iter)
H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
RETURNS
The number of elements in selection on success, 0 on failure
@@ -1168,29 +1454,28 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter)
herr_t
H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(sel_iter);
+ HDassert(sel_iter);
/* Call selection type-specific release routine */
ret_value = (*sel_iter->type->iter_release)(sel_iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_iter_release() */
+} /* end H5S_select_iter_release() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_iterate
PURPOSE
Iterate over the selected elements in a memory buffer.
USAGE
- herr_t H5S_select_iterate(buf, type_id, space, operator, operator_data)
+ herr_t H5S_select_iterate(buf, type, space, operator, operator_data)
void *buf; IN/OUT: Buffer containing elements to iterate over
- hid_t type_id; IN: Datatype ID of BUF array.
+ H5T_t *type; IN: Datatype of BUF array.
H5S_t *space; IN: Dataspace object containing selection to iterate over
H5D_operator_t op; IN: Function pointer to the routine to be
called for each element in BUF iterated over.
@@ -1211,75 +1496,80 @@ H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
the selection is not modified.
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op,
- void *operator_data)
+H5S_select_iterate(void *buf, const H5T_t *type, H5S_t *space, const H5S_sel_iter_op_t *op, void *op_data)
{
- H5T_t *dt; /* Datatype structure */
- H5S_sel_iter_t iter; /* Selection iteration info */
- hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
- uint8_t *loc; /* Current element location in buffer */
- hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */
- hssize_t nelmts; /* Number of elements in selection */
- hsize_t space_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
- hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
- hsize_t curr_off; /* Current offset within sequence */
- hsize_t tmp_off; /* Temporary offset within sequence */
- size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
- size_t curr_len; /* Length of bytes left to process in sequence */
- size_t nseq; /* Number of sequences generated */
- size_t curr_seq; /* Current sequnce being worked on */
- size_t nelem; /* Number of elements used in sequences */
- size_t max_elem; /* Maximum number of elements allowed in sequences */
- size_t elmt_size; /* Datatype size */
- unsigned ndims; /* Number of dimensions in dataspace */
- int i; /* Local Index variable */
- herr_t user_ret=0; /* User's return value */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
+ hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
+ hsize_t *off = NULL; /* Array to store sequence offsets */
+ size_t *len = NULL; /* Array to store sequence lengths */
+ hssize_t nelmts; /* Number of elements in selection */
+ hsize_t space_size[H5S_MAX_RANK]; /* Dataspace size */
+ size_t max_elem; /* Maximum number of elements allowed in sequences */
+ size_t elmt_size; /* Datatype size */
+ unsigned ndims; /* Number of dimensions in dataspace */
+ herr_t user_ret = 0; /* User's return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Check args */
HDassert(buf);
- HDassert(H5I_DATATYPE == H5I_get_type(type_id));
+ HDassert(type);
HDassert(space);
HDassert(op);
/* Get the datatype size */
- if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
- if(0 == (elmt_size = H5T_get_size(dt)))
+ if (0 == (elmt_size = H5T_get_size(type)))
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
+ /* Allocate the selection iterator */
+ if (NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
+
/* Initialize iterator */
- if(H5S_select_iter_init(&iter, space, elmt_size) < 0)
+ if (H5S_select_iter_init(iter, space, elmt_size, 0) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- iter_init = TRUE; /* Selection iteration info has been initialized */
+ iter_init = TRUE; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
- if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
+ if ((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
/* Get the rank of the dataspace */
ndims = space->extent.rank;
- if(ndims > 0) {
- /* Copy the size of the space */
- HDassert(space->extent.size);
- HDmemcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
+ if (ndims > 0) {
+ /* Copy the size of the space */
+ HDassert(space->extent.size);
+ H5MM_memcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
} /* end if */
space_size[ndims] = elmt_size;
/* Compute the maximum number of bytes required */
- H5_ASSIGN_OVERFLOW(max_elem, nelmts, hssize_t, size_t);
+ H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
+
+ /* Allocate the offset & length arrays */
+ if (NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array")
+ if (NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array")
/* Loop, while elements left in selection */
- while(max_elem > 0 && user_ret == 0) {
+ while (max_elem > 0 && user_ret == 0) {
+ size_t nelem; /* Number of elements used in sequences */
+ size_t nseq; /* Number of sequences generated */
+ size_t curr_seq; /* Current sequence being worked on */
+
/* Get the sequences of bytes */
- if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
+ if (H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off,
+ len) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
/* Loop, while sequences left to process */
- for(curr_seq=0; curr_seq<nseq && user_ret==0; curr_seq++) {
+ for (curr_seq = 0; curr_seq < nseq && user_ret == 0; curr_seq++) {
+ hsize_t curr_off; /* Current offset within sequence */
+ size_t curr_len; /* Length of bytes left to process in sequence */
+
/* Get the current offset */
curr_off = off[curr_seq];
@@ -1287,9 +1577,14 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
curr_len = len[curr_seq];
/* Loop, while bytes left in sequence */
- while(curr_len > 0 && user_ret == 0) {
+ while (curr_len > 0 && user_ret == 0) {
+ hsize_t coords[H5S_MAX_RANK]; /* Coordinates of element in dataspace */
+ hsize_t tmp_off; /* Temporary offset within sequence */
+ uint8_t *loc; /* Current element location in buffer */
+ int i; /* Local Index variable */
+
/* Compute the coordinate from the offset */
- for(i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
+ for (i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
coords[i] = tmp_off % space_size[i];
tmp_off /= space_size[i];
} /* end for */
@@ -1297,33 +1592,57 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
/* Get the location within the user's buffer */
loc = (unsigned char *)buf + curr_off;
- /* Call user's callback routine */
- user_ret=(*op)(loc,type_id,ndims,coords,operator_data);
+ /* Check which type of callback to make */
+ switch (op->op_type) {
+ case H5S_SEL_ITER_OP_APP:
+ /* Make the application callback */
+ user_ret = (op->u.app_op.op)(loc, op->u.app_op.type_id, ndims, coords, op_data);
+ break;
+
+ case H5S_SEL_ITER_OP_LIB:
+ /* Call the library's callback */
+ user_ret = (op->u.lib_op)(loc, type, ndims, coords, op_data);
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported op type")
+ } /* end switch */
+
+ /* Check for error return from iterator */
+ if (user_ret < 0)
+ HERROR(H5E_DATASPACE, H5E_CANTNEXT, "iteration operator failed");
/* Increment offset in dataspace */
- curr_off+=elmt_size;
+ curr_off += elmt_size;
/* Decrement number of bytes left in sequence */
- curr_len-=elmt_size;
+ curr_len -= elmt_size;
} /* end while */
- } /* end for */
+ } /* end for */
/* Decrement number of elements left to process */
- max_elem-=nelem;
+ max_elem -= nelem;
} /* end while */
/* Set return value */
- ret_value=user_ret;
+ ret_value = user_ret;
done:
+ /* Release resources, if allocated */
+ if (len)
+ len = H5FL_SEQ_FREE(size_t, len);
+ if (off)
+ off = H5FL_SEQ_FREE(hsize_t, off);
+
/* Release selection iterator */
- if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
+ if (iter)
+ iter = H5FL_FREE(H5S_sel_iter_t, iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_iterate() */
+} /* end H5S_select_iterate() */
-
/*--------------------------------------------------------------------------
NAME
H5Sget_select_type
@@ -1336,30 +1655,29 @@ done:
Non-negative on success/Negative on failure. Return value is from the
set of values in the H5S_sel_type enumerated type.
DESCRIPTION
- This function retrieves the type of selection currently defined for
+ This function retrieves the type of selection currently defined for
a dataspace.
--------------------------------------------------------------------------*/
H5S_sel_type
H5Sget_select_type(hid_t space_id)
{
- H5S_t *space; /* dataspace to modify */
- H5S_sel_type ret_value; /* Return value */
+ H5S_t *space; /* dataspace to modify */
+ H5S_sel_type ret_value; /* Return value */
FUNC_ENTER_API(H5S_SEL_ERROR)
H5TRACE1("St", "i", space_id);
/* Check args */
- if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace")
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ID, H5E_BADID, H5S_SEL_ERROR, "not a dataspace")
/* Set return value */
ret_value = H5S_GET_SELECT_TYPE(space);
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Sget_select_type() */
+} /* end H5Sget_select_type() */
-
/*--------------------------------------------------------------------------
NAME
H5S_get_select_type
@@ -1372,30 +1690,29 @@ done:
Non-negative on success/Negative on failure. Return value is from the
set of values in the H5S_sel_type enumerated type.
DESCRIPTION
- This function retrieves the type of selection currently defined for
+ This function retrieves the type of selection currently defined for
a dataspace.
COMMENTS
This routine participates in the "Inlining C function pointers"
pattern, don't call it directly, use the appropriate macro
defined in H5Sprivate.h.
--------------------------------------------------------------------------*/
-H5S_sel_type
+H5_ATTR_PURE H5S_sel_type
H5S_get_select_type(const H5S_t *space)
{
- H5S_sel_type ret_value; /* Return value */
+ H5S_sel_type ret_value = H5S_SEL_ERROR; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
- assert(space);
+ HDassert(space);
/* Set return value */
- ret_value=H5S_GET_SELECT_TYPE(space);
+ ret_value = H5S_GET_SELECT_TYPE(space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_get_select_type() */
+} /* end H5S_get_select_type() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_shape_same
@@ -1410,23 +1727,23 @@ H5S_get_select_type(const H5S_t *space)
DESCRIPTION
Checks to see if the current selection in the dataspaces are the same
dimensionality and shape.
+
This is primarily used for reading the entire selection in one swoop.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
- Assumes that there is only a single "block" for hyperslab selections.
+ This routine participates in the "Inlining C function pointers" pattern,
+ don't call it directly, use the appropriate macro defined in H5Sprivate.h.
EXAMPLES
REVISION LOG
- Modified function to view identical shapes with different dimensions
- as being the same under some circumstances.
--------------------------------------------------------------------------*/
htri_t
-H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
+H5S_select_shape_same(H5S_t *space1, H5S_t *space2)
{
- H5S_sel_iter_t iter_a; /* Selection a iteration info */
- H5S_sel_iter_t iter_b; /* Selection b iteration info */
- hbool_t iter_a_init = 0; /* Selection a iteration info has been initialized */
- hbool_t iter_b_init = 0; /* Selection b iteration info has been initialized */
- htri_t ret_value = TRUE; /* Return value */
+ H5S_sel_iter_t *iter_a = NULL; /* Selection a iteration info */
+ H5S_sel_iter_t *iter_b = NULL; /* Selection b iteration info */
+ hbool_t iter_a_init = FALSE; /* Selection a iteration info has been initialized */
+ hbool_t iter_b_init = FALSE; /* Selection b iteration info has been initialized */
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -1434,197 +1751,178 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
HDassert(space1);
HDassert(space2);
- /* Special case for one or both dataspaces being scalar */
- if(space1->extent.rank == 0 || space2->extent.rank == 0) {
- /* Check for different number of elements selected */
- if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
- HGOTO_DONE(FALSE)
- } /* end if */
- else {
- const H5S_t *space_a; /* Dataspace with larger rank */
- const H5S_t *space_b; /* Dataspace with smaller rank */
- unsigned space_a_rank; /* Number of dimensions of dataspace A */
- unsigned space_b_rank; /* Number of dimensions of dataspace B */
-
- /* need to be able to handle spaces of different rank:
+ /* Check for different number of elements selected */
+ if (H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
+ HGOTO_DONE(FALSE)
+
+ /* Check special cases if both dataspaces aren't scalar */
+ /* (If only one is, the number of selected points check is sufficient) */
+ if (space1->extent.rank > 0 && space2->extent.rank > 0) {
+ H5S_t *space_a; /* Dataspace with larger rank */
+ H5S_t *space_b; /* Dataspace with smaller rank */
+ unsigned space_a_rank; /* Number of dimensions of dataspace A */
+ unsigned space_b_rank; /* Number of dimensions of dataspace B */
+ int space_a_dim; /* Current dimension in dataspace A */
+ int space_b_dim; /* Current dimension in dataspace B */
+ H5S_sel_type sel_a_type; /* Selection type for dataspace A */
+ H5S_sel_type sel_b_type; /* Selection type for dataspace B */
+
+ /* Need to be able to handle spaces of different rank:
*
* To simplify logic, let space_a point to the element of the set
- * {space1, space2} with the largest rank or space1 if the ranks
+ * {space1, space2} with the largest rank or space1 if the ranks
* are identical.
*
* Similarly, let space_b point to the element of {space1, space2}
* with the smallest rank, or space2 if they are identical.
*
- * Let: space_a_rank be the rank of space_a,
+ * Let: space_a_rank be the rank of space_a,
* space_b_rank be the rank of space_b,
- * delta_rank = space_a_rank - space_b_rank.
*
- * Set all this up below.
+ * Set all this up here.
*/
- if(space1->extent.rank >= space2->extent.rank) {
+ if (space1->extent.rank >= space2->extent.rank) {
space_a = space1;
- space_a_rank = space_a->extent.rank;
-
space_b = space2;
- space_b_rank = space_b->extent.rank;
} /* end if */
else {
space_a = space2;
- space_a_rank = space_a->extent.rank;
-
space_b = space1;
- space_b_rank = space_b->extent.rank;
} /* end else */
+ space_a_rank = space_a->extent.rank;
+ space_b_rank = space_b->extent.rank;
HDassert(space_a_rank >= space_b_rank);
HDassert(space_b_rank > 0);
- /* Check for different number of elements selected */
- if(H5S_GET_SELECT_NPOINTS(space_a) != H5S_GET_SELECT_NPOINTS(space_b))
- HGOTO_DONE(FALSE)
-
- /* Check for "easy" cases before getting into generalized block iteration code */
- if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_ALL) && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_ALL)) {
- hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
- hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
- int space_a_dim; /* Current dimension in dataspace A */
- int space_b_dim; /* Current dimension in dataspace B */
-
- if(H5S_get_simple_extent_dims(space_a, dims1, NULL) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
- if(H5S_get_simple_extent_dims(space_b, dims2, NULL) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
-
+ /* Get selection type for both dataspaces */
+ sel_a_type = H5S_GET_SELECT_TYPE(space_a);
+ sel_b_type = H5S_GET_SELECT_TYPE(space_b);
+
+ /* If selections aren't "none", compare their bounds */
+ if (sel_a_type != H5S_SEL_NONE && sel_b_type != H5S_SEL_NONE) {
+ hsize_t low_a[H5S_MAX_RANK]; /* Low bound of selection in dataspace a */
+ hsize_t low_b[H5S_MAX_RANK]; /* Low bound of selection in dataspace b */
+ hsize_t high_a[H5S_MAX_RANK]; /* High bound of selection in dataspace a */
+ hsize_t high_b[H5S_MAX_RANK]; /* High bound of selection in dataspace b */
+
+ /* Get low & high bounds for both dataspaces */
+ if (H5S_SELECT_BOUNDS(space_a, low_a, high_a) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL,
+ "can't get selection bounds for first dataspace")
+ if (H5S_SELECT_BOUNDS(space_b, low_b, high_b) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL,
+ "can't get selection bounds for second dataspace")
+
+ /* Check that the range between the low & high bounds are the same */
space_a_dim = (int)space_a_rank - 1;
space_b_dim = (int)space_b_rank - 1;
+ while (space_b_dim >= 0) {
+ /* Sanity check */
+ HDassert(low_a[space_a_dim] <= high_a[space_a_dim]);
+ HDassert(low_a[space_b_dim] <= high_a[space_b_dim]);
- /* recall that space_a_rank >= space_b_rank.
- *
- * In the following while loop, we test to see if space_a and space_b
- * have identical size in all dimensions they have in common.
- */
- while(space_b_dim >= 0) {
- if(dims1[space_a_dim] != dims2[space_b_dim])
+ /* Verify that the ranges are the same */
+ if ((high_a[space_a_dim] - low_a[space_a_dim]) != (high_b[space_b_dim] - low_b[space_b_dim]))
HGOTO_DONE(FALSE)
+ /* Go to next dimension */
space_a_dim--;
space_b_dim--;
} /* end while */
- /* Since we are selecting the entire spaces, we must also verify that space_a
- * has size 1 in all dimensions that it does not share with space_b.
- */
- while(space_a_dim >= 0) {
- if(dims1[space_a_dim] != 1)
- HGOTO_DONE(FALSE)
+ /* Check that the rest of the ranges in space a are "flat" */
+ while (space_a_dim >= 0) {
+ /* Sanity check */
+ HDassert(low_a[space_a_dim] <= high_a[space_a_dim]);
- space_a_dim--;
- } /* end while */
- } /* end if */
- else if((H5S_GET_SELECT_TYPE(space1) == H5S_SEL_NONE) || (H5S_GET_SELECT_TYPE(space2) == H5S_SEL_NONE)) {
- HGOTO_DONE(TRUE)
- } /* end if */
- else if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_HYPERSLABS && space_a->select.sel_info.hslab->diminfo_valid)
- && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_HYPERSLABS && space_b->select.sel_info.hslab->diminfo_valid)) {
- int space_a_dim; /* Current dimension in dataspace A */
- int space_b_dim; /* Current dimension in dataspace B */
-
- space_a_dim = (int)space_a_rank - 1;
- space_b_dim = (int)space_b_rank - 1;
-
- /* check that the shapes are the same in the common dimensions, and that
- * block == 1 in all dimensions that appear only in space_a.
- */
- while(space_b_dim >= 0) {
- if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].stride !=
- space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].stride)
- HGOTO_DONE(FALSE)
-
- if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].count !=
- space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].count)
- HGOTO_DONE(FALSE)
-
- if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block !=
- space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].block)
+ /* This range should be flat to be the same in a lower dimension */
+ if (low_a[space_a_dim] != high_a[space_a_dim])
HGOTO_DONE(FALSE)
space_a_dim--;
- space_b_dim--;
} /* end while */
- while(space_a_dim >= 0) {
- if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != 1)
- HGOTO_DONE(FALSE)
+ /* Check for a single block in each selection */
+ if (H5S_SELECT_IS_SINGLE(space_a) && H5S_SELECT_IS_SINGLE(space_b)) {
+ /* If both selections are a single block and their bounds are
+ * the same, then the selections are the same, even if the
+ * selection types are different.
+ */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+ } /* end if */
- space_a_dim--;
- } /* end while */
- } /* end if */
- /* Iterate through all the blocks in the selection */
+ /* If the dataspaces have the same selection type, use the selection's
+ * shape_same operator.
+ */
+ if (sel_a_type == sel_b_type)
+ ret_value = (*space_a->select.type->shape_same)(space_a, space_b);
+ /* Otherwise, iterate through all the blocks in the selection */
else {
- hsize_t start_a[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace a */
- hsize_t start_b[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace b */
- hsize_t end_a[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace a */
- hsize_t end_b[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace b */
- hsize_t off_a[H5O_LAYOUT_NDIMS]; /* Offset of selection a blocks */
- hsize_t off_b[H5O_LAYOUT_NDIMS]; /* Offset of selection b blocks */
- hbool_t first_block = TRUE; /* Flag to indicate the first block */
+ hsize_t start_a[H5S_MAX_RANK]; /* Start point of selection block in dataspace a */
+ hsize_t start_b[H5S_MAX_RANK]; /* Start point of selection block in dataspace b */
+ hsize_t end_a[H5S_MAX_RANK]; /* End point of selection block in dataspace a */
+ hsize_t end_b[H5S_MAX_RANK]; /* End point of selection block in dataspace b */
+ hssize_t offset[H5S_MAX_RANK]; /* Offset of selection b blocks relative to selection a blocks */
+ hbool_t first_block = TRUE; /* Flag to indicate the first block */
+
+ /* Allocate the selection iterators */
+ if (NULL == (iter_a = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
+ if (NULL == (iter_b = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
/* Initialize iterator for each dataspace selection
* Use '0' for element size instead of actual element size to indicate
* that the selection iterator shouldn't be "flattened", since we
* aren't actually going to be doing I/O with the iterators.
*/
- if(H5S_select_iter_init(&iter_a, space_a, (size_t)0) < 0)
+ if (H5S_select_iter_init(iter_a, space_a, (size_t)0, 0) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a")
- iter_a_init = 1;
- if(H5S_select_iter_init(&iter_b, space_b, (size_t)0) < 0)
+ iter_a_init = TRUE;
+ if (H5S_select_iter_init(iter_b, space_b, (size_t)0, 0) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b")
- iter_b_init = 1;
+ iter_b_init = TRUE;
/* Iterate over all the blocks in each selection */
- while(1) {
- int space_a_dim; /* Current dimension in dataspace A */
- int space_b_dim; /* Current dimension in dataspace B */
- htri_t status_a, status_b; /* Status from next block checks */
+ while (1) {
+ htri_t status_a, status_b; /* Status from next block checks */
/* Get the current block for each selection iterator */
- if(H5S_SELECT_ITER_BLOCK(&iter_a, start_a, end_a) < 0)
+ if (H5S_SELECT_ITER_BLOCK(iter_a, start_a, end_a) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block a")
- if(H5S_SELECT_ITER_BLOCK(&iter_b, start_b, end_b) < 0)
+ if (H5S_SELECT_ITER_BLOCK(iter_b, start_b, end_b) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block b")
space_a_dim = (int)space_a_rank - 1;
space_b_dim = (int)space_b_rank - 1;
- /* The first block only compares the sizes and sets the
- * relative offsets for later blocks
+ /* The first block only compares the sizes and sets the
+ * relative offsets for later blocks
*/
- if(first_block) {
- /* If the block sizes in the common dimensions from
+ if (first_block) {
+ /* If the block sizes in the common dimensions from
* each selection don't match, get out
*/
- while(space_b_dim >= 0) {
- if((end_a[space_a_dim] - start_a[space_a_dim]) !=
- (end_b[space_b_dim] - start_b[space_b_dim]))
+ while (space_b_dim >= 0) {
+ if ((end_a[space_a_dim] - start_a[space_a_dim]) !=
+ (end_b[space_b_dim] - start_b[space_b_dim]))
HGOTO_DONE(FALSE)
/* Set the relative locations of the selections */
- off_a[space_a_dim] = start_a[space_a_dim];
- off_b[space_b_dim] = start_b[space_b_dim];
+ offset[space_a_dim] = (hssize_t)start_b[space_b_dim] - (hssize_t)start_a[space_a_dim];
space_a_dim--;
space_b_dim--;
} /* end while */
- /* similarly, if the block size in any dimension that appears only
+ /* Similarly, if the block size in any dimension that appears only
* in space_a is not equal to 1, get out.
*/
- while(space_a_dim >= 0) {
- if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
+ while (space_a_dim >= 0) {
+ if (start_a[space_a_dim] != end_a[space_a_dim])
HGOTO_DONE(FALSE)
- /* Set the relative locations of the selections */
- off_a[space_a_dim] = start_a[space_a_dim];
-
space_a_dim--;
} /* end while */
@@ -1633,16 +1931,16 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
} /* end if */
/* Check over the blocks for each selection */
else {
- /* for dimensions that space_a and space_b have in common: */
- while(space_b_dim >= 0) {
+ /* For dimensions that space_a and space_b have in common: */
+ while (space_b_dim >= 0) {
/* Check if the blocks are in the same relative location */
- if((start_a[space_a_dim] - off_a[space_a_dim]) !=
- (start_b[space_b_dim] - off_b[space_b_dim]))
+ if ((hsize_t)((hssize_t)start_a[space_a_dim] + offset[space_a_dim]) !=
+ start_b[space_b_dim])
HGOTO_DONE(FALSE)
/* If the block sizes from each selection doesn't match, get out */
- if((end_a[space_a_dim] - start_a[space_a_dim]) !=
- (end_b[space_b_dim] - start_b[space_b_dim]))
+ if ((end_a[space_a_dim] - start_a[space_a_dim]) !=
+ (end_b[space_b_dim] - start_b[space_b_dim]))
HGOTO_DONE(FALSE)
space_a_dim--;
@@ -1650,248 +1948,404 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
} /* end while */
/* For dimensions that appear only in space_a: */
- while(space_a_dim >= 0) {
+ while (space_a_dim >= 0) {
/* If the block size isn't 1, get out */
- if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
+ if (start_a[space_a_dim] != end_a[space_a_dim])
HGOTO_DONE(FALSE)
space_a_dim--;
} /* end while */
- } /* end else */
+ } /* end else */
/* Check if we are able to advance to the next selection block */
- if((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_a)) < 0)
+ if ((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_a)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block a")
- if((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_b)) < 0)
+ if ((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_b)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b")
/* Did we run out of blocks at the same time? */
- if((status_a == FALSE) && (status_b == FALSE))
+ if ((status_a == FALSE) && (status_b == FALSE))
break;
- else if(status_a != status_b)
+ else if (status_a != status_b)
HGOTO_DONE(FALSE)
else {
/* Advance to next block in selection iterators */
- if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_a) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block a")
+ if (H5S_SELECT_ITER_NEXT_BLOCK(iter_a) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL,
+ "unable to advance to next iterator block a")
- if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_b) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block b")
+ if (H5S_SELECT_ITER_NEXT_BLOCK(iter_b) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL,
+ "unable to advance to next iterator block b")
} /* end else */
- } /* end while */
- } /* end else */
- } /* end else */
+ } /* end while */
+ } /* end else */
+ } /* end if */
done:
- if(iter_a_init)
- if(H5S_SELECT_ITER_RELEASE(&iter_a) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a")
- if(iter_b_init)
- if(H5S_SELECT_ITER_RELEASE(&iter_b) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b")
+ if (iter_a_init && H5S_SELECT_ITER_RELEASE(iter_a) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a")
+ if (iter_a)
+ iter_a = H5FL_FREE(H5S_sel_iter_t, iter_a);
+ if (iter_b_init && H5S_SELECT_ITER_RELEASE(iter_b) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b")
+ if (iter_b)
+ iter_b = H5FL_FREE(H5S_sel_iter_t, iter_b);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_shape_same() */
+} /* end H5S_select_shape_same() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_shape_same
+ PURPOSE
+ Check if two selections are the same shape
+ USAGE
+ htri_t H5Sselect_shape_same(space1_id, space2_id)
+ hid_t space1_id; IN: ID of 1st Dataspace pointer to compare
+ hid_t space2_id; IN: ID of 2nd Dataspace pointer to compare
+ RETURNS
+ TRUE/FALSE/FAIL
+ DESCRIPTION
+ Checks to see if the current selection in the dataspaces are the same
+ dimensionality and shape.
+ This is primarily used for reading the entire selection in one swoop.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5Sselect_shape_same(hid_t space1_id, hid_t space2_id)
+{
+ H5S_t *space1, *space2; /* Dataspaces to compare */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("t", "ii", space1_id, space2_id);
+
+ if (NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ if ((ret_value = H5S_select_shape_same(space1, space2)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selections")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_shape_same() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_intersect_block
+ PURPOSE
+ Check if current selection intersects with a block
+ USAGE
+ htri_t H5S_select_intersect_block(space, start, end)
+ const H5S_t *space; IN: Dataspace to compare
+ const hsize_t *start; IN: Starting coordinate of block
+ const hsize_t *end; IN: Opposite ("ending") coordinate of block
+ RETURNS
+ TRUE / FALSE / FAIL
+ DESCRIPTION
+ Checks to see if the current selection in the dataspace intersects with
+ the block given.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Assumes that start & end block bounds are _inclusive_, so start == end
+ value OK.
+
+ This routine participates in the "Inlining C function pointers" pattern,
+ don't call it directly, use the appropriate macro defined in H5Sprivate.h.
+--------------------------------------------------------------------------*/
+htri_t
+H5S_select_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end)
+{
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
+
+ /* If selections aren't "none", compare their bounds */
+ if (H5S_SEL_NONE != H5S_GET_SELECT_TYPE(space)) {
+ hsize_t low[H5S_MAX_RANK]; /* Low bound of selection in dataspace */
+ hsize_t high[H5S_MAX_RANK]; /* High bound of selection in dataspace */
+ unsigned u; /* Local index variable */
+
+ /* Get low & high bounds for dataspace selection */
+ if (H5S_SELECT_BOUNDS(space, low, high) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for dataspace")
+
+ /* Loop over selection bounds and block, checking for overlap */
+ for (u = 0; u < space->extent.rank; u++)
+ /* If selection bounds & block don't overlap, can leave now */
+ if (!H5S_RANGE_OVERLAP(low[u], high[u], start[u], end[u]))
+ HGOTO_DONE(FALSE)
+ } /* end if */
+
+ /* Call selection type's intersect routine */
+ if ((ret_value = (*space->select.type->intersect_block)(space, start, end)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't intersect block with selection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_select_intersect_block() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_intersect_block
+ PURPOSE
+ Check if current selection intersects with a block
+ USAGE
+ htri_t H5Sselect_intersect_block(space_id, start, end)
+ hid_t space1_id; IN: ID of dataspace pointer to compare
+ const hsize_t *start; IN: Starting coordinate of block
+ const hsize_t *end; IN: Opposite ("ending") coordinate of block
+ RETURNS
+ TRUE / FALSE / FAIL
+ DESCRIPTION
+ Checks to see if the current selection in the dataspace intersects with
+ the block given.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Assumes that start & end block bounds are _inclusive_, so start == end
+ value OK.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, const hsize_t *end)
+{
+ H5S_t *space; /* Dataspace to query */
+ unsigned u; /* Local index value */
+ htri_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("t", "i*h*h", space_id, start, end);
+
+ /* Check arguments */
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == start)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block start array pointer is NULL")
+ if (NULL == end)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block end array pointer is NULL")
+
+ /* Range check start & end values */
+ for (u = 0; u < space->extent.rank; u++)
+ if (start[u] > end[u])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "block start[%u] (%llu) > end[%u] (%llu)", u,
+ (unsigned long long)start[u], u, (unsigned long long)end[u])
+
+ /* Call internal routine to do comparison */
+ if ((ret_value = H5S_select_intersect_block(space, start, end)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selection and block")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_intersect_block() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_construct_projection
PURPOSE
Given a dataspace a of rank n with some selection, construct a new
- dataspace b of rank m (m != n), with the selection in a being
- topologically identical to that in b (as verified by
+ dataspace b of rank m (m != n), with the selection in a being
+ topologically identical to that in b (as verified by
H5S_select_shape_same().
- This function exists, as some I/O code chokes of topologically
- identical selections with different ranks. At least to begin
+ This function exists, as some I/O code chokes on topologically
+ identical selections with different ranks. At least to begin
with, we will deal with the issue by constructing projections
- of the memory dataspace with ranks equaling those of the file
+ of the memory dataspace with ranks equaling those of the file
dataspace.
- Note that if m > n, it is possible that the starting point in the
- buffer associated with the memory dataspace will have to be
- adjusted to match the projected dataspace. If the buf parameter
- is not NULL, the function must return an adjusted buffer base
- address in *adj_buf_ptr.
+ Note that if m > n, it is possible that the starting point in the
+ buffer associated with the memory dataspace will have to be
+ adjusted to match the projected dataspace. In this case, the amount
+ of adjustment to be applied to the buffer will be returned via the
+ buf_adj parameter, if supplied.
USAGE
- htri_t H5S_select_construct_projection(base_space,
+ htri_t H5S_select_construct_projection(base_space,
new_space_ptr,
new_space_rank,
- buf,
- adj_buf_ptr)
+ element_size,
+ buf_adj)
const H5S_t *base_space; IN: Ptr to Dataspace to project
H5S_t ** new_space_ptr; OUT: Ptr to location in which to return
- the address of the projected space
+ the address of the projected space
int new_space_rank; IN: Rank of the projected space.
- const void * buf; IN: Base address of the buffer
- associated with the base space.
- May be NULL.
- void ** adj_buf_ptr; OUT: If buf != NULL, store the base
- address of the section of buf
- that is described by *new_space_ptr
- in *adj_buf_ptr.
-
+ hsize_t element_size; IN: size of each element in the selection
+ ptrdiff_t buf_adj; OUT: amount of adjustment to be applied
+ to buffer associated with memory
+ dataspace
+
RETURNS
Non-negative on success/Negative on failure.
DESCRIPTION
- Construct a new dataspace and associated selection which is a
- projection of the supplied dataspace and associated selection into
+ Construct a new dataspace and associated selection which is a
+ projection of the supplied dataspace and associated selection into
the specified rank. Return it in *new_space_ptr.
- If buf is supplied, computes the base address of the projected
- selection in buf, and stores the base address in *adj_buf_ptr.
-
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
- The selection in the supplied base_space has thickness 1 in all
+ The selection in the supplied base_space has thickness 1 in all
dimensions greater than new_space_rank. Note that here we count
- dimensions from the fastest changing coordinate to the slowest
+ dimensions from the fastest changing coordinate to the slowest
changing changing coordinate.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
- unsigned new_space_rank, const void *buf, void const **adj_buf_ptr, hsize_t element_size)
+H5S_select_construct_projection(H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank,
+ hsize_t element_size, ptrdiff_t *buf_adj)
{
- H5S_t * new_space = NULL; /* New dataspace constructed */
- hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */
- hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */
- int sbase_space_rank; /* Signed # of dimensions of base dataspace */
- unsigned base_space_rank; /* # of dimensions of base dataspace */
- hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_t *new_space = NULL; /* New dataspace constructed */
+ hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */
+ hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */
+ int sbase_space_rank; /* Signed # of dimensions of base dataspace */
+ unsigned base_space_rank; /* # of dimensions of base dataspace */
+ hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(base_space != NULL);
- HDassert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) || (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE));
+ HDassert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) ||
+ (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE));
HDassert(new_space_ptr != NULL);
HDassert((new_space_rank != 0) || (H5S_GET_SELECT_NPOINTS(base_space) <= 1));
HDassert(new_space_rank <= H5S_MAX_RANK);
- HDassert((buf == NULL) || (adj_buf_ptr != NULL));
- HDassert(element_size > 0 );
+ HDassert(element_size > 0);
/* Get the extent info for the base dataspace */
- if((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0)
+ if ((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality of base space")
base_space_rank = (unsigned)sbase_space_rank;
HDassert(base_space_rank != new_space_rank);
/* Check if projected space is scalar */
- if(new_space_rank == 0) {
- hssize_t npoints; /* Number of points selected */
+ if (new_space_rank == 0) {
+ hssize_t npoints; /* Number of points selected */
- /* Retreve the number of elements selected */
- if((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
+ /* Retrieve the number of elements selected */
+ if ((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected")
HDassert(npoints <= 1);
/* Create new scalar dataspace */
- if(NULL == (new_space = H5S_create(H5S_SCALAR)))
+ if (NULL == (new_space = H5S_create(H5S_SCALAR)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace")
-
+
/* No need to register the dataspace(i.e. get an ID) as
* we will just be discarding it shortly.
*/
- /* Selection for the new space will be either all or
+ /* Selection for the new space will be either all or
* none, depending on whether the base space has 0 or
* 1 elements selected.
*
- * Observe that the base space can't have more than
+ * Observe that the base space can't have more than
* one selected element, since its selection has the
- * same shape as the file dataspace, and that data
+ * same shape as the file dataspace, and that data
* space is scalar.
*/
- if(1 == npoints) {
+ if (1 == npoints) {
/* Assuming that the selection in the base dataspace is not
- * empty, we must compute the offset of the selected item in
+ * empty, we must compute the offset of the selected item in
* the buffer associated with the base dataspace.
*
- * Since the new space rank is zero, we know that the
- * the base space must have rank at least 1 -- and
- * hence it is a simple dataspace. However, the
+ * Since the new space rank is zero, we know that the
+ * the base space must have rank at least 1 -- and
+ * hence it is a simple dataspace. However, the
* selection, may be either point, hyperspace, or all.
*
*/
- if(H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
+ if (H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection")
} /* end if */
else {
HDassert(0 == npoints);
- if(H5S_select_none(new_space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
- } /* end else */
- } /* end if */
- else { /* projected space must be simple */
- hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */
- hsize_t new_space_maxdims[H5S_MAX_RANK];/* Maximum dimensions for new dataspace */
- unsigned rank_diff; /* Difference in ranks */
-
+ if (H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
+ } /* end else */
+ } /* end if */
+ else { /* projected space must be simple */
+ hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */
+ hsize_t new_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions for new dataspace */
+ unsigned rank_diff; /* Difference in ranks */
+
/* Set up the dimensions of the new, projected dataspace.
*
- * How we do this depends on whether we are projecting up into
- * increased dimensions, or down into a reduced number of
+ * How we do this depends on whether we are projecting up into
+ * increased dimensions, or down into a reduced number of
* dimensions.
*
- * If we are projecting up (the first half of the following
- * if statement), we copy the dimensions of the base data
- * space into the fastest changing dimensions of the new
+ * If we are projecting up (the first half of the following
+ * if statement), we copy the dimensions of the base data
+ * space into the fastest changing dimensions of the new
* projected dataspace, and set the remaining dimensions to
* one.
*
* If we are projecting down (the second half of the following
- * if statement), we just copy the dimensions with the most
+ * if statement), we just copy the dimensions with the most
* quickly changing dimensions into the dims for the projected
* data set.
*
- * This works, because H5S_select_shape_same() will return
+ * This works, because H5S_select_shape_same() will return
* true on selections of different rank iff:
*
* 1) the selection in the lower rank dataspace matches that
- * in the dimensions with the fastest changing indicies in
+ * in the dimensions with the fastest changing indices in
* the larger rank dataspace, and
*
* 2) the selection has thickness 1 in all ranks that appear
- * only in the higher rank dataspace (i.e. those with
- * more slowly changing indicies).
- */
- if(new_space_rank > base_space_rank) {
- hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
+ * only in the higher rank dataspace (i.e. those with
+ * more slowly changing indices).
+ */
+ if (new_space_rank > base_space_rank) {
+ hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
- /* we must copy the dimensions of the base space into
+ /* we must copy the dimensions of the base space into
* the fastest changing dimensions of the new space,
* and set the remaining dimensions to 1
*/
rank_diff = new_space_rank - base_space_rank;
- H5V_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
- H5V_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
- HDmemcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank);
- HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank);
- } /* end if */
+ H5VM_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
+ H5VM_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
+ H5MM_memcpy(&new_space_dims[rank_diff], base_space_dims,
+ sizeof(new_space_dims[0]) * base_space_rank);
+ H5MM_memcpy(&new_space_maxdims[rank_diff], base_space_maxdims,
+ sizeof(new_space_maxdims[0]) * base_space_rank);
+ } /* end if */
else { /* new_space_rank < base_space_rank */
- /* we must copy the fastest changing dimension of the
+ /* we must copy the fastest changing dimension of the
* base space into the dimensions of the new space.
*/
rank_diff = base_space_rank - new_space_rank;
- HDmemcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank);
- HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank);
+ H5MM_memcpy(new_space_dims, &base_space_dims[rank_diff],
+ sizeof(new_space_dims[0]) * new_space_rank);
+ H5MM_memcpy(new_space_maxdims, &base_space_maxdims[rank_diff],
+ sizeof(new_space_maxdims[0]) * new_space_rank);
} /* end else */
- /* now have the new space rank and dimensions set up --
+ /* now have the new space rank and dimensions set up --
* so we can create the new simple dataspace.
*/
- if(NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims)))
+ if (NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
-
+
/* No need to register the dataspace(i.e. get an ID) as
* we will just be discarding it shortly.
*/
@@ -1900,29 +2354,31 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
* dataspace. We must now project the selection in the base
* dataspace into the projected dataspace.
*/
- if(H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0)
+ if (H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection")
-
+
/* If we get this far, we have created the new dataspace, and projected
* the selection in the base dataspace into the new dataspace.
*
- * If the base dataspace is simple, check to see if the
- * offset_changed flag on the base selection has been set -- if so,
- * project the offset into the new dataspace and set the
+ * If the base dataspace is simple, check to see if the
+ * offset_changed flag on the base selection has been set -- if so,
+ * project the offset into the new dataspace and set the
* offset_changed flag.
*/
- if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) {
- if(new_space_rank > base_space_rank) {
+ if (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) {
+ if (new_space_rank > base_space_rank) {
HDmemset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff);
- HDmemcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank);
+ H5MM_memcpy(&new_space->select.offset[rank_diff], base_space->select.offset,
+ sizeof(new_space->select.offset[0]) * base_space_rank);
} /* end if */
else
- HDmemcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank);
+ H5MM_memcpy(new_space->select.offset, &base_space->select.offset[rank_diff],
+ sizeof(new_space->select.offset[0]) * new_space_rank);
/* Propagate the offset changed flag into the new dataspace. */
new_space->select.offset_changed = TRUE;
} /* end if */
- } /* end else */
+ } /* end else */
/* If we have done the projection correctly, the following assertion
* should hold.
@@ -1932,38 +2388,25 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
/* load the address of the new space into *new_space_ptr */
*new_space_ptr = new_space;
- /* now adjust the buffer if required */
- if(buf != NULL) {
- if(new_space_rank < base_space_rank) {
- /* a bit of pointer magic here:
- *
- * Since we can't do pointer arithmetic on void pointers, we first
- * cast buf to a pointer to byte -- i.e. uint8_t.
- *
- * We then multiply the projected space element offset we
- * calculated earlier by the supplied element size, add this
- * value to the type cast buf pointer, cast the result back
- * to a pointer to void, and assign the result to *adj_buf_ptr.
- */
- *adj_buf_ptr = (const void *)(((const uint8_t *)buf) +
- ((size_t)(projected_space_element_offset * element_size)));
- } /* end if */
+ /* return the buffer adjustment amount if required */
+ if (buf_adj != NULL) {
+ if (new_space_rank < base_space_rank) {
+ *buf_adj = (ptrdiff_t)(projected_space_element_offset * element_size);
+ }
else
/* No adjustment necessary */
- *adj_buf_ptr = buf;
- } /* end if */
+ *buf_adj = 0;
+ }
done:
/* Cleanup on error */
- if(ret_value < 0) {
- if(new_space && H5S_close(new_space) < 0)
+ if (ret_value < 0)
+ if (new_space && H5S_close(new_space) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_construct_projection() */
+} /* end H5S_select_construct_projection() */
-
/*--------------------------------------------------------------------------
NAME
H5S_select_fill
@@ -1989,13 +2432,15 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
+H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *_buf)
{
- H5S_sel_iter_t iter; /* Selection iteration info */
- hbool_t iter_init = 0; /* Selection iteration info has been initialized */
- hssize_t nelmts; /* Number of elements in selection */
- size_t max_elem; /* Total number of elements in selection */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
+ hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
+ hsize_t *off = NULL; /* Array to store sequence offsets */
+ size_t *len = NULL; /* Array to store sequence lengths */
+ hssize_t nelmts; /* Number of elements in selection */
+ size_t max_elem; /* Total number of elements in selection */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -2005,40 +2450,49 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b
HDassert(space);
HDassert(_buf);
+ /* Allocate the selection iterator */
+ if (NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
+
/* Initialize iterator */
- if(H5S_select_iter_init(&iter, space, fill_size) < 0)
+ if (H5S_select_iter_init(iter, space, fill_size, 0) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- iter_init = 1; /* Selection iteration info has been initialized */
+ iter_init = TRUE; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
- if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
+ if ((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
/* Compute the number of bytes to process */
- H5_ASSIGN_OVERFLOW(max_elem, nelmts, hssize_t, size_t);
+ H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
+
+ /* Allocate the offset & length arrays */
+ if (NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array")
+ if (NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array")
/* Loop, while elements left in selection */
- while(max_elem > 0) {
- hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
- size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
- size_t nseq; /* Number of sequences generated */
- size_t curr_seq; /* Current sequnce being worked on */
- size_t nelem; /* Number of elements used in sequences */
+ while (max_elem > 0) {
+ size_t nseq; /* Number of sequences generated */
+ size_t curr_seq; /* Current sequence being worked on */
+ size_t nelem; /* Number of elements used in sequences */
/* Get the sequences of bytes */
- if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
+ if (H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off,
+ len) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
/* Loop over sequences */
- for(curr_seq = 0; curr_seq < nseq; curr_seq++) {
- uint8_t *buf; /* Current location in buffer */
+ for (curr_seq = 0; curr_seq < nseq; curr_seq++) {
+ uint8_t *buf; /* Current location in buffer */
/* Get offset in memory buffer */
buf = (uint8_t *)_buf + off[curr_seq];
/* Fill each sequence in memory with fill value */
HDassert((len[curr_seq] % fill_size) == 0);
- H5V_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size));
+ H5VM_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size));
} /* end for */
/* Decrement number of elements left to process */
@@ -2046,10 +2500,724 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b
} /* end while */
done:
- /* Release resouces */
- if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ /* Release resources, if allocated */
+ if (len)
+ len = H5FL_SEQ_FREE(size_t, len);
+ if (off)
+ off = H5FL_SEQ_FREE(hsize_t, off);
+
+ /* Release selection iterator */
+ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
+ if (iter)
+ iter = H5FL_FREE(H5S_sel_iter_t, iter);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_fill() */
+} /* end H5S_select_fill() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_project_intersection
+
+ PURPOSE
+ Projects the intersection of of the selections of src_space and
+ src_intersect_space within the selection of src_space as a selection
+ within the selection of dst_space
+
+ USAGE
+ herr_t H5S_select_project_intersection(src_space,dst_space,src_intersect_space,proj_space,share_selection)
+ H5S_t *src_space; IN: Selection that is mapped to dst_space, and intersected with
+src_intersect_space H5S_t *dst_space; IN: Selection that is mapped to src_space H5S_t
+*src_intersect_space; IN: Selection whose intersection with src_space is projected to dst_space to obtain the
+result H5S_t **new_space_ptr; OUT: Will contain the result (intersection of src_intersect_space and src_space
+projected from src_space to dst_space) after the operation hbool_t share_selection; IN: Whether we are allowed
+to share structures inside dst_space with proj_space
+
+ RETURNS
+ Non-negative on success/Negative on failure.
+
+ DESCRIPTION
+ Projects the intersection of of the selections of src_space and
+ src_intersect_space within the selection of src_space as a selection
+ within the selection of dst_space. The result is placed in the
+ selection of new_space_ptr.
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space,
+ H5S_t **new_space_ptr, hbool_t share_selection)
+{
+ H5S_t *new_space = NULL; /* New dataspace constructed */
+ H5S_t *tmp_src_intersect_space = NULL; /* Temporary SIS converted from points->hyperslabs */
+ H5S_sel_iter_t *ss_iter = NULL; /* Selection iterator for src_space */
+ hbool_t ss_iter_init = FALSE; /* Whether ss_iter has been initialized */
+ H5S_sel_iter_t *ds_iter = NULL; /* Selection iterator for dst_space */
+ hbool_t ds_iter_init = FALSE; /* Whether ds_iter has been initialized */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(src_space);
+ HDassert(dst_space);
+ HDassert(src_intersect_space);
+ HDassert(new_space_ptr);
+ HDassert(H5S_GET_SELECT_NPOINTS(src_space) == H5S_GET_SELECT_NPOINTS(dst_space));
+ HDassert(H5S_GET_EXTENT_NDIMS(src_space) == H5S_GET_EXTENT_NDIMS(src_intersect_space));
+
+ if (NULL == (ss_iter = H5FL_CALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
+ if (NULL == (ds_iter = H5FL_CALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
+
+ /* Create new space, using dst extent. Start with "all" selection. */
+ if (NULL == (new_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create output dataspace")
+ if (H5S__extent_copy_real(&new_space->extent, &dst_space->extent, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy destination space extent")
+
+ /* If the intersecting space is "all", the intersection must be equal to the
+ * source space and the projection must be equal to the destination space */
+ if (H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_ALL) {
+ /* Copy the destination selection. */
+ if (H5S_select_copy(new_space, dst_space, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection")
+ } /* end if */
+ /* If any of the selections contain no elements, the projection must be
+ * "none" */
+ else if ((H5S_GET_SELECT_NPOINTS(src_intersect_space) == 0) || (H5S_GET_SELECT_NPOINTS(src_space) == 0) ||
+ (H5S_GET_SELECT_NPOINTS(dst_space) == 0)) {
+ /* Change to "none" selection */
+ if (H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ } /* end if */
+ else {
+ /* Handle scalar dataspaces. It should not be possible for the source
+ * intersect space or the source space to be scalar since scalar spaces
+ * only support all or none selections, and both of those cases are
+ * covered above, and the source intersect space must have the same
+ * rank, so it also cannot be scalar, as scalar dataspaces have a rank
+ * of 0. */
+ HDassert(H5S_GET_EXTENT_TYPE(src_space) != H5S_SCALAR);
+ HDassert(H5S_GET_EXTENT_TYPE(src_intersect_space) != H5S_SCALAR);
+
+ /* Check for scalar dst_space. In this case we simply check if the
+ * (single) point selected in src_space intersects src_intersect_space,
+ * if so select all in new_space, otherwise select none. */
+ if (H5S_GET_EXTENT_TYPE(dst_space) == H5S_SCALAR) {
+ hsize_t coords_start[H5S_MAX_RANK];
+ hsize_t coords_end[H5S_MAX_RANK];
+ htri_t intersect;
+
+ /* Get source space bounds. Should be a single point. */
+ if (H5S_SELECT_BOUNDS(src_space, coords_start, coords_end) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get source space bounds")
+ HDassert(0 == HDmemcmp(coords_start, coords_end,
+ H5S_GET_EXTENT_NDIMS(src_space) * sizeof(coords_start[0])));
+
+ /* Check for intersection */
+ if ((intersect = H5S_SELECT_INTERSECT_BLOCK(src_intersect_space, coords_start, coords_end)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't check for intersection")
+
+ /* Select all or none as appropriate */
+ if (intersect) {
+ if (H5S_select_all(new_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't select all")
+ } /* end if */
+ else if (H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ } /* end if */
+ else {
+ /* If the source intersect space is a point selection, convert it to a
+ * hyperslab (discarding ordering). We can get away with this because
+ * the order does not matter for the source intersect space */
+ /* Maybe we should just leave it as a point selection for the point by
+ * point algorithm? The search through the selection in
+ * H5S_SELECT_INTERSECT_BLOCK will likely be O(N) either way. -NAF */
+ if (H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_POINTS) {
+ H5S_pnt_node_t *curr_pnt = src_intersect_space->select.sel_info.pnt_lst->head;
+
+ /* Create dataspace and copy extent */
+ if (NULL == (tmp_src_intersect_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL,
+ "unable to create temporary source intersect dataspace")
+ if (H5S__extent_copy_real(&tmp_src_intersect_space->extent, &src_intersect_space->extent,
+ FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL,
+ "unable to copy source intersect space extent")
+
+ /* Iterate over points */
+ for (curr_pnt = src_intersect_space->select.sel_info.pnt_lst->head; curr_pnt;
+ curr_pnt = curr_pnt->next)
+ /* Add point to hyperslab selection */
+ if (H5S_hyper_add_span_element(tmp_src_intersect_space, src_intersect_space->extent.rank,
+ curr_pnt->pnt) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL,
+ "can't add point to temporary dataspace selection")
+
+ /* Redirect local src_intersect_space pointer (will not affect
+ * calling function) */
+ src_intersect_space = tmp_src_intersect_space;
+ } /* end for */
+
+ /* By this point, src_intersect_space must be a hyperslab selection */
+ HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_HYPERSLABS);
+
+ /* If either the source space or the destination space is a point
+ * selection, iterate element by element */
+ if ((H5S_GET_SELECT_TYPE(src_space) == H5S_SEL_POINTS) ||
+ (H5S_GET_SELECT_TYPE(dst_space) == H5S_SEL_POINTS)) {
+ hsize_t coords[H5S_MAX_RANK];
+ htri_t intersect;
+
+ /* Start with "none" selection */
+ if (H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+
+ /* Initialize iterators */
+ if (H5S_select_iter_init(ss_iter, src_space, 1, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "can't initialize source space selection iterator")
+ ss_iter_init = TRUE;
+ if (H5S_select_iter_init(ds_iter, dst_space, 1, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "can't initialize destination space selection iterator")
+ ds_iter_init = TRUE;
+
+ /* Iterate over points */
+ do {
+ HDassert(ss_iter->elmt_left > 0);
+ HDassert(ss_iter->elmt_left > 0);
+
+ /* Get SS coords */
+ if (H5S_SELECT_ITER_COORDS(ss_iter, coords) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL,
+ "can't get source selection coordinates")
+
+ /* Check for intersection */
+ if ((intersect = H5S_SELECT_INTERSECT_BLOCK(src_intersect_space, coords, coords)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't check for intersection")
+
+ /* Add point if it intersects */
+ if (intersect) {
+ /* Get DS coords */
+ if (H5S_SELECT_ITER_COORDS(ds_iter, coords) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL,
+ "can't get destination selection coordinates")
+
+ /* Add point to new_space */
+ if (H5S_select_elements(new_space, H5S_SELECT_APPEND, 1, coords) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL,
+ "can't add point to new selection")
+ } /* end if */
+
+ /* Advance iterators */
+ if (H5S_SELECT_ITER_NEXT(ss_iter, 1) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL,
+ "can't advacne source selection iterator")
+ ss_iter->elmt_left--;
+ if (H5S_SELECT_ITER_NEXT(ds_iter, 1) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL,
+ "can't advacne destination selection iterator")
+ ds_iter->elmt_left--;
+ } while (ss_iter->elmt_left > 0);
+ HDassert(H5S_SELECT_ITER_NELMTS(ds_iter) == 0);
+ } /* end if */
+ else {
+ HDassert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_NONE);
+ HDassert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_NONE);
+
+ /* Source and destination selections are all or hyperslab,
+ * intersecting selection is hyperslab. Call the hyperslab routine
+ * to project to another hyperslab selection. */
+ if (H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space,
+ share_selection) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL,
+ "can't project hyperslab onto destination selection")
+ } /* end else */
+ } /* end else */
+ } /* end else */
+
+ /* load the address of the new space into *new_space_ptr */
+ *new_space_ptr = new_space;
+
+done:
+ /* Cleanup on error */
+ if (ret_value < 0)
+ if (new_space && H5S_close(new_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
+
+ /* General cleanup */
+ if (tmp_src_intersect_space && H5S_close(tmp_src_intersect_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release temporary dataspace")
+ if (ss_iter_init && H5S_SELECT_ITER_RELEASE(ss_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release source selection iterator")
+ if (ds_iter_init && H5S_SELECT_ITER_RELEASE(ds_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release destination selection iterator")
+
+ ss_iter = H5FL_FREE(H5S_sel_iter_t, ss_iter);
+ ds_iter = H5FL_FREE(H5S_sel_iter_t, ds_iter);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_select_project_intersection() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_project_intersection
+
+ PURPOSE
+ Projects the intersection of of the selections of src_space_id and
+ src_intersect_space_id within the selection of src_space_id as a
+ selection within the selection of dst_space_id.
+
+ USAGE
+ hid_t H5Sselect_project_intersection(src_space_id,dst_space_d,src_intersect_space_id)
+ hid_t src_space_id; IN: Selection that is mapped to dst_space_id, and intersected with
+src_intersect_space_id hid_t dst_space_id; IN: Selection that is mapped to src_space_id hid_t
+src_intersect_space_id; IN: Selection whose intersection with src_space_id is projected to dst_space_id to
+obtain the result
+
+ RETURNS
+ A dataspace with a selection equal to the intersection of
+ src_intersect_space_id and src_space_id projected from src_space to
+ dst_space on success, negative on failure.
+
+ DESCRIPTION
+ Projects the intersection of of the selections of src_space and
+ src_intersect_space within the selection of src_space as a selection
+ within the selection of dst_space. The result is placed in the
+ selection of new_space_ptr.
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t
+H5Sselect_project_intersection(hid_t src_space_id, hid_t dst_space_id, hid_t src_intersect_space_id)
+{
+ H5S_t *src_space, *dst_space, *src_intersect_space; /* Input dataspaces */
+ H5S_t *proj_space = NULL; /* Output dataspace */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("i", "iii", src_space_id, dst_space_id, src_intersect_space_id);
+
+ /* Check args */
+ if (NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == (dst_space = (H5S_t *)H5I_object_verify(dst_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+ if (NULL == (src_intersect_space = (H5S_t *)H5I_object_verify(src_intersect_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Check numbers of points selected matches in source and destination */
+ if (H5S_GET_SELECT_NPOINTS(src_space) != H5S_GET_SELECT_NPOINTS(dst_space))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL,
+ "number of points selected in source space does not match that in destination space")
+
+ /* Check numbers of dimensions matches in source and source intersect spaces
+ */
+ if (H5S_GET_EXTENT_NDIMS(src_space) != H5S_GET_EXTENT_NDIMS(src_intersect_space))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL,
+ "rank of source space does not match rank of source intersect space")
+
+ /* Perform operation */
+ if (H5S_select_project_intersection(src_space, dst_space, src_intersect_space, &proj_space, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "can't project dataspace intersection")
+
+ /* Register */
+ if ((ret_value = H5I_register(H5I_DATASPACE, proj_space, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
+
+done:
+ if (ret_value < 0)
+ if (proj_space && H5S_close(proj_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_project_intersection() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_subtract
+
+ PURPOSE
+ Subtract one selection from another
+
+ USAGE
+ herr_t H5S_select_subtract(space,subtract_space)
+ H5S_t *space; IN/OUT: Selection to be operated on
+ H5S_t *subtract_space; IN: Selection that will be subtracted from space
+
+ RETURNS
+ Non-negative on success/Negative on failure.
+
+ DESCRIPTION
+ Removes any and all portions of space that are also present in
+ subtract_space. In essence, performs an A_NOT_B operation with the
+ two selections.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_subtract(H5S_t *space, H5S_t *subtract_space)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(space);
+ HDassert(subtract_space);
+
+ /* If either space is using the none selection, then we do not need to do
+ * anything */
+ if ((space->select.type->type != H5S_SEL_NONE) && (subtract_space->select.type->type != H5S_SEL_NONE)) {
+ /* If subtract_space is using the all selection, set space to none */
+ if (subtract_space->select.type->type == H5S_SEL_ALL) {
+ /* Change to "none" selection */
+ if (H5S_select_none(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ } /* end if */
+ /* If either selection is a point selection, fail currently */
+ else if ((subtract_space->select.type->type == H5S_SEL_POINTS) ||
+ (space->select.type->type == H5S_SEL_POINTS)) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported")
+ } /* end if */
+ else {
+ /* Check for all selection in space, convert to hyperslab */
+ if (space->select.type->type == H5S_SEL_ALL) {
+ /* Convert current "all" selection to "real" hyperslab selection */
+ /* Then allow operation to proceed */
+ hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */
+ hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */
+ hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */
+ hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */
+ unsigned u; /* Local index variable */
+
+ /* Fill in temporary information for the dimensions */
+ for (u = 0; u < space->extent.rank; u++) {
+ tmp_start[u] = 0;
+ tmp_stride[u] = 1;
+ tmp_count[u] = 1;
+ tmp_block[u] = space->extent.size[u];
+ } /* end for */
+
+ /* Convert to hyperslab selection */
+ if (H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) <
+ 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
+ } /* end if */
+
+ HDassert(space->select.type->type == H5S_SEL_HYPERSLABS);
+ HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS);
+
+ /* Both spaces are now hyperslabs, perform the operation */
+ if (H5S__modify_select(space, H5S_SELECT_NOTB, subtract_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab")
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_select_subtract() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ssel_iter_create
+ PURPOSE
+ Create a dataspace selection iterator for a dataspace's selection
+ USAGE
+ hid_t H5Ssel_iter_create(space)
+ hid_t space; IN: ID of the dataspace with selection to iterate over
+ RETURNS
+ Valid dataspace selection iterator ID on success, H5I_INVALID_HID on failure
+ DESCRIPTION
+ Creates a selection iterator and initializes it to start at the first
+ element selected in the dataspace.
+ PROGRAMMER
+ Quincey Koziol - February 11, 2019
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t
+H5Ssel_iter_create(hid_t space_id, size_t elmt_size, unsigned flags)
+{
+ H5S_t *space; /* Dataspace with selection to iterate over */
+ H5S_sel_iter_t *sel_iter; /* Selection iterator created */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "izIu", space_id, elmt_size, flags);
+
+ /* Check args */
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace")
+ if (elmt_size == 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, "element size must be greater than 0")
+ if (flags != (flags & H5S_SEL_ITER_ALL_PUBLIC_FLAGS))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, "invalid selection iterator flag")
+
+ /* Allocate the iterator */
+ if (NULL == (sel_iter = H5FL_MALLOC(H5S_sel_iter_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, H5I_INVALID_HID, "can't allocate selection iterator")
+
+ /* Add flag to indicate that this iterator is from an API call */
+ flags |= H5S_SEL_ITER_API_CALL;
+
+ /* Initialize the selection iterator */
+ if (H5S_select_iter_init(sel_iter, space, elmt_size, flags) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, H5I_INVALID_HID, "unable to initialize selection iterator")
+
+ /* Register */
+ if ((ret_value = H5I_register(H5I_SPACE_SEL_ITER, sel_iter, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTREGISTER, H5I_INVALID_HID,
+ "unable to register dataspace selection iterator ID")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ssel_iter_create() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ssel_iter_get_seq_list
+ PURPOSE
+ Retrieve a list of offset / length sequences for the elements in an iterator
+ USAGE
+ herr_t H5Ssel_iter_get_seq_list(sel_iter_id, maxseq, maxbytes, nseq, nbytes, off, len)
+ hid_t sel_iter_id; IN: ID of the dataspace selection iterator to retrieve sequence from
+ size_t maxseq; IN: Max. # of sequences to retrieve
+ size_t maxbytes; IN: Max. # of bytes to retrieve in sequences
+ size_t *nseq; OUT: # of sequences retrieved
+ size_t *nbytes; OUT: # of bytes retrieved, in all sequences
+ hsize_t *off; OUT: Array of sequence offsets
+ size_t *len; OUT: Array of sequence lengths
+ RETURNS
+ Non-negative on success / Negative on failure
+ DESCRIPTION
+ Retrieve a list of offset / length pairs (a list of "sequences") matching
+ the selected elements for an iterator, according to the iteration order for
+ the iterator. The lengths returned are in _bytes_, not elements.
+
+ Note that the iteration order for "all" and "hyperslab" selections is
+ row-major (i.e. "C-ordered"), but the iteration order for "point"
+ selections is "in order selected", unless the H5S_SEL_ITER_GET_SEQ_LIST_SORTED
+ flag is passed to H5Sset_iter_create for a point selection.
+
+ MAXSEQ and MAXBYTES specify the most sequences or bytes possible to
+ place into the OFF and LEN arrays. *NSEQ and *NBYTES return the actual
+ number of sequences and bytes put into the arrays.
+
+ Each call to H5Ssel_iter_get_seq_list() will retrieve the next set
+ of sequences for the selection being iterated over.
+
+ The total number of bytes possible to retrieve from a selection iterator
+ is the 'elmt_size' passed to H5Ssel_iter_create multiplied by the number
+ of elements selected in the dataspace the iterator was created from
+ (which can be retrieved with H5Sget_select_npoints). When there are no
+ further sequences of elements to retrieve, calls to this routine will
+ set *NSEQ and *NBYTES to zero.
+ PROGRAMMER
+ Quincey Koziol - February 11, 2019
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Ssel_iter_get_seq_list(hid_t sel_iter_id, size_t maxseq, size_t maxbytes, size_t *nseq /*out*/,
+ size_t *nbytes /*out*/, hsize_t *off /*out*/, size_t *len /*out*/)
+{
+ H5S_sel_iter_t *sel_iter; /* Dataspace selection iterator to operate on */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "izzxxxx", sel_iter_id, maxseq, maxbytes, nseq, nbytes, off, len);
+
+ /* Check args */
+ if (NULL == (sel_iter = (H5S_sel_iter_t *)H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator")
+ if (NULL == nseq)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "'nseq' pointer is NULL")
+ if (NULL == nbytes)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "'nbytes' pointer is NULL")
+ if (NULL == off)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "offset array pointer is NULL")
+ if (NULL == len)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "length array pointer is NULL")
+
+ /* Get the sequences of bytes */
+ if (maxseq > 0 && maxbytes > 0 && sel_iter->elmt_left > 0) {
+ if (H5S_SELECT_ITER_GET_SEQ_LIST(sel_iter, maxseq, maxbytes, nseq, nbytes, off, len) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed")
+ } /* end if */
+ else
+ *nseq = *nbytes = 0;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ssel_iter_get_seq_list() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ssel_iter_reset
+ PURPOSE
+ Resets a dataspace selection iterator back to an initial state.
+ USAGE
+ herr_t H5Ssel_iter_reset(sel_iter_id)
+ hid_t sel_iter_id; IN: ID of the dataspace selection iterator to
+ reset
+ hid_t space_id; IN: ID of the dataspace with selection to
+ iterate over
+ RETURNS
+ Non-negative on success / Negative on failure
+ DESCRIPTION
+ Resets a dataspace selection iterator back to an initial state so that
+ the iterator may be used for iteration once again.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Ssel_iter_reset(hid_t sel_iter_id, hid_t space_id)
+{
+ H5S_sel_iter_t *sel_iter;
+ H5S_t *space;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", sel_iter_id, space_id);
+
+ /* Check args */
+ if (NULL == (sel_iter = (H5S_sel_iter_t *)H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator")
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Call selection type-specific release routine */
+ if (H5S_SELECT_ITER_RELEASE(sel_iter) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL,
+ "problem releasing a selection iterator's type-specific info")
+
+ /* Simply re-initialize iterator */
+ if (H5S_select_iter_init(sel_iter, space, sel_iter->elmt_size, sel_iter->flags) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to re-initialize selection iterator")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ssel_iter_reset() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S__sel_iter_close_cb
+ *
+ * Purpose: Called when the ref count reaches zero on a selection iterator's ID
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S__sel_iter_close_cb(H5S_sel_iter_t *_sel_iter, void H5_ATTR_UNUSED **request)
+{
+ H5S_sel_iter_t *sel_iter = (H5S_sel_iter_t *)_sel_iter; /* The selection iterator to close */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(sel_iter);
+
+ /* Close the selection iterator object */
+ if (H5S_sel_iter_close(sel_iter) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "unable to close selection iterator");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S__sel_iter_close_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_sel_iter_close
+ *
+ * Purpose: Releases a dataspace selection iterator and its memory.
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, February 11, 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_sel_iter_close(H5S_sel_iter_t *sel_iter)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(sel_iter);
+
+ /* Call selection type-specific release routine */
+ if (H5S_SELECT_ITER_RELEASE(sel_iter) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL,
+ "problem releasing a selection iterator's type-specific info")
+
+ /* Release the structure */
+ sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_sel_iter_close() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Ssel_iter_close
+ PURPOSE
+ Close a dataspace selection iterator
+ USAGE
+ herr_t H5Ssel_iter_close(sel_iter_id)
+ hid_t sel_iter_id; IN: ID of the dataspace selection iterator to close
+ RETURNS
+ Non-negative on success / Negative on failure
+ DESCRIPTION
+ Close a dataspace selection iterator, releasing its state.
+ PROGRAMMER
+ Quincey Koziol - February 11, 2019
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Ssel_iter_close(hid_t sel_iter_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", sel_iter_id);
+
+ /* Check args */
+ if (NULL == H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator")
+
+ /* When the reference count reaches zero the resources are freed */
+ if (H5I_dec_app_ref(sel_iter_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing dataspace selection iterator ID")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ssel_iter_close() */