diff options
Diffstat (limited to 'src/H5Sselect.c')
-rw-r--r-- | src/H5Sselect.c | 277 |
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() */ + |