diff options
author | Dana Robinson <derobins@hdfgroup.org> | 2015-03-04 00:27:40 (GMT) |
---|---|---|
committer | Dana Robinson <derobins@hdfgroup.org> | 2015-03-04 00:27:40 (GMT) |
commit | 5b294640c003dac45c2cc489793950207bf63c8f (patch) | |
tree | ef451f922a5242888c2cd63552212fa278284162 /src/H5Shyper.c | |
parent | dc059968de3823ffa1b0008c14b7e7e46c1fb8d8 (diff) | |
parent | 6ee9ea656fad6f408e81bd995eb465e0dd4ce0db (diff) | |
download | hdf5-5b294640c003dac45c2cc489793950207bf63c8f.zip hdf5-5b294640c003dac45c2cc489793950207bf63c8f.tar.gz hdf5-5b294640c003dac45c2cc489793950207bf63c8f.tar.bz2 |
[svn-r26350] Merge of r26273-26348 from the trunk.
Tested on: h5committest
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r-- | src/H5Shyper.c | 188 |
1 files changed, 149 insertions, 39 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c index c97c9b6..9b1562f 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -54,8 +54,8 @@ static herr_t H5S_hyper_get_seq_list(const H5S_t *space, unsigned flags, static herr_t H5S_hyper_release(H5S_t *space); static htri_t H5S_hyper_is_valid(const H5S_t *space); static hssize_t H5S_hyper_serial_size(const H5S_t *space); -static herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t *buf); -static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf); +static herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t **p); static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset); static htri_t H5S_hyper_is_contiguous(const H5S_t *space); @@ -1994,7 +1994,7 @@ H5S_hyper_serial_size(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **buf) +H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p) { H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ hsize_t u; /* Index variable */ @@ -2007,7 +2007,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, HDassert(start); HDassert(end); HDassert(rank < H5O_LAYOUT_NDIMS); - HDassert(buf && *buf); + HDassert(p && *p); /* Walk through the list of spans, recursing or outputing them */ curr=spans->head; @@ -2019,7 +2019,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, end[rank]=curr->high; /* Recurse down to the next dimension */ - if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,buf)<0) + if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,p)<0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") } /* end if */ else { @@ -2027,17 +2027,17 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, /* Encode previous starting points */ for(u=0; u<rank; u++) - UINT32ENCODE(*buf, (uint32_t)start[u]); + UINT32ENCODE(*p, (uint32_t)start[u]); /* Encode starting point for this span */ - UINT32ENCODE(*buf, (uint32_t)curr->low); + UINT32ENCODE(*p, (uint32_t)curr->low); /* Encode previous ending points */ for(u=0; u<rank; u++) - UINT32ENCODE(*buf, (uint32_t)end[u]); + UINT32ENCODE(*p, (uint32_t)end[u]); /* Encode starting point for this span */ - UINT32ENCODE(*buf, (uint32_t)curr->high); + UINT32ENCODE(*p, (uint32_t)curr->high); } /* end else */ /* Advance to next node */ @@ -2055,9 +2055,11 @@ done: PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_hyper_serialize(space, buf) - H5S_t *space; IN: Dataspace pointer of selection to serialize - uint8 *buf; OUT: Buffer to put serialized selection into + herr_t H5S_hyper_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -2069,7 +2071,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) +H5S_hyper_serialize (const H5S_t *space, uint8_t **p) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ @@ -2089,14 +2091,14 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) HDassert(space); /* Store the preamble information */ - UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */ - UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */ - lenp = buf; /* keep the pointer to the length location for later */ - buf += 4; /* skip over space for length */ + UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ + UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */ + UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */ + lenp = *p; /* keep the pointer to the length location for later */ + *p += 4; /* skip over space for length */ /* Encode number of dimensions */ - UINT32ENCODE(buf, (uint32_t)space->extent.rank); + UINT32ENCODE(*p, (uint32_t)space->extent.rank); len += 4; /* Check for a "regular" hyperslab selection */ @@ -2114,7 +2116,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode number of hyperslabs */ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(buf, (uint32_t)block_count); + UINT32ENCODE(*p, (uint32_t)block_count); len+=4; /* Now serialize the information for the regular hyperslab */ @@ -2137,11 +2139,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode hyperslab starting location */ for(u = 0; u < ndims; u++) - UINT32ENCODE(buf, (uint32_t)offset[u]); + UINT32ENCODE(*p, (uint32_t)offset[u]); /* Encode hyperslab ending location */ for(u = 0; u < ndims; u++) - UINT32ENCODE(buf, (uint32_t)(offset[u] + (diminfo[u].block - 1))); + UINT32ENCODE(*p, (uint32_t)(offset[u] + (diminfo[u].block - 1))); /* Move the offset to the next sequence to start */ offset[fast_dim]+=diminfo[fast_dim].stride; @@ -2192,15 +2194,15 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) /* Encode number of hyperslabs */ block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst); H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(buf, (uint32_t)block_count); + UINT32ENCODE(*p, (uint32_t)block_count); len+=4; /* Add 8 bytes times the rank for each hyperslab selected */ H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t); - len += (size_t)(8 * space->extent.rank * block_count); + len += (uint32_t)(8 * space->extent.rank * block_count); /* Encode each hyperslab in selection */ - H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &buf); + H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, p); } /* end else */ /* Encode length */ @@ -2216,9 +2218,12 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_hyper_deserialize(space, buf) - H5S_t *space; IN/OUT: Dataspace pointer to place selection into - uint8 *buf; IN: Buffer to retrieve serialized selection from + herr_t H5S_hyper_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -2230,9 +2235,9 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) +H5S_hyper_deserialize (H5S_t *space, const uint8_t **p) { - uint32_t rank; /* rank of points */ + unsigned rank; /* rank of points */ size_t num_elem=0; /* number of elements in selection */ hsize_t start[H5O_LAYOUT_NDIMS]; /* hyperslab start information */ hsize_t end[H5O_LAYOUT_NDIMS]; /* hyperslab end information */ @@ -2251,14 +2256,13 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) /* Check args */ HDassert(space); - HDassert(buf); + HDassert(p); + HDassert(*p); /* Deserialize slabs to select */ - buf+=16; /* Skip over selection header */ - UINT32DECODE(buf,rank); /* decode the rank of the point selection */ - if(rank!=space->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace") - UINT32DECODE(buf,num_elem); /* decode the number of points */ + /* (The header and rank have already beed decoded) */ + rank = space->extent.rank; /* Retrieve rank from space */ + UINT32DECODE(*p,num_elem); /* decode the number of points */ /* Set the count & stride for all blocks */ for(tcount=count,tstride=stride,j=0; j<rank; j++,tstride++,tcount++) { @@ -2270,14 +2274,14 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf) for(i=0; i<num_elem; i++) { /* Decode the starting points */ for(tstart=start,j=0; j<rank; j++,tstart++) - UINT32DECODE(buf, *tstart); + UINT32DECODE(*p, *tstart); /* Decode the ending points */ for(tend=end,j=0; j<rank; j++,tend++) - UINT32DECODE(buf, *tend); + UINT32DECODE(*p, *tend); /* Change the ending points into blocks */ - for(tblock=block,tstart=start,tend=end,j=0; j<(unsigned)rank; j++,tstart++,tend++,tblock++) + for(tblock=block,tstart=start,tend=end,j=0; j<rank; j++,tstart++,tend++,tblock++) *tblock=(*tend-*tstart)+1; /* Select or add the hyperslab to the current selection */ @@ -8856,3 +8860,109 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_get_seq_list() */ + +/*-------------------------------------------------------------------------- + NAME + H5Sis_regular_hyperslab + PURPOSE + Determine if a hyperslab selection is regular + USAGE + htri_t H5Sis_regular_hyperslab(dsid) + hid_t dsid; IN: Dataspace ID of hyperslab selection to query + RETURNS + TRUE/FALSE for hyperslab selection, FAIL on error or when querying other + selection types. + DESCRIPTION + If a hyperslab can be represented as a single call to H5Sselect_hyperslab, + with the H5S_SELECT_SET option, it is regular. If the hyperslab selection + would require multiple calls to H5Sselect_hyperslab, it is irregular. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5Sis_regular_hyperslab(hid_t spaceid) +{ + H5S_t *space; /* Dataspace to query */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("t", "i", spaceid); + + /* Check args */ + if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, 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") + + ret_value = H5S_hyper_is_regular(space); + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Sis_regular_hyperslab() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Sgetregular_hyperslab + PURPOSE + Retrieve a regular hyperslab selection + USAGE + herr_t H5Sget_regular_hyperslab(dsid, start, stride, block, count) + hid_t dsid; IN: Dataspace ID of hyperslab selection to query + hsize_t start[]; OUT: Offset of start of hyperslab + hsize_t stride[]; OUT: Hyperslab stride + hsize_t count[]; OUT: Number of blocks included in hyperslab + hsize_t block[]; OUT: Size of block in hyperslab + RETURNS + Non-negative on success/Negative on failure. (It is an error to query + the regular hyperslab selections for non-regular hyperslab selections) + DESCRIPTION + Retrieve the start/stride/count/block for a regular hyperslab selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note that if a hyperslab is originally regular, then becomes irregular + through selection operations, and then becomes regular again, the new + final regular selection may be equivalent but not identical to the + original regular selection. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[], hsize_t stride[], + hsize_t count[], hsize_t block[]) +{ + H5S_t *space; /* Dataspace to query */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "i*h*h*h*h", spaceid, start, stride, count, block); + + /* Check args */ + if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, 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(TRUE != H5S_hyper_is_regular(space)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a regular hyperslab selection") + + /* Retrieve hyperslab parameters */ + if(start) + for(u = 0; u < space->extent.rank; u++) + start[u] = space->select.sel_info.hslab->app_diminfo[u].start; + if(stride) + for(u = 0; u < space->extent.rank; u++) + stride[u] = space->select.sel_info.hslab->app_diminfo[u].stride; + if(count) + for(u = 0; u < space->extent.rank; u++) + count[u] = space->select.sel_info.hslab->app_diminfo[u].count; + if(block) + for(u = 0; u < space->extent.rank; u++) + block[u] = space->select.sel_info.hslab->app_diminfo[u].block; + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Sget_regular_hyperslab() */ + |