#include "H5Smodule.h"
#include "H5private.h"
#include "H5Dprivate.h"
#include "H5Eprivate.h"
#include "H5FLprivate.h"
#include "H5Iprivate.h"
#include "H5MMprivate.h"
#include "H5Spkg.h"
#include "H5VMprivate.h"
#define H5S_SEL_ITER_ALL_PUBLIC_FLAGS (H5S_SEL_ITER_GET_SEQ_LIST_SORTED | \
H5S_SEL_ITER_SHARE_WITH_DATASPACE)
#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);
#endif
H5FL_DEFINE(H5S_sel_iter_t);
H5FL_SEQ_EXTERN(size_t);
H5FL_SEQ_EXTERN(hsize_t);
herr_t
H5S_select_offset(H5S_t *space, const hssize_t *offset)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(0 < space->extent.rank && space->extent.rank <= H5S_MAX_RANK);
HDassert(offset);
H5MM_memcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank);
space->select.offset_changed = TRUE;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5Soffset_simple(hid_t space_id, const hssize_t *offset)
{
H5S_t *space;
herr_t ret_value = SUCCEED;
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_ATOM, H5E_BADATOM, 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_ATOM, 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")
if(H5S_select_offset(space, offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset")
done:
FUNC_LEAVE_API(ret_value)
}
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);
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")
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)
}
herr_t
H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI(FAIL)
HDassert(dst);
HDassert(src);
if(H5S_SELECT_RELEASE(dst) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection")
dst->select = src->select;
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)
}
herr_t
H5S_select_release(H5S_t *ds)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(ds);
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)
}
hssize_t
H5S_select_serial_size(const H5S_t *space)
{
hssize_t ret_value = -1;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->serial_size)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_serialize(const H5S_t *space, uint8_t **p)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(p);
ret_value = (*space->select.type->serialize)(space, p);
FUNC_LEAVE_NOAPI(ret_value)
}
hssize_t
H5Sget_select_npoints(hid_t spaceid)
{
H5S_t *space;
hssize_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE1("Hs", "i", spaceid);
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)
}
H5_ATTR_PURE hsize_t
H5S_get_select_npoints(const H5S_t *space)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
FUNC_LEAVE_NOAPI(space->select.num_elem)
}
htri_t
H5Sselect_valid(hid_t spaceid)
{
H5S_t *space;
htri_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE1("t", "i", spaceid);
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)
}
htri_t
H5S_select_valid(const H5S_t *space)
{
htri_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->is_valid)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_deserialize(H5S_t **space, const uint8_t **p)
{
uint32_t sel_type;
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
UINT32DECODE(*p, sel_type);
switch(sel_type) {
case H5S_SEL_POINTS:
ret_value = (*H5S_sel_point->deserialize)(space, p);
break;
case H5S_SEL_HYPERSLABS:
ret_value = (*H5S_sel_hyper->deserialize)(space, p);
break;
case H5S_SEL_ALL:
ret_value = (*H5S_sel_all->deserialize)(space, p);
break;
case H5S_SEL_NONE:
ret_value = (*H5S_sel_none->deserialize)(space, p);
break;
default:
break;
}
if(ret_value < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
{
H5S_t *space;
herr_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "i*h*h", spaceid, start, end);
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)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
ret_value = H5S_SELECT_BOUNDS(space, start, end);
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(start);
HDassert(end);
ret_value = (*space->select.type->bounds)(space, start, end);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(offset);
ret_value = (*space->select.type->offset)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
}
int
H5S_get_select_unlim_dim(const H5S_t *space)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->unlim_dim)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_get_select_num_elem_non_unlim(const H5S_t *space,
hsize_t *num_elem_non_unlim)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
HDassert(num_elem_non_unlim);
if(!space->select.type->num_elem_non_unlim)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type has no num_elem_non_unlim 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)
}
htri_t
H5S_select_is_contiguous(const H5S_t *space)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->is_contiguous)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5S_select_is_single(const H5S_t *space)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->is_single)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5S_select_is_regular(const H5S_t *space)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = (*space->select.type->is_regular)(space);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(offset);
ret_value = (*space->select.type->adjust_u)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_adjust_s(H5S_t *space, const hssize_t *offset)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(offset);
ret_value = (*space->select.type->adjust_s)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
}
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;
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")
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)
}
herr_t
H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(offset);
ret_value = (*space->select.type->project_scalar)(space, offset);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
HDassert(new_space);
HDassert(offset);
ret_value = (*space->select.type->project_simple)(space, new_space, offset);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space,
size_t elmt_size, unsigned flags)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(sel_iter);
HDassert(space);
sel_iter->rank = space->extent.rank;
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);
}
sel_iter->elmt_size = elmt_size;
sel_iter->elmt_left = space->select.num_elem;
sel_iter->flags = flags;
ret_value = (*space->select.type->iter_init)(space, sel_iter);
HDassert(sel_iter->type);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(sel_iter);
HDassert(coords);
ret_value = (*sel_iter->type->iter_coords)(sel_iter, coords);
FUNC_LEAVE_NOAPI(ret_value)
}
#ifdef LATER
static herr_t
H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
{
herr_t ret_value;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(iter);
HDassert(start);
HDassert(end);
ret_value = (*iter->type->iter_block)(iter, start, end);
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
hsize_t
H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter)
{
hsize_t ret_value = 0;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(sel_iter);
ret_value = (*sel_iter->type->iter_nelmts)(sel_iter);
FUNC_LEAVE_NOAPI(ret_value)
}
#ifdef LATER
static htri_t
H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter)
{
herr_t ret_value;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(iter);
ret_value = (*iter->type->iter_has_next_block)(iter);
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
herr_t
H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(iter);
HDassert(nelem>0);
ret_value = (*iter->type->iter_next)(iter, nelem);
iter->elmt_left-=nelem;
FUNC_LEAVE_NOAPI(ret_value)
}
#ifdef LATER
static herr_t
H5S_select_iter_next_block(H5S_sel_iter_t *iter)
{
herr_t ret_value;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(iter);
ret_value = (*iter->type->iter_next_block)(iter);
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
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;
FUNC_ENTER_NOAPI_NOINIT
HDassert(iter);
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)
}
herr_t
H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
{
herr_t ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(sel_iter);
ret_value = (*sel_iter->type->iter_release)(sel_iter);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space,
const H5S_sel_iter_op_t *op, void *op_data)
{
H5S_sel_iter_t *iter = NULL;
hbool_t iter_init = FALSE;
hsize_t *off = NULL;
size_t *len = NULL;
hssize_t nelmts;
hsize_t space_size[H5S_MAX_RANK];
size_t max_elem;
size_t elmt_size;
unsigned ndims;
herr_t user_ret = 0;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(buf);
HDassert(type);
HDassert(space);
HDassert(op);
if(0 == (elmt_size = H5T_get_size(type)))
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
if(NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
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;
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
ndims = space->extent.rank;
if(ndims > 0) {
HDassert(space->extent.size);
H5MM_memcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
}
space_size[ndims] = elmt_size;
H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
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")
while(max_elem > 0 && user_ret == 0) {
size_t nelem;
size_t nseq;
size_t curr_seq;
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")
for(curr_seq = 0; curr_seq < nseq && user_ret == 0; curr_seq++) {
hsize_t curr_off;
size_t curr_len;
curr_off = off[curr_seq];
curr_len = len[curr_seq];
while(curr_len > 0 && user_ret == 0) {
hsize_t coords[H5S_MAX_RANK];
hsize_t tmp_off;
uint8_t *loc;
int i;
for(i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
coords[i] = tmp_off % space_size[i];
tmp_off /= space_size[i];
}
loc = (unsigned char *)buf + curr_off;
switch(op->op_type) {
case H5S_SEL_ITER_OP_APP:
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:
user_ret = (op->u.lib_op)(loc, type, ndims, coords, op_data);
break;
default:
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported op type")
}
if(user_ret < 0)
HERROR(H5E_DATASPACE, H5E_CANTNEXT, "iteration operator failed");
curr_off += elmt_size;
curr_len -= elmt_size;
}
}
max_elem -= nelem;
}
ret_value = user_ret;
done:
if(len)
len = H5FL_SEQ_FREE(size_t, len);
if(off)
off = H5FL_SEQ_FREE(hsize_t, off);
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_sel_type
H5Sget_select_type(hid_t space_id)
{
H5S_t *space;
H5S_sel_type ret_value;
FUNC_ENTER_API(H5S_SEL_ERROR)
H5TRACE1("St", "i", space_id);
if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace")
ret_value = H5S_GET_SELECT_TYPE(space);
done:
FUNC_LEAVE_API(ret_value)
}
H5_ATTR_PURE H5S_sel_type
H5S_get_select_type(const H5S_t *space)
{
H5S_sel_type ret_value = H5S_SEL_ERROR;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
ret_value = H5S_GET_SELECT_TYPE(space);
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
{
H5S_sel_iter_t *iter_a = NULL;
H5S_sel_iter_t *iter_b = NULL;
hbool_t iter_a_init = FALSE;
hbool_t iter_b_init = FALSE;
htri_t ret_value = TRUE;
FUNC_ENTER_NOAPI(FAIL)
HDassert(space1);
HDassert(space2);
if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
HGOTO_DONE(FALSE)
if(space1->extent.rank > 0 && space2->extent.rank > 0) {
const H5S_t *space_a;
const H5S_t *space_b;
unsigned space_a_rank;
unsigned space_b_rank;
int space_a_dim;
int space_b_dim;
H5S_sel_type sel_a_type;
H5S_sel_type sel_b_type;
if(space1->extent.rank >= space2->extent.rank) {
space_a = space1;
space_b = space2;
}
else {
space_a = space2;
space_b = space1;
}
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);
sel_a_type = H5S_GET_SELECT_TYPE(space_a);
sel_b_type = H5S_GET_SELECT_TYPE(space_b);
if(sel_a_type != H5S_SEL_NONE && sel_b_type != H5S_SEL_NONE) {
hsize_t low_a[H5S_MAX_RANK];
hsize_t low_b[H5S_MAX_RANK];
hsize_t high_a[H5S_MAX_RANK];
hsize_t high_b[H5S_MAX_RANK];
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")
space_a_dim = (int)space_a_rank - 1;
space_b_dim = (int)space_b_rank - 1;
while(space_b_dim >= 0) {
HDassert(low_a[space_a_dim] <= high_a[space_a_dim]);
HDassert(low_a[space_b_dim] <= high_a[space_b_dim]);
if((high_a[space_a_dim] - low_a[space_a_dim])
!= (high_b[space_b_dim] - low_b[space_b_dim]))
HGOTO_DONE(FALSE)
space_a_dim--;
space_b_dim--;
}
while(space_a_dim >= 0) {
HDassert(low_a[space_a_dim] <= high_a[space_a_dim]);
if(low_a[space_a_dim] != high_a[space_a_dim])
HGOTO_DONE(FALSE)
space_a_dim--;
}
if(H5S_SELECT_IS_SINGLE(space_a) && H5S_SELECT_IS_SINGLE(space_b)) {
HGOTO_DONE(TRUE)
}
}
if(sel_a_type == sel_b_type)
ret_value = (*space_a->select.type->shape_same)(space_a, space_b);
else {
hsize_t start_a[H5S_MAX_RANK];
hsize_t start_b[H5S_MAX_RANK];
hsize_t end_a[H5S_MAX_RANK];
hsize_t end_b[H5S_MAX_RANK];
hssize_t offset[H5S_MAX_RANK];
hbool_t first_block = TRUE;
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")
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 = 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 = TRUE;
while(1) {
htri_t status_a, status_b;
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)
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;
if(first_block) {
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)
offset[space_a_dim] = (hssize_t)start_b[space_b_dim] - (hssize_t)start_a[space_a_dim];
space_a_dim--;
space_b_dim--;
}
while(space_a_dim >= 0) {
if(start_a[space_a_dim] != end_a[space_a_dim])
HGOTO_DONE(FALSE)
space_a_dim--;
}
first_block = FALSE;
}
else {
while(space_b_dim >= 0) {
if((hsize_t)((hssize_t)start_a[space_a_dim] + offset[space_a_dim]) != start_b[space_b_dim])
HGOTO_DONE(FALSE)
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--;
space_b_dim--;
}
while(space_a_dim >= 0) {
if(start_a[space_a_dim] != end_a[space_a_dim])
HGOTO_DONE(FALSE)
space_a_dim--;
}
}
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)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b")
if((status_a == FALSE) && (status_b == FALSE))
break;
else if(status_a != status_b)
HGOTO_DONE(FALSE)
else {
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")
}
}
}
}
done:
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)
}
htri_t
H5Sselect_shape_same(hid_t space1_id, hid_t space2_id)
{
H5S_t *space1, *space2;
htri_t ret_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)
}
htri_t
H5S_select_intersect_block(const H5S_t *space, const hsize_t *start,
const hsize_t *end)
{
htri_t ret_value = TRUE;
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
HDassert(start);
HDassert(end);
if(H5S_SEL_NONE != H5S_GET_SELECT_TYPE(space)) {
hsize_t low[H5S_MAX_RANK];
hsize_t high[H5S_MAX_RANK];
unsigned u;
if(H5S_SELECT_BOUNDS(space, low, high) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for dataspace")
for(u = 0; u < space->extent.rank; u++)
if(!H5S_RANGE_OVERLAP(low[u], high[u], start[u], end[u]))
HGOTO_DONE(FALSE)
}
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)
}
htri_t
H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, const hsize_t *end)
{
H5S_t *space;
unsigned u;
htri_t ret_value = FAIL;
FUNC_ENTER_API(FAIL)
H5TRACE3("t", "i*h*h", space_id, start, end);
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")
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])
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)
}
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_t * new_space = NULL;
hsize_t base_space_dims[H5S_MAX_RANK];
hsize_t base_space_maxdims[H5S_MAX_RANK];
int sbase_space_rank;
unsigned base_space_rank;
hsize_t projected_space_element_offset = 0;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(base_space != NULL);
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 );
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);
if(new_space_rank == 0) {
hssize_t npoints;
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);
if(NULL == (new_space = H5S_create(H5S_SCALAR)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace")
if(1 == npoints) {
if(H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection")
}
else {
HDassert(0 == npoints);
if(H5S_select_none(new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
}
}
else {
hsize_t new_space_dims[H5S_MAX_RANK];
hsize_t new_space_maxdims[H5S_MAX_RANK];
unsigned rank_diff;
if(new_space_rank > base_space_rank) {
hsize_t tmp_dim_size = 1;
rank_diff = new_space_rank - base_space_rank;
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);
}
else {
rank_diff = base_space_rank - 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);
}
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")
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(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);
H5MM_memcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank);
}
else
H5MM_memcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank);
new_space->select.offset_changed = TRUE;
}
}
HDassert(TRUE == H5S_select_shape_same(base_space, new_space));
*new_space_ptr = new_space;
if(buf != NULL) {
if(new_space_rank < base_space_rank) {
*adj_buf_ptr = (const void *)(((const uint8_t *)buf) +
((size_t)(projected_space_element_offset * element_size)));
}
else
*adj_buf_ptr = buf;
}
done:
if(ret_value < 0)
if(new_space && H5S_close(new_space) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
{
H5S_sel_iter_t *iter = NULL;
hbool_t iter_init = FALSE;
hsize_t *off = NULL;
size_t *len = NULL;
hssize_t nelmts;
size_t max_elem;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(fill);
HDassert(fill_size > 0);
HDassert(space);
HDassert(_buf);
if(NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
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 = TRUE;
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
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")
while(max_elem > 0) {
size_t nseq;
size_t curr_seq;
size_t nelem;
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")
for(curr_seq = 0; curr_seq < nseq; curr_seq++) {
uint8_t *buf;
buf = (uint8_t *)_buf + off[curr_seq];
HDassert((len[curr_seq] % fill_size) == 0);
H5VM_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size));
}
max_elem -= nelem;
}
done:
if(len)
len = H5FL_SEQ_FREE(size_t, len);
if(off)
off = H5FL_SEQ_FREE(hsize_t, off);
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)
}
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,
hbool_t share_selection)
{
H5S_t *new_space = NULL;
H5S_t *tmp_src_intersect_space = NULL;
H5S_sel_iter_t *ss_iter = NULL;
hbool_t ss_iter_init = FALSE;
H5S_sel_iter_t *ds_iter = NULL;
hbool_t ds_iter_init = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
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")
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(H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_ALL) {
if(H5S_select_copy(new_space, dst_space, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection")
}
else if((H5S_GET_SELECT_NPOINTS(src_intersect_space) == 0)
|| (H5S_GET_SELECT_NPOINTS(src_space) == 0)
|| (H5S_GET_SELECT_NPOINTS(dst_space) == 0)) {
if(H5S_select_none(new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
}
else {
HDassert(H5S_GET_EXTENT_TYPE(src_space) != H5S_SCALAR);
HDassert(H5S_GET_EXTENT_TYPE(src_intersect_space) != H5S_SCALAR);
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;
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])));
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")
if(intersect) {
if(H5S_select_all(new_space, TRUE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't select all")
}
else
if(H5S_select_none(new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
}
else {
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;
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")
for(curr_pnt = src_intersect_space->select.sel_info.pnt_lst->head; curr_pnt; curr_pnt = curr_pnt->next)
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")
src_intersect_space = tmp_src_intersect_space;
}
HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_HYPERSLABS);
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;
if(H5S_select_none(new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
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;
do {
HDassert(ss_iter->elmt_left > 0);
HDassert(ss_iter->elmt_left > 0);
if(H5S_SELECT_ITER_COORDS(ss_iter, coords) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get source selection coordinates")
if((intersect = H5S_SELECT_INTERSECT_BLOCK(src_intersect_space, coords, coords)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't check for intersection")
if(intersect) {
if(H5S_SELECT_ITER_COORDS(ds_iter, coords) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get destination selection coordinates")
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")
}
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);
}
else {
HDassert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_NONE);
HDassert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_NONE);
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")
}
}
}
*new_space_ptr = new_space;
done:
if(ret_value < 0)
if(new_space && H5S_close(new_space) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
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)
}
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;
H5S_t *proj_space = NULL;
hid_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE3("i", "iii", src_space_id, dst_space_id, src_intersect_space_id);
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")
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")
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")
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")
if((ret_value = H5I_register(H5I_DATASPACE, proj_space, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
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)
}
herr_t
H5S_select_subtract(H5S_t *space, H5S_t *subtract_space)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
HDassert(subtract_space);
if((space->select.type->type != H5S_SEL_NONE)
&& (subtract_space->select.type->type != H5S_SEL_NONE)) {
if(subtract_space->select.type->type == H5S_SEL_ALL) {
if(H5S_select_none(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
}
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")
}
else {
if(space->select.type->type == H5S_SEL_ALL) {
hsize_t tmp_start[H5S_MAX_RANK];
hsize_t tmp_stride[H5S_MAX_RANK];
hsize_t tmp_count[H5S_MAX_RANK];
hsize_t tmp_block[H5S_MAX_RANK];
unsigned u;
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];
}
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")
}
HDassert(space->select.type->type == H5S_SEL_HYPERSLABS);
HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS);
if(H5S__modify_select(space, H5S_SELECT_NOTB, subtract_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab")
}
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5S_sel_iter_close(H5S_sel_iter_t *sel_iter)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(sel_iter);
if(H5S_SELECT_ITER_RELEASE(sel_iter) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "problem releasing a selection iterator's type-specific info")
sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter);
done:
FUNC_LEAVE_NOAPI(ret_value)
}