summaryrefslogtreecommitdiffstats
path: root/src/H5Sselect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Sselect.c')
-rw-r--r--src/H5Sselect.c277
1 files changed, 262 insertions, 15 deletions
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index e04ae16..0af3dfa 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -63,7 +63,9 @@ static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
herr_t
H5S_select_offset(H5S_t *space, const hssize_t *offset)
{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
/* Check args */
HDassert(space);
@@ -76,7 +78,14 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset)
/* Indicate that the offset was changed */
space->select.offset_changed = TRUE;
- FUNC_LEAVE_NOAPI(SUCCEED)
+ /* If the selection is 'hyper', update the selection due to changed offset
+ */
+ if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS)
+ if(H5S_hyper_clip_to_extent(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_offset() */
@@ -218,7 +227,7 @@ H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
*-------------------------------------------------------------------------
*/
hssize_t
-H5S_select_serial_size(const H5S_t *space)
+H5S_select_serial_size(const H5F_t *f, const H5S_t *space)
{
hssize_t ret_value; /* Return value */
@@ -227,7 +236,7 @@ H5S_select_serial_size(const H5S_t *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)(f, space);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_serial_size() */
@@ -258,7 +267,7 @@ H5S_select_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_serialize(const H5S_t *space, uint8_t **p)
+H5S_select_serialize(const H5F_t *f, const H5S_t *space, uint8_t **p)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -268,7 +277,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t **p)
HDassert(p);
/* Call the selection type's serialize function */
- ret_value=(*space->select.type->serialize)(space,p);
+ ret_value = (*space->select.type->serialize)(f, space, p);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_serialize() */
@@ -450,11 +459,13 @@ H5S_select_valid(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_deserialize (H5S_t **space, const uint8_t **p)
+H5S_select_deserialize(const H5F_t *f, H5S_t **space, const uint8_t **p)
{
H5S_t *tmp_space; /* Pointer to actual dataspace to use, either
*space or a newly allocated one */
uint32_t sel_type; /* Pointer to the selection type */
+ uint32_t version; /* Version number */
+ uint8_t flags = 0; /* Flags */
herr_t ret_value=FAIL; /* return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -472,8 +483,23 @@ H5S_select_deserialize (H5S_t **space, const uint8_t **p)
/* Decode selection type */
UINT32DECODE(*p, sel_type);
- /* Skip over the remainder of the header */
- *p += 12;
+ /* Decode version */
+ UINT32DECODE(*p, version);
+
+ if(version >= (uint32_t)2) {
+ /* Decode flags */
+ flags = *(*p)++;
+
+ /* Check for unknown flags */
+ if(flags & ~H5S_SELECT_FLAG_BITS)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "unknown flag for selection")
+
+ /* Skip over the remainder of the header */
+ *p += 4;
+ } /* end if */
+ else
+ /* Skip over the remainder of the header */
+ *p += 8;
/* Decode and check or patch rank for point and hyperslab selections */
if((sel_type == H5S_SEL_POINTS) || (sel_type == H5S_SEL_HYPERSLABS)) {
@@ -482,9 +508,14 @@ H5S_select_deserialize (H5S_t **space, const uint8_t **p)
/* Decode the rank of the point selection */
UINT32DECODE(*p,rank);
- if(!*space)
+ if(!*space) {
+ hsize_t dims[H5S_MAX_RANK];
+
/* Patch the rank of the allocated dataspace */
- tmp_space->extent.rank = rank;
+ (void)HDmemset(dims, 0, (size_t)rank * sizeof(dims[0]));
+ if(H5S__set_extent_simple(tmp_space, rank, dims, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set dimensions")
+ } /* end if */
else
/* Verify the rank of the provided dataspace */
if(rank != tmp_space->extent.rank)
@@ -494,19 +525,19 @@ H5S_select_deserialize (H5S_t **space, const uint8_t **p)
/* Make routine for selection type */
switch(sel_type) {
case H5S_SEL_POINTS: /* Sequence of points selected */
- ret_value = (*H5S_sel_point->deserialize)(tmp_space, p);
+ ret_value = (*H5S_sel_point->deserialize)(f, tmp_space, version, flags, p);
break;
case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
- ret_value = (*H5S_sel_hyper->deserialize)(tmp_space, p);
+ ret_value = (*H5S_sel_hyper->deserialize)(f, tmp_space, version, flags, p);
break;
case H5S_SEL_ALL: /* Entire extent selected */
- ret_value = (*H5S_sel_all->deserialize)(tmp_space, p);
+ ret_value = (*H5S_sel_all->deserialize)(f, tmp_space, version, flags, p);
break;
case H5S_SEL_NONE: /* Nothing selected */
- ret_value = (*H5S_sel_none->deserialize)(tmp_space, p);
+ ret_value = (*H5S_sel_none->deserialize)(f, tmp_space, version, flags, p);
break;
default:
@@ -668,6 +699,44 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *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; /* return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check args */
+ HDassert(space);
+
+ ret_value = (*space->select.type->unlim_dim)(space);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_get_select_unlim_dim() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_is_contiguous
PURPOSE
Determines if a selection is contiguous in the dataspace
@@ -2101,3 +2170,181 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_fill() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_project_intersection
+
+ PURPOSE
+ VDSINC
+
+ USAGE
+ VDSINC
+
+ RETURNS
+ Non-negative on success/Negative on failure.
+
+ DESCRIPTION
+ VDSINC
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
+ const H5S_t *src_intersect_space, H5S_t **new_space_ptr)
+{
+ H5S_t *new_space = NULL; /* New dataspace constructed */
+ 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);
+
+ /* 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")
+
+ /* Set offset to zeros */
+ (void)HDmemset(new_space->select.offset, 0, (size_t)new_space->extent.rank * sizeof(new_space->select.offset[0]));
+ new_space->select.offset_changed = FALSE;
+
+ /* 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(src_intersect_space->select.type->type == 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 spaces are "none", the projection must also be "none" */
+ else if((src_intersect_space->select.type->type == H5S_SEL_NONE)
+ || (src_space->select.type->type == H5S_SEL_NONE)
+ || (dst_space->select.type->type == H5S_SEL_NONE)) {
+ /* Change to "none" selection */
+ if(H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ } /* end if */
+ /* If any of the spaces use point selection, fall back to general algorithm
+ */
+ else if((src_intersect_space->select.type->type == H5S_SEL_POINTS)
+ || (src_space->select.type->type == H5S_SEL_POINTS)
+ || (dst_space->select.type->type == H5S_SEL_POINTS))
+ HDassert(0 && "Not yet implemented...");//VDSINC
+ else {
+ HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS);
+ /* Intersecting space is hyperslab selection. Call the hyperslab
+ * routine to project to another hyperslab selection. */
+ if(H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't project hyperslab ondot destination selection")
+ } /* 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")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_select_project_intersection() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_subtract
+
+ PURPOSE
+ VDSINC
+
+ USAGE
+ VDSINC
+
+ RETURNS
+ Non-negative on success/Negative on failure.
+
+ DESCRIPTION
+ VDSINC
+
+ 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) {
+ HDassert(0 && "Checking code coverage...");//VDSINC
+ /* Change to "none" selection */
+ if(H5S_select_none(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ } /* end if */
+ else {
+ /* Check for point selection in subtract_space, convert to
+ * hyperslab */
+ if(subtract_space->select.type->type == H5S_SEL_POINTS)
+ HDassert(0 && "Not yet implemented...");//VDSINC
+
+ /* Check for point or 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[H5O_LAYOUT_NDIMS]; /* Temporary start information */
+ hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */
+ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */
+ unsigned i; /* Local index variable */
+
+ /* Fill in temporary information for the dimensions */
+ for(i = 0; i < space->extent.rank; i++) {
+ tmp_start[i] = 0;
+ tmp_stride[i] = 1;
+ tmp_count[i] = 1;
+ tmp_block[i] = space->extent.size[i];
+ } /* 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 */
+ else if(space->select.type->type == H5S_SEL_POINTS)
+ HDassert(0 && "Not yet implemented...");//VDSINC
+
+ 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__hyper_subtract(space, subtract_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab")
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_select_subtract() */
+