summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2019-11-26 17:38:25 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2019-11-26 17:38:25 (GMT)
commit9f61c26927ac74c4498cbebd7c9f2166d5f5b786 (patch)
tree81df83e8c53a80b61365d579b26aeb9532fe493f
parent5f3414e4d908fcdc8f3d31c624c4c157d87161e8 (diff)
parent4e12984b77cdd7615843d94f8de8d54db27476ac (diff)
downloadhdf5-9f61c26927ac74c4498cbebd7c9f2166d5f5b786.zip
hdf5-9f61c26927ac74c4498cbebd7c9f2166d5f5b786.tar.gz
hdf5-9f61c26927ac74c4498cbebd7c9f2166d5f5b786.tar.bz2
Merge pull request #2045 in HDFFV/hdf5 from ~NFORTNE2/hdf5_naf:select_adjust to develop
* commit '4e12984b77cdd7615843d94f8de8d54db27476ac': Move checking for zero offset in selection adjust calls to the selection callbacks. This makes the procedure for checking it consistent across selection types and between _s and _u, ensures it is always is performed even when called within the H5S package, and removes the redundant check that would occur when callins H5S_select_adjust_s() from outside the H5S package. Replace H5Sselect_adjust_u() and H5Shyper_adjust_s() with H5Sselect_adjust. Implement "adjust_s" callback for all selection types. Add range checking to H5Sselect_adjust().
-rw-r--r--src/H5Dchunk.c3
-rw-r--r--src/H5Sall.c33
-rw-r--r--src/H5Shyper.c112
-rw-r--r--src/H5Snone.c33
-rw-r--r--src/H5Spkg.h3
-rw-r--r--src/H5Spoint.c122
-rw-r--r--src/H5Sprivate.h4
-rw-r--r--src/H5Spublic.h3
-rw-r--r--src/H5Sselect.c76
9 files changed, 276 insertions, 113 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 947f611..4d139c7 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -2115,7 +2115,7 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
} /* end for */
/* Adjust the selection */
- if(H5S_hyper_adjust_s(chunk_info->mspace, chunk_adjust) < 0)
+ if(H5S_SELECT_ADJUST_S(chunk_info->mspace, chunk_adjust) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection")
} /* end else */
@@ -2128,7 +2128,6 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__create_chunk_mem_map_hyper() */
-
/*-------------------------------------------------------------------------
* Function: H5D__create_mem_map_1d
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 9d0a65a..4a4245d 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -66,6 +66,7 @@ static htri_t H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2);
static htri_t H5S__all_intersect_block(const H5S_t *space, const hsize_t *start,
const hsize_t *end);
static herr_t H5S__all_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S__all_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__all_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S__all_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
@@ -112,6 +113,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{
H5S__all_shape_same,
H5S__all_intersect_block,
H5S__all_adjust_u,
+ H5S__all_adjust_s,
H5S__all_project_scalar,
H5S__all_project_simple,
H5S__all_iter_init,
@@ -1043,6 +1045,37 @@ H5S__all_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *off
} /* end H5S__all_adjust_u() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__all_adjust_s
+ PURPOSE
+ Adjust an "all" selection by subtracting an offset
+ USAGE
+ herr_t H5S__all_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 selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__all_adjust_s(H5S_t H5_ATTR_UNUSED *space, const hssize_t H5_ATTR_UNUSED *offset)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check args */
+ HDassert(space);
+ HDassert(offset);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5S__all_adjust_s() */
+
+
/*-------------------------------------------------------------------------
* Function: H5S__all_project_scalar
*
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 2c7502a..ab06eff 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -194,6 +194,7 @@ static htri_t H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2);
static htri_t H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start,
const hsize_t *end);
static herr_t H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S__hyper_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__hyper_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
@@ -240,6 +241,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S__hyper_shape_same,
H5S__hyper_intersect_block,
H5S__hyper_adjust_u,
+ H5S__hyper_adjust_s,
H5S__hyper_project_scalar,
H5S__hyper_project_simple,
H5S__hyper_iter_init,
@@ -6475,39 +6477,50 @@ H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, unsigned rank,
static herr_t
H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset)
{
+ hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */
+ unsigned u; /* Local index variable */
+
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(space);
HDassert(offset);
- /* Subtract the offset from the "regular" coordinates, if they exist */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
- unsigned u; /* Local index variable */
+ /* Check for an all-zero offset vector */
+ for(u = 0; u < space->extent.rank; u++)
+ if(0 != offset[u]) {
+ non_zero_offset = TRUE;
+ break;
+ } /* end if */
- for(u = 0; u < space->extent.rank; u++) {
- HDassert(space->select.sel_info.hslab->diminfo.opt[u].start >= offset[u]);
- space->select.sel_info.hslab->diminfo.opt[u].start -= offset[u];
+ /* Only perform operation if the offset is non-zero */
+ if(non_zero_offset) {
+ /* Subtract the offset from the "regular" coordinates, if they exist */
+ /* (No need to rebuild the dimension info yet -QAK) */
+ if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ for(u = 0; u < space->extent.rank; u++) {
+ HDassert(space->select.sel_info.hslab->diminfo.opt[u].start >= offset[u]);
+ space->select.sel_info.hslab->diminfo.opt[u].start -= offset[u];
- /* Adjust the low & high bounds */
- HDassert(space->select.sel_info.hslab->diminfo.low_bounds[u] >= offset[u]);
- space->select.sel_info.hslab->diminfo.low_bounds[u] -= offset[u];
- space->select.sel_info.hslab->diminfo.high_bounds[u] -= offset[u];
- } /* end for */
- } /* end if */
+ /* Adjust the low & high bounds */
+ HDassert(space->select.sel_info.hslab->diminfo.low_bounds[u] >= offset[u]);
+ space->select.sel_info.hslab->diminfo.low_bounds[u] -= offset[u];
+ space->select.sel_info.hslab->diminfo.high_bounds[u] -= offset[u];
+ } /* end for */
+ } /* end if */
- /* Subtract the offset from the span tree coordinates, if they exist */
- if(space->select.sel_info.hslab->span_lst) {
- uint64_t op_gen; /* Operation generation value */
+ /* Subtract the offset from the span tree coordinates, if they exist */
+ if(space->select.sel_info.hslab->span_lst) {
+ uint64_t op_gen; /* Operation generation value */
- /* Acquire an operation generation value for this operation */
- op_gen = H5S__hyper_get_op_gen();
+ /* Acquire an operation generation value for this operation */
+ op_gen = H5S__hyper_get_op_gen();
- /* Perform adjustment */
- /* Always use op_info[0] since we own this op_info, so there can be no
- * simultaneous operations */
- H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, space->extent.rank, offset, 0, op_gen);
+ /* Perform adjustment */
+ /* Always use op_info[0] since we own this op_info, so there can be no
+ * simultaneous operations */
+ H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, space->extent.rank, offset, 0, op_gen);
+ } /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -6980,11 +6993,11 @@ H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, unsigned rank,
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_adjust_s
+ H5S__hyper_adjust_s
PURPOSE
Adjust a hyperslab selection by subtracting an offset
USAGE
- herr_t H5S_hyper_adjust_s(space,offset)
+ herr_t H5S__hyper_adjust_s(space,offset)
H5S_t *space; IN/OUT: Pointer to dataspace to adjust
const hssize_t *offset; IN: Offset to subtract
RETURNS
@@ -6996,8 +7009,8 @@ H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, unsigned rank,
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t
-H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset)
+static herr_t
+H5S__hyper_adjust_s(H5S_t *space, const hssize_t *offset)
{
hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */
unsigned u; /* Local index variable */
@@ -7048,48 +7061,7 @@ H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_adjust_s() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Shyper_adjust_s
- PURPOSE
- Adjust a hyperslab selection by subtracting an offset
- USAGE
- herr_t H5Shyper_adjust_s(space_id,offset)
- hid_t space_id; IN: ID of the dataspace to adjust
- const hssize_t *offset; IN: Offset to subtract
- RETURNS
- Non-negative on success, negative on failure
- DESCRIPTION
- Moves a hyperslab selection by subtracting an offset from it.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5Shyper_adjust_s(hid_t space_id, const hssize_t *offset)
-{
- H5S_t *space;
- 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(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection")
- if(NULL == offset)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "NULL offset pointer")
-
- if(H5S_hyper_adjust_s(space, offset) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection")
-
-done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Shyper_adjust_s() */
+} /* end H5S__hyper_adjust_s() */
/*--------------------------------------------------------------------------
@@ -7135,7 +7107,7 @@ H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset)
} /* end for */
/* Call the 'adjust' routine */
- if(H5S_hyper_adjust_s(space, space->select.offset) < 0)
+ if(H5S__hyper_adjust_s(space, space->select.offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection")
/* Zero out the selection offset */
@@ -7183,7 +7155,7 @@ H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset)
HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
/* Call the 'adjust' routine */
- if(H5S_hyper_adjust_s(space, old_offset) < 0)
+ if(H5S__hyper_adjust_s(space, old_offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection")
/* Copy the selection offset over */
diff --git a/src/H5Snone.c b/src/H5Snone.c
index c262d18..0949b2a 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -66,6 +66,7 @@ static htri_t H5S__none_shape_same(const H5S_t *space1, const H5S_t *space2);
static htri_t H5S__none_intersect_block(const H5S_t *space, const hsize_t *start,
const hsize_t *end);
static herr_t H5S__none_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S__none_adjust_s(H5S_t *space, const hssize_t *offset);
static herr_t H5S__none_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space,
hsize_t *offset);
@@ -113,6 +114,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{
H5S__none_shape_same,
H5S__none_intersect_block,
H5S__none_adjust_u,
+ H5S__none_adjust_s,
H5S__none_project_scalar,
H5S__none_project_simple,
H5S__none_iter_init,
@@ -954,6 +956,37 @@ H5S__none_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *of
} /* end H5S__none_adjust_u() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__none_adjust_s
+ PURPOSE
+ Adjust an "none" selection by subtracting an offset
+ USAGE
+ herr_t H5S__none_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 selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__none_adjust_s(H5S_t H5_ATTR_UNUSED *space, const hssize_t H5_ATTR_UNUSED *offset)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check args */
+ HDassert(space);
+ HDassert(offset);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5S__none_adjust_s() */
+
+
/*-------------------------------------------------------------------------
* Function: H5S__none_project_scalar
*
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 6809643..ba60cbf 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -261,6 +261,8 @@ typedef htri_t (*H5S_sel_shape_same_func_t)(const H5S_t *space1, const H5S_t *sp
typedef htri_t (*H5S_sel_intersect_block_func_t)(const H5S_t *space, const hsize_t *start, const hsize_t *end);
/* Method to adjust a selection by an offset */
typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset);
+/* Method to adjust a selection by an offset (signed) */
+typedef herr_t (*H5S_sel_adjust_s_func_t)(H5S_t *space, const hssize_t *offset);
/* Method to construct single element projection onto scalar dataspace */
typedef herr_t (*H5S_sel_project_scalar)(const H5S_t *space, hsize_t *offset);
/* Method to construct selection projection onto/into simple dataspace */
@@ -289,6 +291,7 @@ typedef struct {
H5S_sel_shape_same_func_t shape_same; /* Method to determine if two dataspaces' selections are the same shape */
H5S_sel_intersect_block_func_t intersect_block; /* Method to determine if a dataspaces' selection intersects a block */
H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */
+ H5S_sel_adjust_s_func_t adjust_s; /* Method to adjust a selection by an offset (signed) */
H5S_sel_project_scalar project_scalar; /* Method to construct scalar dataspace projection */
H5S_sel_project_simple project_simple; /* Method to construct simple dataspace projection */
H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index ea6c9c5..721211e 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -78,7 +78,8 @@ static htri_t H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2);
static htri_t H5S__point_intersect_block(const H5S_t *space, const hsize_t *start,
const hsize_t *end);
static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset);
-static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S__point_adjust_s(H5S_t *space, const hssize_t *offset);
+static herr_t H5S__point_project_scalar(const H5S_t *spasce, hsize_t *offset);
static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space,
hsize_t *offset);
static herr_t H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
@@ -128,6 +129,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S__point_shape_same,
H5S__point_intersect_block,
H5S__point_adjust_u,
+ H5S__point_adjust_s,
H5S__point_project_scalar,
H5S__point_project_simple,
H5S__point_iter_init,
@@ -2078,6 +2080,7 @@ done:
static herr_t
H5S__point_adjust_u(H5S_t *space, const hsize_t *offset)
{
+ hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */
H5S_pnt_node_t *node; /* Point node */
unsigned rank; /* Dataspace rank */
unsigned u; /* Local index variable */
@@ -2087,31 +2090,110 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset)
HDassert(space);
HDassert(offset);
- /* Iterate through the nodes, checking the bounds on each element */
- node = space->select.sel_info.pnt_lst->head;
- rank = space->extent.rank;
- while(node) {
- /* Adjust each coordinate for point node */
- for(u = 0; u < rank; u++) {
- /* Check for offset moving selection negative */
- HDassert(node->pnt[u] >= offset[u]);
+ /* Check for an all-zero offset vector */
+ for(u = 0; u < space->extent.rank; u++)
+ if(0 != offset[u]) {
+ non_zero_offset = TRUE;
+ break;
+ } /* end if */
+
+ /* Only perform operation if the offset is non-zero */
+ if(non_zero_offset) {
+ /* Iterate through the nodes, checking the bounds on each element */
+ node = space->select.sel_info.pnt_lst->head;
+ rank = space->extent.rank;
+ while(node) {
+ /* Adjust each coordinate for point node */
+ for(u = 0; u < rank; u++) {
+ /* Check for offset moving selection negative */
+ HDassert(node->pnt[u] >= offset[u]);
+
+ /* Adjust node's coordinate location */
+ node->pnt[u] -= offset[u];
+ } /* end for */
+
+ /* Advance to next point node in selection */
+ node = node->next;
+ } /* end while */
- /* Adjust node's coordinate location */
- node->pnt[u] -= offset[u];
+ /* update the bound box of the selection */
+ for(u = 0; u < rank; u++) {
+ space->select.sel_info.pnt_lst->low_bounds[u] -= offset[u];
+ space->select.sel_info.pnt_lst->high_bounds[u] -= offset[u];
} /* end for */
+ } /* end if */
- /* Advance to next point node in selection */
- node = node->next;
- } /* end while */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5S__point_adjust_u() */
- /* update the bound box of the selection */
- for(u = 0; u < rank; u++) {
- space->select.sel_info.pnt_lst->low_bounds[u] -= offset[u];
- space->select.sel_info.pnt_lst->high_bounds[u] -= offset[u];
- } /* end for */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__point_adjust_s
+ PURPOSE
+ Adjust a "point" selection by subtracting an offset
+ USAGE
+ herr_t H5S__point_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 point selection by subtracting an offset from it.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__point_adjust_s(H5S_t *space, const hssize_t *offset)
+{
+ hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */
+ H5S_pnt_node_t *node; /* Point node */
+ unsigned rank; /* Dataspace rank */
+ unsigned u; /* Local index variable */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(space);
+ HDassert(offset);
+
+ /* Check for an all-zero offset vector */
+ for(u = 0; u < space->extent.rank; u++)
+ if(0 != offset[u]) {
+ non_zero_offset = TRUE;
+ break;
+ } /* end if */
+
+ /* Only perform operation if the offset is non-zero */
+ if(non_zero_offset) {
+ /* Iterate through the nodes, checking the bounds on each element */
+ node = space->select.sel_info.pnt_lst->head;
+ rank = space->extent.rank;
+ while(node) {
+ /* Adjust each coordinate for point node */
+ for(u = 0; u < rank; u++) {
+ /* Check for offset moving selection negative */
+ HDassert((hssize_t)node->pnt[u] >= offset[u]);
+
+ /* Adjust node's coordinate location */
+ node->pnt[u] = (hsize_t)((hssize_t)node->pnt[u] - offset[u]);
+ } /* end for */
+
+ /* Advance to next point node in selection */
+ node = node->next;
+ } /* end while */
+
+ /* update the bound box of the selection */
+ for(u = 0; u < rank; u++) {
+ HDassert((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] >= offset[u]);
+ space->select.sel_info.pnt_lst->low_bounds[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] - offset[u]);
+ space->select.sel_info.pnt_lst->high_bounds[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->high_bounds[u] - offset[u]);
+ } /* end for */
+ } /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S__point_adjust_u() */
+} /* end H5S__point_adjust_s() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 41c8b95..f29319f 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -145,6 +145,7 @@ typedef struct H5S_sel_iter_op_t {
#define H5S_SELECT_IS_SINGLE(S) ((*(S)->select.type->is_single)(S))
#define H5S_SELECT_IS_REGULAR(S) ((*(S)->select.type->is_regular)(S))
#define H5S_SELECT_ADJUST_U(S,O) ((*(S)->select.type->adjust_u)(S, O))
+#define H5S_SELECT_ADJUST_S(S,O) ((*(S)->select.type->adjust_s)(S, O))
#define H5S_SELECT_PROJECT_SCALAR(S,O) ((*(S)->select.type->project_scalar)(S, O))
#define H5S_SELECT_PROJECT_SIMPLE(S,NS, O) ((*(S)->select.type->project_simple)(S, NS, O))
#define H5S_SELECT_ITER_COORDS(ITER,COORDS) ((*(ITER)->type->iter_coords)(ITER,COORDS))
@@ -170,6 +171,7 @@ typedef struct H5S_sel_iter_op_t {
#define H5S_SELECT_IS_SINGLE(S) (H5S_select_is_single(S))
#define H5S_SELECT_IS_REGULAR(S) (H5S_select_is_regular(S))
#define H5S_SELECT_ADJUST_U(S,O) (H5S_select_adjust_u(S, O))
+#define H5S_SELECT_ADJUST_S(S,O) (H5S_select_adjust_s(S, O))
#define H5S_SELECT_PROJECT_SCALAR(S,O) (H5S_select_project_scalar(S, O))
#define H5S_SELECT_PROJECT_SIMPLE(S,NS,O) (H5S_select_project_simple(S, NS, O))
#define H5S_SELECT_ITER_COORDS(ITER,COORDS) (H5S_select_iter_coords(ITER,COORDS))
@@ -257,6 +259,7 @@ H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space);
H5_DLL htri_t H5S_select_is_single(const H5S_t *space);
H5_DLL htri_t H5S_select_is_regular(const H5S_t *space);
H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset);
+H5_DLL herr_t H5S_select_adjust_s(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_select_project_scalar(const H5S_t *space, hsize_t *offset);
H5_DLL herr_t H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
H5_DLL herr_t H5S_select_project_intersection(const H5S_t *src_space,
@@ -282,7 +285,6 @@ H5_DLL herr_t H5S_combine_hyperslab(H5S_t *old_space, H5S_seloper_t op,
const hsize_t *block, H5S_t **new_space);
H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank,
const hsize_t *coords);
-H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset);
H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset);
H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset);
H5_DLL herr_t H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size);
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 263a880..f7c5ae7 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -143,7 +143,7 @@ H5_DLL H5S_sel_type H5Sget_select_type(hid_t spaceid);
H5_DLL hssize_t H5Sget_select_npoints(hid_t spaceid);
H5_DLL herr_t H5Sselect_copy(hid_t dst_id, hid_t src_id);
H5_DLL htri_t H5Sselect_valid(hid_t spaceid);
-H5_DLL herr_t H5Sselect_adjust_u(hid_t spaceid, const hsize_t *offset);
+H5_DLL herr_t H5Sselect_adjust(hid_t spaceid, const hssize_t *offset);
H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[],
hsize_t end[]);
H5_DLL htri_t H5Sselect_shape_same(hid_t space1_id, hid_t space2_id);
@@ -171,7 +171,6 @@ H5_DLL htri_t H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[],
H5_DLL hssize_t H5Sget_select_hyper_nblocks(hid_t spaceid);
H5_DLL herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
hsize_t numblocks, hsize_t buf[/*numblocks*/]);
-H5_DLL herr_t H5Shyper_adjust_s(hid_t space_id, const hssize_t *offset);
H5_DLL hid_t H5Sselect_project_intersection(hid_t src_space_id,
hid_t dst_space_id, hid_t src_intersect_space_id);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index c506218..bf0441f 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -947,8 +947,6 @@ H5S_select_is_regular(const H5S_t *space)
herr_t
H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
{
- hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -957,23 +955,55 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
HDassert(space);
HDassert(offset);
- /* Check for an all-zero offset vector */
- for(u = 0; u < space->extent.rank; u++)
- if(0 != offset[u]) {
- non_zero_offset = TRUE;
- break;
- } /* end if */
-
- /* Only perform operation if the offset is non-zero */
- if(non_zero_offset)
- ret_value = (*space->select.type->adjust_u)(space, offset);
+ /* Perform operation */
+ ret_value = (*space->select.type->adjust_u)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_adjust_u() */
+
/*--------------------------------------------------------------------------
NAME
- H5Sselect_adjust_u
+ 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
@@ -990,25 +1020,35 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Sselect_adjust_u(hid_t space_id, const hsize_t *offset)
+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*h", space_id, offset);
+ 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")
- if(H5S_select_adjust_u(space, offset) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection");
+ /* 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_u() */
+} /* end H5Sselect_adjust() */
/*--------------------------------------------------------------------------