summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1998-07-06 21:01:13 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1998-07-06 21:01:13 (GMT)
commit43f13aeca28a722d6436d43dcd84a59918dc0950 (patch)
tree1ee94e4f1b64a7d027112d616d8617992c09520a /src
parentd70e61b1dbd7ff16aa4ac5cad4a69bf87b84f208 (diff)
downloadhdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.zip
hdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.tar.gz
hdf5-43f13aeca28a722d6436d43dcd84a59918dc0950.tar.bz2
[svn-r451] Completely tore out existing dataspace API and replaced with code to match
API defined in the html/Dataspaces.html document. This code does not include support for strides, merging selections, or permutations of coordinates yet, but it's a drop-in replacement for the existing API with the same features.
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c2
-rw-r--r--src/H5D.c414
-rw-r--r--src/H5E.c1
-rw-r--r--src/H5Epublic.h1
-rw-r--r--src/H5Farray.c14
-rw-r--r--src/H5Iprivate.h1
-rw-r--r--src/H5Ipublic.h1
-rw-r--r--src/H5Oattr.c10
-rw-r--r--src/H5Osdspace.c26
-rw-r--r--src/H5S.c1326
-rw-r--r--src/H5Sall.c511
-rw-r--r--src/H5Shyper.c1395
-rw-r--r--src/H5Spoint.c455
-rw-r--r--src/H5Sprivate.h263
-rw-r--r--src/H5Spublic.h22
-rw-r--r--src/H5Sselect.c386
-rw-r--r--src/H5Ssimp.c272
-rw-r--r--src/H5TB.c506
-rw-r--r--src/H5TBprivate.h26
-rw-r--r--src/H5V.c66
-rw-r--r--src/H5Vprivate.h1
-rw-r--r--src/H5public.h2
-rw-r--r--src/Makefile.in15
23 files changed, 4666 insertions, 1050 deletions
diff --git a/src/H5A.c b/src/H5A.c
index b07bf37..81d6200 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -262,7 +262,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
/* Compute the internal sizes */
attr->dt_size=(H5O_DTYPE[0].raw_size)(attr->ent.file,type);
- attr->ds_size=(H5O_SDSPACE[0].raw_size)(attr->ent.file,&(space->u.simple));
+ attr->ds_size=(H5O_SDSPACE[0].raw_size)(attr->ent.file,&(space->extent.u.simple));
attr->data_size=H5S_get_npoints(space)*H5T_get_size(type);
/* Hold the symbol table entry (and file) open */
diff --git a/src/H5D.c b/src/H5D.c
index c11511e..653d8e3 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -29,6 +29,8 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5Pprivate.h> /* Property lists */
#include <H5Zprivate.h> /* Data compression */
+int qak_debug=0;
+
#define PABLO_MASK H5D_mask
/*
@@ -1221,8 +1223,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
uint8 *bkg_buf = NULL; /*background buffer */
H5T_conv_t tconv_func = NULL; /*conversion function */
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
- const H5S_conv_t *sconv_func = NULL; /*space conversion funcs*/
- H5S_number_t numbering; /*element numbering info*/
+ H5S_conv_t sconv_func={NULL}; /*space conversion funcs*/
+ H5S_sel_iter_t mem_iter, /* memory selection iteration information */
+ bkg_iter, /* background iteration information */
+ file_iter; /* file selection iteration information */
H5T_cdata_t *cdata = NULL; /*type conversion data */
herr_t ret_value = FAIL;
herr_t status;
@@ -1244,14 +1248,14 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
assert(xfer_parms);
assert(buf);
if (!file_space) {
- if (NULL==(free_this_space=H5S_read (&(dataset->ent)))) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to read data space from dataset header");
- }
- file_space = free_this_space;
+ if (NULL==(free_this_space=H5S_read (&(dataset->ent)))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read data space from dataset header");
+ }
+ file_space = free_this_space;
}
if (!mem_space) mem_space = file_space;
- nelmts = H5S_get_npoints(mem_space);
+ nelmts = H5S_select_npoints(mem_space);
#ifdef HAVE_PARALLEL
/*
@@ -1278,27 +1282,31 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* enough value in xfer_parms since turning off data type conversion also
* turns off background preservation.
*/
- if (nelmts!=H5S_get_npoints (file_space)) {
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+#ifdef QAK
+printf("%s: check 1.0, nelmts=%d\n",FUNC,(int)nelmts);
+#endif /* QAK */
+ if (nelmts!=H5S_select_npoints (file_space)) {
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
"src and dest data spaces have different sizes");
}
if (NULL == (tconv_func = H5T_find(dataset->type, mem_type,
xfer_parms->need_bkg, &cdata))) {
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"unable to convert between src and dest data types");
} else if (H5T_conv_noop!=tconv_func) {
- if ((src_id=H5I_register(H5_DATATYPE,
- H5T_copy(dataset->type, H5T_COPY_ALL)))<0 ||
- (dst_id=H5I_register(H5_DATATYPE,
- H5T_copy(mem_type, H5T_COPY_ALL)))<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL,
- "unable to register types for conversion");
- }
- }
- if (NULL==(sconv_func=H5S_find (mem_space, file_space))) {
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL,
+ if ((src_id=H5I_register(H5_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0 ||
+ (dst_id=H5I_register(H5_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL,
+ "unable to register types for conversion");
+ }
+ }
+ if (FAIL==H5S_find (&sconv_func, mem_space, file_space)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"unable to convert from file to memory data space");
}
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
#ifdef HAVE_PARALLEL
/*
@@ -1307,8 +1315,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){
/* Supports only no conversion, type or space, for now. */
if (H5T_conv_noop==tconv_func &&
- NULL!=sconv_func->read) {
- status = (sconv_func->read)(dataset->ent.file, &(dataset->layout),
+ NULL!=sconv_func.read) {
+ status = (sconv_func.read)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->compress),
&(dataset->create_parms->efl),
H5T_get_size (dataset->type),
@@ -1326,22 +1334,24 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* If there is no type conversion then try reading directly into the
* application's buffer. This saves at least one mem-to-mem copy.
*/
- if (H5D_OPTIMIZE_PIPE &&
- H5T_conv_noop==tconv_func &&
- NULL!=sconv_func->read) {
- status = (sconv_func->read)(dataset->ent.file, &(dataset->layout),
+ if (H5D_OPTIMIZE_PIPE && H5T_conv_noop==tconv_func &&
+ NULL!=sconv_func.read) {
+ status = (sconv_func.read)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->compress),
&(dataset->create_parms->efl),
H5T_get_size (dataset->type), file_space,
mem_space, xfer_parms->xfer_mode,
buf/*out*/);
- if (status>=0) goto succeed;
+ if (status>=0) goto succeed;
#ifdef H5D_DEBUG
- fprintf (stderr, "H5D: data space conversion could not be optimized "
- "for this case (using general method instead)\n");
+ fprintf (stderr, "H5D: data space conversion could not be optimized "
+ "for this case (using general method instead)\n");
#endif
- H5E_clear ();
+ H5E_clear ();
}
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
/*
@@ -1352,21 +1362,24 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
target_size = xfer_parms->buf_size;
request_nelmts = target_size / MAX(src_type_size, dst_type_size);
if (request_nelmts<=0) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
"temporary buffer max size is too small");
}
- if (sconv_func->init) {
- smine_nelmts = (sconv_func->init)(&(dataset->layout), mem_space,
- file_space, request_nelmts,
- &numbering/*out*/);
- if (smine_nelmts<=0) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize element numbering information");
- }
- } else {
- smine_nelmts = request_nelmts;
- HDmemset (&numbering, 0, sizeof numbering);
- }
+ if (FAIL == (sconv_func.finit)(&(dataset->layout), file_space, &file_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize file selection information");
+ }
+ if (FAIL == (sconv_func.minit)(&(dataset->layout), mem_space, &mem_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize memory selection information");
+ }
+ if (FAIL == (sconv_func.binit)(&(dataset->layout), mem_space, &bkg_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize memory selection information");
+ }
+#ifdef QAK
+printf("%s: check 3.0, request_nelmts=%d\n",FUNC,(int)request_nelmts);
+#endif /* QAK */
/*
* Get a temporary buffer for type conversion unless the app has already
@@ -1376,9 +1389,9 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* same size over and over.
*/
if (cdata->need_bkg) {
- need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg);
+ need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg);
} else {
- need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
}
if (NULL==(tconv_buf=xfer_parms->tconv_buf)) {
if (NULL==(tconv_buf = H5MM_malloc (target_size))) {
@@ -1387,7 +1400,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
}
if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) {
- if (NULL==(bkg_buf = H5MM_malloc (smine_nelmts * dst_type_size))) {
+ if (NULL==(bkg_buf = H5MM_malloc (request_nelmts * dst_type_size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for background buffer");
}
@@ -1414,58 +1427,88 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
#endif
+#ifdef QAK
+printf("%s: check 4.0, nelmts=%d, need_bkg=%d\n",FUNC,(int)nelmts,(int)need_bkg);
+#endif /* QAK */
/* Start strip mining... */
for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
- smine_nelmts = MIN (smine_nelmts, nelmts-smine_start);
+ /* Go figure out how many elements to read from the file */
+ smine_nelmts = (sconv_func.favail)(file_space,&file_iter,
+ MIN(request_nelmts,(nelmts-smine_start)));
+#ifdef QAK
+printf("%s: check 5.0, nelmts=%d, smine_start=%d, smine_nelmts=%d\n",FUNC,(int)nelmts,(int)smine_start,(int)smine_nelmts);
+#endif /* QAK */
- /*
- * Gather the data from disk into the data type conversion
- * buffer. Also gather data from application to background buffer
- * if necessary.
- */
- if ((sconv_func->fgath)(dataset->ent.file, &(dataset->layout),
- &(dataset->create_parms->compress),
- &(dataset->create_parms->efl),
- H5T_get_size (dataset->type), file_space,
- &numbering, smine_start, smine_nelmts,
- xfer_parms->xfer_mode,
- tconv_buf/*out*/)!=smine_nelmts) {
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
- }
- if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) ||
- (!H5D_OPTIMIZE_PIPE && need_bkg)) {
- if ((sconv_func->mgath)(buf, H5T_get_size (mem_type), mem_space,
- &numbering, smine_start, smine_nelmts,
- bkg_buf/*out*/)!=smine_nelmts) {
- HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
- }
- }
+ /*
+ * Gather the data from disk into the data type conversion
+ * buffer. Also gather data from application to background buffer
+ * if necessary.
+ */
+ if ((sconv_func.fgath)(dataset->ent.file, &(dataset->layout),
+ &(dataset->create_parms->compress),
+ &(dataset->create_parms->efl),
+ H5T_get_size (dataset->type), file_space, &file_iter,
+ smine_nelmts, xfer_parms->xfer_mode,
+ tconv_buf/*out*/)!=smine_nelmts) {
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
+ }
+#ifdef QAK
+printf("%s: check 6.0\n",FUNC);
+{
+ int i;
+ int *b;
- /*
- * Perform data type conversion.
- */
+ if(qak_debug) {
+ b=tconv_buf;
+ printf("\ntconv_buf:");
+ for (i=0; i<smine_nelmts; i++,b++) {
+ printf("(%d)%d ",i,*b);
+ }
+ printf("\n");
+ }
+}
+#endif /* QAK */
+ if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) ||
+ (!H5D_OPTIMIZE_PIPE && need_bkg)) {
+ if ((sconv_func.mgath)(buf, H5T_get_size (mem_type), mem_space,
+ &bkg_iter, smine_nelmts, bkg_buf/*out*/)!=smine_nelmts) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
+ }
+ }
+#ifdef QAK
+printf("%s: check 7.0\n",FUNC);
+#endif /* QAK */
+
+ /*
+ * Perform data type conversion.
+ */
#ifdef H5T_DEBUG
- H5T_timer_begin (&timer, cdata);
+ H5T_timer_begin (&timer, cdata);
#endif
- cdata->command = H5T_CONV_CONV;
- status = (tconv_func)(src_id, dst_id, cdata, smine_nelmts, tconv_buf,
+ cdata->command = H5T_CONV_CONV;
+ status = (tconv_func)(src_id, dst_id, cdata, smine_nelmts, tconv_buf,
bkg_buf);
#ifdef H5T_DEBUG
- H5T_timer_end (&timer, cdata, smine_nelmts);
+ H5T_timer_end (&timer, cdata, smine_nelmts);
#endif
- if (status<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "data type conversion failed");
- }
-
- /*
- * Scatter the data into memory.
- */
- if ((sconv_func->mscat)(tconv_buf, H5T_get_size (mem_type), mem_space,
- &numbering, smine_start, smine_nelmts,
- buf/*out*/)<0) {
- HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "scatter failed");
- }
+ if (status<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "data type conversion failed");
+ }
+
+#ifdef QAK
+printf("%s: check 8.0\n",FUNC);
+#endif /* QAK */
+ /*
+ * Scatter the data into memory.
+ */
+ if ((sconv_func.mscat)(tconv_buf, H5T_get_size (mem_type), mem_space,
+ &mem_iter, smine_nelmts, buf/*out*/)<0) {
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "scatter failed");
+ }
+#ifdef QAK
+printf("%s: check 9.0\n",FUNC);
+#endif /* QAK */
}
succeed:
@@ -1516,8 +1559,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
uint8 *bkg_buf = NULL; /*background buffer */
H5T_conv_t tconv_func = NULL; /*conversion function */
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
- const H5S_conv_t *sconv_func = NULL; /*space conversion funcs*/
- H5S_number_t numbering; /*element numbering info*/
+ H5S_conv_t sconv_func= {NULL}; /*space conversion funcs*/
+ H5S_sel_iter_t mem_iter, /* memory selection iteration information */
+ bkg_iter, /* background iteration information */
+ file_iter; /* file selection iteration information */
H5T_cdata_t *cdata = NULL; /*type conversion data */
herr_t ret_value = FAIL, status;
size_t src_type_size; /*size of source type */
@@ -1545,7 +1590,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
file_space = free_this_space;
}
if (!mem_space) mem_space = file_space;
- nelmts = H5S_get_npoints(mem_space);
+ nelmts = H5S_select_npoints(mem_space);
#ifdef HAVE_PARALLEL
/*
@@ -1572,7 +1617,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* enough value in xfer_parms since turning off data type conversion also
* turns off background preservation.
*/
- if (nelmts!=H5S_get_npoints (file_space)) {
+ if (nelmts!=H5S_select_npoints (file_space)) {
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
"src and dest data spaces have different sizes");
}
@@ -1589,10 +1634,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
"unable to register types for conversion");
}
}
- if (NULL==(sconv_func=H5S_find (mem_space, file_space))) {
+ if (FAIL==H5S_find (&sconv_func, mem_space, file_space)) {
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"unable to convert from memory to file data space");
}
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
#ifdef HAVE_PARALLEL
/*
@@ -1601,8 +1649,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){
/* Supports only no conversion, type or space, for now. */
if (H5T_conv_noop==tconv_func &&
- NULL!=sconv_func->write) {
- status = (sconv_func->write)(dataset->ent.file,
+ NULL!=sconv_func.write) {
+ status = (sconv_func.write)(dataset->ent.file,
&(dataset->layout),
&(dataset->create_parms->compress),
&(dataset->create_parms->efl),
@@ -1623,8 +1671,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
*/
if (H5D_OPTIMIZE_PIPE &&
H5T_conv_noop==tconv_func &&
- NULL!=sconv_func->write) {
- status = (sconv_func->write)(dataset->ent.file, &(dataset->layout),
+ NULL!=sconv_func.write) {
+ status = (sconv_func.write)(dataset->ent.file, &(dataset->layout),
&(dataset->create_parms->compress),
&(dataset->create_parms->efl),
H5T_get_size (dataset->type), file_space,
@@ -1636,6 +1684,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
#endif
H5E_clear ();
}
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
/*
@@ -1646,21 +1697,24 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
target_size = xfer_parms->buf_size;
request_nelmts = target_size / MAX (src_type_size, dst_type_size);
if (request_nelmts<=0) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
"temporary buffer max size is too small");
}
- if (sconv_func->init) {
- smine_nelmts = (sconv_func->init)(&(dataset->layout), mem_space,
- file_space, request_nelmts,
- &numbering/*out*/);
- if (smine_nelmts<=0) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to initialize element numbering information");
- }
- } else {
- smine_nelmts = request_nelmts;
- HDmemset (&numbering, 0, sizeof numbering);
- }
+ if (FAIL == (sconv_func.finit)(&(dataset->layout), file_space, &file_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize file selection information");
+ }
+ if (FAIL == (sconv_func.minit)(&(dataset->layout), mem_space, &mem_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize memory selection information");
+ }
+ if (FAIL == (sconv_func.binit)(&(dataset->layout), mem_space, &bkg_iter)) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize memory selection information");
+ }
+#ifdef QAK
+printf("%s: check 3.0, request_nelmts=%d\n",FUNC,(int)request_nelmts);
+#endif /* QAK */
/*
* Get a temporary buffer for type conversion unless the app has already
@@ -1670,9 +1724,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* same size over and over.
*/
if (cdata->need_bkg) {
- need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg);
+ need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg);
} else {
- need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
}
if (NULL==(tconv_buf=xfer_parms->tconv_buf)) {
if (NULL==(tconv_buf = H5MM_malloc (target_size))) {
@@ -1681,7 +1735,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
}
if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) {
- if (NULL==(bkg_buf = H5MM_malloc (smine_nelmts * dst_type_size))) {
+ if (NULL==(bkg_buf = H5MM_malloc (request_nelmts * dst_type_size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for background buffer");
}
@@ -1707,65 +1761,93 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
}
#endif
+#ifdef QAK
+printf("%s: check 4.0, nelmts=%d, need_bkg=%d\n",FUNC,(int)nelmts,(int)need_bkg);
+#endif /* QAK */
/* Start strip mining... */
for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
- smine_nelmts = MIN (smine_nelmts, nelmts-smine_start);
-
- /*
- * Gather data from application buffer into the data type conversion
- * buffer. Also gather data from the file into the background buffer
- * if necessary.
- */
- if ((sconv_func->mgath)(buf, H5T_get_size (mem_type), mem_space,
- &numbering, smine_start, smine_nelmts,
- tconv_buf/*out*/)!=smine_nelmts) {
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed");
- }
- if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) ||
- (!H5D_OPTIMIZE_PIPE && need_bkg)) {
- if ((sconv_func->fgath)(dataset->ent.file, &(dataset->layout),
- &(dataset->create_parms->compress),
- &(dataset->create_parms->efl),
- H5T_get_size (dataset->type), file_space,
- &numbering, smine_start, smine_nelmts,
- xfer_parms->xfer_mode,
- bkg_buf/*out*/)!=smine_nelmts) {
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL,
- "file gather failed");
- }
- }
-
- /*
- * Perform data type conversion.
- */
+ /* Go figure out how many elements to read from the file */
+ smine_nelmts = (sconv_func.favail)(file_space,&file_iter,
+ MIN(request_nelmts,(nelmts-smine_start)));
+#ifdef QAK
+printf("%s: check 5.0, nelmts=%d, smine_start=%d, smine_nelmts=%d\n",FUNC,(int)nelmts,(int)smine_start,(int)smine_nelmts);
+#endif /* QAK */
+
+ /*
+ * Gather data from application buffer into the data type conversion
+ * buffer. Also gather data from the file into the background buffer
+ * if necessary.
+ */
+ if ((sconv_func.mgath)(buf, H5T_get_size (mem_type), mem_space,
+ &mem_iter, smine_nelmts, tconv_buf/*out*/)!=smine_nelmts) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed");
+ }
+#ifdef QAK
+{
+ int i;
+ int *b;
+
+ if(qak_debug) {
+ b=buf;
+ b+=1430;
+ printf("buf:");
+ for (i=0; i<smine_nelmts; i++,b++) {
+ printf("(%d)%d ",i,*b);
+ }
+ b=tconv_buf;
+ printf("\ntconv_buf:");
+ for (i=0; i<smine_nelmts; i++,b++) {
+ printf("(%d)%d ",i,*b);
+ }
+ printf("\n");
+ }
+}
+printf("%s: check 6.0\n",FUNC);
+#endif /* QAK */
+ if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) ||
+ (!H5D_OPTIMIZE_PIPE && need_bkg)) {
+ if ((sconv_func.fgath)(dataset->ent.file, &(dataset->layout),
+ &(dataset->create_parms->compress),
+ &(dataset->create_parms->efl),
+ H5T_get_size (dataset->type), file_space,
+ &bkg_iter, smine_nelmts, xfer_parms->xfer_mode,
+ bkg_buf/*out*/)!=smine_nelmts) {
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
+ }
+ }
+
+ /*
+ * Perform data type conversion.
+ */
#ifdef H5T_DEBUG
- H5T_timer_begin (&timer, cdata);
+ H5T_timer_begin (&timer, cdata);
#endif
- cdata->command = H5T_CONV_CONV;
- status = (tconv_func) (src_id, dst_id, cdata, smine_nelmts, tconv_buf,
- bkg_buf);
+ cdata->command = H5T_CONV_CONV;
+ status = (tconv_func) (src_id, dst_id, cdata, smine_nelmts, tconv_buf,
+ bkg_buf);
#ifdef H5T_DEBUG
- H5T_timer_end (&timer, cdata, smine_nelmts);
+ H5T_timer_end (&timer, cdata, smine_nelmts);
#endif
- if (status<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "data type conversion failed");
- }
+ if (status<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "data type conversion failed");
+ }
- /*
- * Scatter the data out to the file.
- */
- if ((sconv_func->fscat)(dataset->ent.file, &(dataset->layout),
- &(dataset->create_parms->compress),
- &(dataset->create_parms->efl),
- H5T_get_size (dataset->type), file_space,
- &numbering, smine_start, smine_nelmts,
- xfer_parms->xfer_mode, tconv_buf)<0) {
- HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed");
- }
+ /*
+ * Scatter the data out to the file.
+ */
+ if ((sconv_func.fscat)(dataset->ent.file, &(dataset->layout),
+ &(dataset->create_parms->compress),
+ &(dataset->create_parms->efl),
+ H5T_get_size (dataset->type), file_space,
+ &file_iter, smine_nelmts,
+ xfer_parms->xfer_mode, tconv_buf)<0) {
+ HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed");
+ }
}
+
succeed:
ret_value = SUCCEED;
@@ -1773,10 +1855,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (src_id >= 0) H5I_dec_ref(src_id);
if (dst_id >= 0) H5I_dec_ref(dst_id);
if (tconv_buf && NULL==xfer_parms->tconv_buf) {
- H5MM_xfree(tconv_buf);
+ H5MM_xfree(tconv_buf);
}
if (bkg_buf && NULL==xfer_parms->bkg_buf) {
- H5MM_xfree (bkg_buf);
+ H5MM_xfree (bkg_buf);
}
if (free_this_space) H5S_close (free_this_space);
FUNC_LEAVE(ret_value);
diff --git a/src/H5E.c b/src/H5E.c
index 0c189f0..1344b65 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -67,6 +67,7 @@ static const H5E_minor_mesg_t H5E_minor_mesg_g[] = {
{H5E_BADRANGE, "Out of range"},
{H5E_BADVALUE, "Bad value"},
{H5E_NOSPACE, "No space available for allocation"},
+ {H5E_CANTCOPY, "Unable to copy object"},
{H5E_FILEEXISTS, "File already exists"},
{H5E_FILEOPEN, "File already open"},
{H5E_CANTCREATE, "Unable to create file"},
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 4096179..d155e9a 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -89,6 +89,7 @@ typedef enum H5E_minor_t {
/* Resource errors */
H5E_NOSPACE, /*no space available for allocation */
+ H5E_CANTCOPY, /*unable to copy object */
/* File accessability errors */
H5E_FILEEXISTS, /*file already exists */
diff --git a/src/H5Farray.c b/src/H5Farray.c
index 85df727..0a3d5ab 100644
--- a/src/H5Farray.c
+++ b/src/H5Farray.c
@@ -155,6 +155,13 @@ H5F_arr_read (H5F_t *f, const struct H5O_layout_t *layout,
"supported yet");
}
#endif
+#ifdef QAK
+{
+ printf("%s: layout->ndims=%d\n",FUNC,(int)layout->ndims);
+ for(i=0; i<layout->ndims; i++)
+ printf("%s: %d: hslab_size=%d, mem_size=%d, mem_offset=%d, file_offset=%d\n",FUNC,i,(int)_hslab_size[i],(int)mem_size[i],(int)mem_offset[i],(int)file_offset[i]);
+}
+#endif /* QAK */
switch (layout->type) {
case H5D_CONTIGUOUS:
@@ -360,6 +367,13 @@ H5F_arr_write (H5F_t *f, const struct H5O_layout_t *layout,
"collective access on non-contiguous datasets not supported yet");
}
#endif
+#ifdef QAK
+{
+ printf("%s: layout->ndims=%d\n",FUNC,(int)layout->ndims);
+ for(i=0; i<layout->ndims; i++)
+ printf("%s: %d: hslab_size=%d, mem_size=%d, mem_offset=%d, file_offset=%d\n",FUNC,i,(int)_hslab_size[i],(int)mem_size[i],(int)mem_offset[i],(int)file_offset[i]);
+}
+#endif /* QAK */
switch (layout->type) {
case H5D_CONTIGUOUS:
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 895128b..81c53d2 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -68,6 +68,7 @@
#define H5I_OID_HASHSIZE 64
#define H5I_GROUPID_HASHSIZE 64
#define H5I_ATTRID_HASHSIZE 64
+#define H5I_TEMPBUFID_HASHSIZE 64
/* Atom information structure used */
typedef struct H5I_id_info_t {
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 96442a7..74b0bd8 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -40,6 +40,7 @@ typedef enum {
H5_DATASPACE, /*group ID for Dataspace objects */
H5_DATASET, /*group ID for Dataset objects */
H5_ATTR, /*group ID for Attribute objects */
+ H5_TEMPBUF, /*group ID for Temporary buffer objects */
MAXGROUP /*highest group in group_t (Invalid as true group)*/
} H5I_group_t;
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 6a13a91..c71318f 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -115,13 +115,13 @@ H5O_attr_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
"memory allocation failed");
}
if((simple=(H5O_SDSPACE->decode)(f,p,NULL))!=NULL) {
- attr->ds->type = H5S_SIMPLE;
- HDmemcpy(&(attr->ds->u.simple),simple, sizeof(H5S_simple_t));
+ attr->ds->extent.type = H5S_SIMPLE;
+ HDmemcpy(&(attr->ds->extent.u.simple),simple, sizeof(H5S_simple_t));
H5MM_xfree(simple);
} else {
- attr->ds->type = H5S_SCALAR;
+ attr->ds->extent.type = H5S_SCALAR;
} /* end else */
- attr->ds_size=(H5O_SDSPACE->raw_size)(f,&(attr->ds->u.simple));
+ attr->ds_size=(H5O_SDSPACE->raw_size)(f,&(attr->ds->extent.u.simple));
p+=attr->ds_size;
/* Compute the size of the data */
@@ -190,7 +190,7 @@ H5O_attr_encode(H5F_t *f, uint8 *p, const void *mesg)
p+=attr->dt_size;
/* encode the attribute dataspace */
- if((H5O_SDSPACE->encode)(f,p,&(attr->ds->u.simple))<0) {
+ if((H5O_SDSPACE->encode)(f,p,&(attr->ds->extent.u.simple))<0) {
HRETURN_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL,
"can't encode attribute dataspace");
}
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index a780af3..117dcf3 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -102,7 +102,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
for (u = 0; u < sdim->rank; u++) {
H5F_decode_length (f, p, sdim->size[u]);
}
- if (flags & 0x01) {
+ if (flags & H5S_VALID_MAX) {
if (NULL==(sdim->max=H5MM_malloc(sizeof(sdim->max[0])*
sdim->rank))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
@@ -112,7 +112,8 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
H5F_decode_length (f, p, sdim->max[u]);
}
}
- if (flags & 0x02) {
+#ifdef LATER
+ if (flags & H5S_VALID_PERM) {
if (NULL==(sdim->perm=H5MM_malloc(sizeof(sdim->perm[0])*
sdim->rank))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
@@ -121,6 +122,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
for (u = 0; u < sdim->rank; u++)
UINT32DECODE(p, sdim->perm[u]);
}
+#endif
}
}
@@ -171,8 +173,10 @@ H5O_sdspace_encode(H5F_t *f, uint8 *p, const void *mesg)
assert(sdim);
/* set flags */
- if (sdim->max) flags |= 0x01;
- if (sdim->perm) flags |= 0x02;
+ if (sdim->max) flags |= H5S_VALID_MAX;
+#ifdef LATER
+ if (sdim->perm) flags |= H5S_VALID_PERM;
+#endif
/* encode */
UINT32ENCODE(p, sdim->rank);
@@ -181,15 +185,17 @@ H5O_sdspace_encode(H5F_t *f, uint8 *p, const void *mesg)
for (u = 0; u < sdim->rank; u++) {
H5F_encode_length (f, p, sdim->size[u]);
}
- if (flags & 0x01) {
+ if (flags & H5S_VALID_MAX) {
for (u = 0; u < sdim->rank; u++) {
H5F_encode_length (f, p, sdim->max[u]);
}
}
- if (flags & 0x02) {
+#ifdef LATER
+ if (flags & H5S_VALID_PERM) {
for (u = 0; u < sdim->rank; u++)
UINT32ENCODE(p, sdim->perm[u]);
}
+#endif
}
FUNC_LEAVE(SUCCEED);
}
@@ -241,6 +247,7 @@ H5O_sdspace_copy(const void *mesg, void *dest)
}
HDmemcpy (dst->max, src->max, src->rank*sizeof(src->max[0]));
}
+#ifdef LATER
if (src->perm) {
if (NULL==(dst->perm=H5MM_calloc(src->rank*sizeof(src->perm[0])))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
@@ -248,6 +255,7 @@ H5O_sdspace_copy(const void *mesg, void *dest)
}
HDmemcpy (dst->perm, src->perm, src->rank*sizeof(src->perm[0]));
}
+#endif
FUNC_LEAVE((void *) dst);
}
@@ -278,7 +286,9 @@ H5O_sdspace_reset(void *_mesg)
FUNC_ENTER (H5O_sdspace_reset, FAIL);
mesg->size = H5MM_xfree (mesg->size);
mesg->max = H5MM_xfree (mesg->max);
+#ifdef LATER
mesg->perm = H5MM_xfree (mesg->perm);
+#endif
FUNC_LEAVE (SUCCEED);
}
@@ -321,8 +331,10 @@ H5O_sdspace_size(H5F_t *f, const void *mesg)
/* add in the space for the maximum dimensions, if they are present */
ret_value += sdim->max ? sdim->rank * H5F_SIZEOF_SIZE (f) : 0;
+#ifdef LATER
/* add in the space for the dimension permutations, if they are present */
ret_value += sdim->perm ? sdim->rank * 4 : 0;
+#endif
FUNC_LEAVE(ret_value);
}
@@ -386,6 +398,7 @@ H5O_sdspace_debug(H5F_t __unused__ *f, const void *mesg,
HDfprintf (stream, "CONSTANT\n");
}
+#ifdef LATER
if (sdim->perm) {
HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Perm:");
for (u = 0; u < sdim->rank; u++) {
@@ -393,6 +406,7 @@ H5O_sdspace_debug(H5F_t __unused__ *f, const void *mesg,
(unsigned long) (sdim->perm[u]));
}
}
+#endif
FUNC_LEAVE(SUCCEED);
}
diff --git a/src/H5S.c b/src/H5S.c
index 8802a68..ad4cb1a 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -20,7 +20,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5Iprivate.h> /* ID Functions */
#include <H5Eprivate.h> /* Error handling */
#include <H5MMprivate.h> /* Memory Management functions */
-#include <H5Oprivate.h> /*object headers */
+#include <H5Oprivate.h> /* object headers */
#include <H5Sprivate.h> /* Data-space functions */
/* Interface initialization */
@@ -51,9 +51,8 @@ H5S_init_interface(void)
/* Initialize the atom group for the file IDs */
if ((ret_value = H5I_init_group(H5_DATASPACE, H5I_DATASPACEID_HASHSIZE,
- H5S_RESERVED_ATOMS,
- (herr_t (*)(void *)) H5S_close)) != FAIL) {
- ret_value = H5_add_exit(&H5S_term_interface);
+ H5S_RESERVED_ATOMS, (herr_t (*)(void *)) H5S_close)) != FAIL) {
+ ret_value = H5_add_exit(&H5S_term_interface);
}
FUNC_LEAVE(ret_value);
}
@@ -82,116 +81,97 @@ H5S_term_interface(void)
H5I_destroy_group(H5_DATASPACE);
}
-/*-------------------------------------------------------------------------
- * Function: H5Screate_simple
- *
- * Purpose: Creates a new simple data space object and opens it for
- * access. The DIMS argument is the size of the simple dataset
- * and the MAXDIMS argument is the upper limit on the size of
- * the dataset. MAXDIMS may be the null pointer in which case
- * the upper limit is the same as DIMS. If an element of
- * MAXDIMS is H5S_UNLIMITED then the corresponding dimension is
- * unlimited, otherwise no element of MAXDIMS should be smaller
- * than the corresponding element of DIMS.
- *
- * Return: Success: The ID for the new simple data space object.
- *
- * Failure: FAIL
- *
- * Errors:
- *
- * Programmer: Quincey Koziol
- * Tuesday, January 27, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5Screate_simple (int rank, const hsize_t *dims, const hsize_t *maxdims)
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_create
+ PURPOSE
+ Create empty, typed dataspace
+ USAGE
+ H5S_t *H5S_create(type)
+ H5S_type_t type; IN: Dataspace type to create
+ RETURNS
+ Pointer to dataspace on success, NULL on failure
+ DESCRIPTION
+ Creates a new dataspace of a given type. The extent & selection are
+ undefined
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5S_t *H5S_create(H5S_class_t type)
{
- H5S_t *ds = NULL;
+ H5S_t *ret_value = NULL;
+
+ FUNC_ENTER(H5S_create, NULL);
+
+ /* Create a new data space */
+ if((ret_value = H5MM_calloc(sizeof(H5S_t)))!=NULL)
+ {
+ ret_value->extent.type = type;
+ ret_value->select.type = H5S_SEL_ALL; /* Entire extent selected by default */
+ }
+
+#ifdef LATER
+done:
+#endif
+ FUNC_LEAVE(ret_value);
+} /* end H5S_create() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Screate
+ PURPOSE
+ Create empty, typed dataspace
+ USAGE
+ hid_t H5Screate(type)
+ H5S_type_t type; IN: Dataspace type to create
+ RETURNS
+ Valid dataspace ID on success, negative on failure
+ DESCRIPTION
+ Creates a new dataspace of a given type. The extent & selection are
+ undefined
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t H5Screate(H5S_class_t type)
+{
+ H5S_t *new_ds=NULL;
hid_t ret_value = FAIL;
- int i;
FUNC_ENTER(H5Screate, FAIL);
- H5TRACE3("i","Is*h*h",rank,dims,maxdims);
- /* Check arguments */
- if (rank<0) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
- "dimensionality cannot be negative");
- }
- if (!dims && dims!=0) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
- "no dimensions specified");
- }
- if (maxdims) {
- for (i=0; i<rank; i++) {
- if (H5S_UNLIMITED!=maxdims[i] && maxdims[i]<dims[i]) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
- "maxdims is smaller than dims");
- }
- }
- }
+ /* Check args */
+ if(type<=H5S_NO_CLASS || type> H5S_SIMPLE) /* don't allow complex dataspace yet */
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "invalid dataspace type");
- /* Create a new data space */
- if (NULL==(ds = H5MM_calloc(sizeof(H5S_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
+ if (NULL==(new_ds=H5S_create(type))) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace");
}
- if(rank>0) /* for creating simple dataspace */
- {
- ds->type = H5S_SIMPLE;
- ds->hslab_def = FALSE; /* no hyperslab defined currently */
-
- /* Initialize rank and dimensions */
- ds->u.simple.rank = rank;
-
- if (NULL==(ds->u.simple.size = H5MM_calloc(1*rank*sizeof(hsize_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- HDmemcpy(ds->u.simple.size, dims, rank*sizeof(hsize_t));
-
- if (maxdims) {
- if (NULL==(ds->u.simple.max=H5MM_calloc(rank*sizeof(hsize_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- HDmemcpy (ds->u.simple.max, maxdims, rank*sizeof(hsize_t));
- }
- } /* end if */
- else /* rank==0, for scalar data space */
- {
- ds->type = H5S_SCALAR;
- ds->u.simple.rank = 0;
- } /* end else */
-
- /* Register the new data space and get an ID for it */
- if ((ret_value = H5I_register(H5_DATASPACE, ds)) < 0) {
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL,
- "unable to register data space for ID");
+
+ /* Atomize */
+ if ((ret_value=H5I_register (H5_DATASPACE, new_ds))<0) {
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space atom");
}
- done:
+done:
if (ret_value < 0) {
- H5MM_xfree(ds);
}
FUNC_LEAVE(ret_value);
-}
+} /* end H5Screate() */
/*-------------------------------------------------------------------------
- * Function: H5Sclose
+ * Function: H5S_close
*
- * Purpose: Release access to a data space object.
+ * Purpose: Releases all memory associated with a data space.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
- * Errors:
- *
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*
@@ -199,33 +179,55 @@ H5Screate_simple (int rank, const hsize_t *dims, const hsize_t *maxdims)
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5Sclose (hid_t space_id)
+herr_t H5S_close(H5S_t *ds)
{
- FUNC_ENTER(H5Sclose, FAIL);
- H5TRACE1("e","i",space_id);
+ FUNC_ENTER(H5S_close, FAIL);
- /* Check args */
- if (H5_DATASPACE != H5I_group(space_id) ||
- NULL == H5I_object(space_id)) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
- /* When the reference count reaches zero the resources are freed */
- if (H5I_dec_ref(space_id) < 0) {
- HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
+ assert(ds);
+
+ /* Release selection (this should come before the extent release) */
+ H5S_select_release(ds);
+
+ /* release extent */
+ switch (ds->extent.type) {
+ case H5S_NO_CLASS:
+ /*nothing needed */
+ break;
+
+ case H5S_SCALAR:
+ /*nothing needed */
+ break;
+
+ case H5S_SIMPLE:
+ H5S_release_simple(&(ds->extent.u.simple));
+ break;
+
+ case H5S_COMPLEX:
+ /* nothing yet */
+ break;
+
+ default:
+ assert("unknown dataspace (extent) type" && 0);
+ break;
}
+
+ /* Release the main structure */
+ H5MM_xfree(ds);
+
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5S_close
+ * Function: H5Sclose
*
- * Purpose: Releases all memory associated with a data space.
+ * Purpose: Release access to a data space object.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
+ * Errors:
+ *
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*
@@ -234,41 +236,25 @@ H5Sclose (hid_t space_id)
*-------------------------------------------------------------------------
*/
herr_t
-H5S_close(H5S_t *ds)
+H5Sclose (hid_t space_id)
{
- FUNC_ENTER(H5S_close, FAIL);
-
- assert(ds);
-
- switch (ds->type) {
- case H5S_SCALAR:
- /*nothing needed */
- break;
-
- case H5S_SIMPLE:
- H5S_close_simple(&(ds->u.simple));
- break;
-
- case H5S_COMPLEX:
- /* nothing */
- break;
+ FUNC_ENTER(H5Sclose, FAIL);
+ H5TRACE1("e","i",space_id);
- default:
- assert("unknown data space type" && 0);
- break;
+ /* Check args */
+ if (H5_DATASPACE != H5I_group(space_id) ||
+ NULL == H5I_object(space_id)) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+ /* When the reference count reaches zero the resources are freed */
+ if (H5I_dec_ref(space_id) < 0) {
+ HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
}
- if(ds->hslab_def==TRUE) {
- H5MM_xfree(ds->h.start);
- H5MM_xfree(ds->h.count);
- H5MM_xfree(ds->h.stride);
- } /* end if */
- H5MM_xfree(ds);
-
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5S_close_simple
+ * Function: H5S_release_simple
*
* Purpose: Releases all memory associated with a simple data space.
* (but doesn't free the simple space itself)
@@ -284,16 +270,16 @@ H5S_close(H5S_t *ds)
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5S_close_simple(H5S_simple_t *simple)
+herr_t H5S_release_simple(H5S_simple_t *simple)
{
- FUNC_ENTER(H5S_close_simple, FAIL);
+ FUNC_ENTER(H5S_release_simple, FAIL);
assert(simple);
- H5MM_xfree(simple->size);
- H5MM_xfree(simple->max);
- H5MM_xfree(simple->perm);
+ if(simple->size)
+ H5MM_xfree(simple->size);
+ if(simple->max)
+ H5MM_xfree(simple->max);
FUNC_LEAVE(SUCCEED);
}
@@ -325,21 +311,18 @@ H5Scopy (hid_t space_id)
H5TRACE1("i","i",space_id);
/* Check args */
- if (H5_DATASPACE!=H5I_group (space_id) ||
- NULL==(src=H5I_object (space_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if (H5_DATASPACE!=H5I_group (space_id) || NULL==(src=H5I_object (space_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
}
/* Copy */
if (NULL==(dst=H5S_copy (src))) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
- "unable to copy data space");
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy data space");
}
/* Atomize */
if ((ret_value=H5I_register (H5_DATASPACE, dst))<0) {
- HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL,
- "unable to register data space atom");
+ HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space atom");
}
FUNC_LEAVE (ret_value);
@@ -347,9 +330,67 @@ H5Scopy (hid_t space_id)
/*-------------------------------------------------------------------------
+ * Function: H5S_extent_copy
+ *
+ * Purpose: Copies a dataspace extent
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 3, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src)
+{
+ int i;
+
+ FUNC_ENTER(H5S_extent_copy, NULL);
+
+ /* Copy the regular fields */
+ *dst=*src;
+
+ switch (src->type) {
+ case H5S_SCALAR:
+ /*nothing needed */
+ break;
+
+ case H5S_SIMPLE:
+ if (src->u.simple.size) {
+ dst->u.simple.size = H5MM_malloc(src->u.simple.rank *
+ sizeof(src->u.simple.size[0]));
+ for (i = 0; i < src->u.simple.rank; i++) {
+ dst->u.simple.size[i] = src->u.simple.size[i];
+ }
+ }
+ if (src->u.simple.max) {
+ dst->u.simple.max = H5MM_malloc(src->u.simple.rank *
+ sizeof(src->u.simple.max[0]));
+ for (i = 0; i < src->u.simple.rank; i++) {
+ dst->u.simple.max[i] = src->u.simple.max[i];
+ }
+ }
+ break;
+
+ case H5S_COMPLEX:
+ /*void */
+ break;
+
+ default:
+ assert("unknown data space type" && 0);
+ break;
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
* Function: H5S_copy
*
- * Purpose: Copies a data space.
+ * Purpose: Copies a data space, by copying the extent and selection through
+ * H5S_extent_copy and H5S_select_copy
*
* Return: Success: A pointer to a new copy of SRC
*
@@ -362,11 +403,9 @@ H5Scopy (hid_t space_id)
*
*-------------------------------------------------------------------------
*/
-H5S_t *
-H5S_copy(const H5S_t *src)
+H5S_t * H5S_copy(const H5S_t *src)
{
H5S_t *dst = NULL;
- int i;
FUNC_ENTER(H5S_copy, NULL);
@@ -376,55 +415,13 @@ H5S_copy(const H5S_t *src)
}
*dst = *src;
- switch (dst->type) {
- case H5S_SCALAR:
- /*nothing needed */
- break;
-
- case H5S_SIMPLE:
- if (dst->u.simple.size) {
- dst->u.simple.size = H5MM_malloc(dst->u.simple.rank *
- sizeof(dst->u.simple.size[0]));
- if (NULL==dst->u.simple.size) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
- for (i = 0; i < dst->u.simple.rank; i++) {
- dst->u.simple.size[i] = src->u.simple.size[i];
- }
- }
- if (dst->u.simple.max) {
- dst->u.simple.max = H5MM_malloc(dst->u.simple.rank *
- sizeof(dst->u.simple.max[0]));
- if (NULL==dst->u.simple.max) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
- for (i = 0; i < dst->u.simple.rank; i++) {
- dst->u.simple.max[i] = src->u.simple.max[i];
- }
- }
- if (dst->u.simple.perm) {
- dst->u.simple.perm = H5MM_malloc(dst->u.simple.rank *
- sizeof(dst->u.simple.perm[0]));
- if (NULL==dst->u.simple.perm) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
- for (i = 0; i < dst->u.simple.rank; i++) {
- dst->u.simple.perm[i] = src->u.simple.perm[i];
- }
- }
- break;
-
- case H5S_COMPLEX:
- /*void */
- break;
-
- default:
- assert("unknown data space type" && 0);
- break;
- }
+ /* Copy the source dataspace's extent */
+ if (H5S_extent_copy(&(dst->extent),&(src->extent))<0)
+ HRETURN_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent");
+
+ /* Copy the source dataspace's selection */
+ if (H5S_select_copy(dst,src)<0)
+ HRETURN_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy select");
FUNC_LEAVE(dst);
}
@@ -455,9 +452,8 @@ H5Sget_npoints (hid_t space_id)
H5TRACE1("h","i",space_id);
/* Check args */
- if (H5_DATASPACE != H5I_group(space_id) ||
- NULL == (ds = H5I_object(space_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data space");
+ if (H5_DATASPACE != H5I_group(space_id) || NULL == (ds = H5I_object(space_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data space");
}
ret_value = H5S_get_npoints(ds);
@@ -492,35 +488,25 @@ H5S_get_npoints(const H5S_t *ds)
/* check args */
assert(ds);
- switch (ds->type) {
- case H5S_SCALAR:
- ret_value = 1;
- break;
-
- case H5S_SIMPLE:
- /*
- * Count the elements selected by the hypeslab if there is one,
- * otherwise count all the elements.
- */
- if (ds->hslab_def) {
- for (ret_value=1, i=0; i<ds->u.simple.rank; i++) {
- ret_value *= ds->h.count[i];
- }
- } else {
- for (ret_value=1, i=0; i<ds->u.simple.rank; i++) {
- ret_value *= ds->u.simple.size[i];
- }
- }
- break;
-
- case H5S_COMPLEX:
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
- "complex data spaces are not supported yet");
-
- default:
- assert("unknown data space class" && 0);
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
- "internal error (unknown data space class)");
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ ret_value = 1;
+ break;
+
+ case H5S_SIMPLE:
+ for (ret_value=1, i=0; i<ds->extent.u.simple.rank; i++) {
+ ret_value *= ds->extent.u.simple.size[i];
+ }
+ break;
+
+ case H5S_COMPLEX:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
+ "complex data spaces are not supported yet");
+
+ default:
+ assert("unknown data space class" && 0);
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
+ "internal error (unknown data space class)");
}
FUNC_LEAVE(ret_value);
@@ -558,36 +544,36 @@ H5S_get_npoints_max(const H5S_t *ds)
/* check args */
assert(ds);
- switch (ds->type) {
- case H5S_SCALAR:
- ret_value = 1;
- break;
-
- case H5S_SIMPLE:
- if (ds->u.simple.max) {
- for (ret_value=1, i=0; i<ds->u.simple.rank; i++) {
- if (H5S_UNLIMITED==ds->u.simple.max[i]) {
- ret_value = MAX_HSIZET;
- break;
- } else {
- ret_value *= ds->u.simple.max[i];
- }
- }
- } else {
- for (ret_value=1, i=0; i<ds->u.simple.rank; i++) {
- ret_value *= ds->u.simple.size[i];
- }
- }
- break;
-
- case H5S_COMPLEX:
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
- "complex data spaces are not supported yet");
-
- default:
- assert("unknown data space class" && 0);
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
- "internal error (unknown data space class)");
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ ret_value = 1;
+ break;
+
+ case H5S_SIMPLE:
+ if (ds->extent.u.simple.max) {
+ for (ret_value=1, i=0; i<ds->extent.u.simple.rank; i++) {
+ if (H5S_UNLIMITED==ds->extent.u.simple.max[i]) {
+ ret_value = MAX_HSIZET;
+ break;
+ } else {
+ ret_value *= ds->extent.u.simple.max[i];
+ }
+ }
+ } else {
+ for (ret_value=1, i=0; i<ds->extent.u.simple.rank; i++) {
+ ret_value *= ds->extent.u.simple.size[i];
+ }
+ }
+ break;
+
+ case H5S_COMPLEX:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
+ "complex data spaces are not supported yet");
+
+ default:
+ assert("unknown data space class" && 0);
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0,
+ "internal error (unknown data space class)");
}
FUNC_LEAVE(ret_value);
@@ -620,9 +606,8 @@ H5Sget_ndims (hid_t space_id)
H5TRACE1("Is","i",space_id);
/* Check args */
- if (H5_DATASPACE != H5I_group(space_id) ||
- NULL == (ds = H5I_object(space_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if (H5_DATASPACE != H5I_group(space_id) || NULL == (ds = H5I_object(space_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
}
ret_value = H5S_get_ndims(ds);
@@ -656,23 +641,23 @@ H5S_get_ndims(const H5S_t *ds)
/* check args */
assert(ds);
- switch (ds->type) {
- case H5S_SCALAR:
- ret_value = 0;
- break;
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ ret_value = 0;
+ break;
- case H5S_SIMPLE:
- ret_value = ds->u.simple.rank;
- break;
+ case H5S_SIMPLE:
+ ret_value = ds->extent.u.simple.rank;
+ break;
- case H5S_COMPLEX:
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "complex data spaces are not supported yet");
+ case H5S_COMPLEX:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
+ "complex data spaces are not supported yet");
- default:
- assert("unknown data space class" && 0);
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "internal error (unknown data space class)");
+ default:
+ assert("unknown data space class" && 0);
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
+ "internal error (unknown data space class)");
}
FUNC_LEAVE(ret_value);
@@ -710,9 +695,8 @@ H5Sget_dims (hid_t space_id, hsize_t dims[]/*out*/, hsize_t maxdims[]/*out*/)
H5TRACE1("Is","i",space_id);
/* Check args */
- if (H5_DATASPACE != H5I_group(space_id) ||
- NULL == (ds = H5I_object(space_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if (H5_DATASPACE != H5I_group(space_id) || NULL == (ds = H5I_object(space_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
}
ret_value = H5S_get_dims(ds, dims, maxdims);
@@ -746,35 +730,35 @@ H5S_get_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[])
/* check args */
assert(ds);
- assert(dims);
-
- switch (ds->type) {
- case H5S_SCALAR:
- ret_value = 0;
- break;
-
- case H5S_SIMPLE:
- ret_value = ds->u.simple.rank;
- for (i=0; i<ret_value; i++) {
- if (dims) dims[i] = ds->u.simple.size[i];
- if (max_dims) {
- if (ds->u.simple.max) {
- max_dims[i] = ds->u.simple.max[i];
- } else {
- max_dims[i] = ds->u.simple.size[i];
- }
- }
- }
- break;
-
- case H5S_COMPLEX:
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "complex data spaces are not supported yet");
-
- default:
- assert("unknown data space class" && 0);
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "internal error (unknown data space class)");
+
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ ret_value = 0;
+ break;
+
+ case H5S_SIMPLE:
+ ret_value = ds->extent.u.simple.rank;
+ for (i=0; i<ret_value; i++) {
+ if (dims)
+ dims[i] = ds->extent.u.simple.size[i];
+ if (max_dims) {
+ if (ds->extent.u.simple.max) {
+ max_dims[i] = ds->extent.u.simple.max[i];
+ } else {
+ max_dims[i] = ds->extent.u.simple.size[i];
+ }
+ }
+ }
+ break;
+
+ case H5S_COMPLEX:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
+ "complex data spaces are not supported yet");
+
+ default:
+ assert("unknown data space class" && 0);
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
+ "internal error (unknown data space class)");
}
FUNC_LEAVE(ret_value);
@@ -805,27 +789,22 @@ H5S_modify(H5G_entry_t *ent, const H5S_t *ds)
assert(ent);
assert(ds);
- switch (ds->type) {
- case H5S_SCALAR:
-#ifdef OLD_WAY
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "scalar data spaces are not implemented yet");
-#endif
-
- case H5S_SIMPLE:
- if (H5O_modify(ent, H5O_SDSPACE, 0, 0, &(ds->u.simple)) < 0) {
- HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
- "can't update simple data space message");
- }
- break;
-
- case H5S_COMPLEX:
- HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "complex data spaces are not implemented yet");
-
- default:
- assert("unknown data space class" && 0);
- break;
+ switch (ds->extent.type) {
+ case H5S_SCALAR:
+ case H5S_SIMPLE:
+ if (H5O_modify(ent, H5O_SDSPACE, 0, 0, &(ds->extent.u.simple)) < 0) {
+ HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "can't update simple data space message");
+ }
+ break;
+
+ case H5S_COMPLEX:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
+ "complex data spaces are not implemented yet");
+
+ default:
+ assert("unknown data space class" && 0);
+ break;
}
FUNC_LEAVE(SUCCEED);
@@ -860,24 +839,26 @@ H5S_read(H5G_entry_t *ent)
assert(ent);
if (NULL==(ds = H5MM_calloc(sizeof(H5S_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
- if (H5O_read(ent, H5O_SDSPACE, 0, &(ds->u.simple))) {
- ds->type = H5S_SIMPLE;
-
+ if (H5O_read(ent, H5O_SDSPACE, 0, &(ds->extent.u.simple))) {
+ ds->extent.type = H5S_SIMPLE;
} else {
- ds->type = H5S_SCALAR;
+ ds->extent.type = H5S_SCALAR;
}
+ /* Default to entire dataspace being selected */
+ ds->select.type=H5S_SEL_ALL;
+
FUNC_LEAVE(ds);
}
/*-------------------------------------------------------------------------
* Function: H5S_cmp
*
- * Purpose: Compares two data spaces.
+ * Purpose: Compares two data space extents.
*
* Return: Success: 0 if DS1 and DS2 are the same.
* <0 if DS1 is less than DS2.
@@ -889,6 +870,7 @@ H5S_read(H5G_entry_t *ent)
* Wednesday, December 10, 1997
*
* Modifications:
+ * 6/9/98 Changed to only compare extents - QAK
*
*-------------------------------------------------------------------------
*/
@@ -904,61 +886,42 @@ H5S_cmp(const H5S_t *ds1, const H5S_t *ds2)
assert(ds2);
/* compare */
- if (ds1->type < ds2->type)
- HRETURN(-1);
- if (ds1->type > ds2->type)
- HRETURN(1);
-
- switch (ds1->type) {
- case H5S_SIMPLE:
- if (ds1->u.simple.rank < ds2->u.simple.rank)
- HRETURN(-1);
- if (ds1->u.simple.rank > ds2->u.simple.rank)
- HRETURN(1);
-
- for (i = 0; i < ds1->u.simple.rank; i++) {
- if (ds1->u.simple.size[i] < ds2->u.simple.size[i])
- HRETURN(-1);
- if (ds1->u.simple.size[i] > ds2->u.simple.size[i])
- HRETURN(1);
- }
-
- /* don't compare max dimensions */
-
- for (i = 0; i < ds1->u.simple.rank; i++) {
- if ((ds1->u.simple.perm ? ds1->u.simple.perm[i] : i) <
- (ds2->u.simple.perm ? ds2->u.simple.perm[i] : i))
- HRETURN(-1);
- if ((ds1->u.simple.perm ? ds2->u.simple.perm[i] : i) >
- (ds2->u.simple.perm ? ds2->u.simple.perm[i] : i))
- HRETURN(1);
- }
-
- /* Check if we should compare hyperslab definitions */
- if(ds1->hslab_def==TRUE && ds2->hslab_def==TRUE) {
- for (i = 0; i < ds1->u.simple.rank; i++) {
- if (ds1->h.start[i] < ds2->h.start[i])
- HRETURN(-1);
- if (ds1->h.start[i] > ds2->h.start[i])
- HRETURN(1);
- if (ds1->h.count[i] < ds2->h.count[i])
- HRETURN(-1);
- if (ds1->h.count[i] > ds2->h.count[i])
- HRETURN(1);
- if (ds1->h.stride[i] < ds2->h.stride[i])
- HRETURN(-1);
- if (ds1->h.stride[i] > ds2->h.stride[i])
- HRETURN(1);
- }
- } else {
- if(ds1->hslab_def!=ds2->hslab_def)
- HRETURN(ds1->hslab_def==TRUE ? 1 : -1);
- }
-
- break;
-
- default:
- assert("not implemented yet" && 0);
+ if (ds1->extent.type < ds2->extent.type)
+ HRETURN(-1);
+ if (ds1->extent.type > ds2->extent.type)
+ HRETURN(1);
+
+ switch (ds1->extent.type) {
+ case H5S_SIMPLE:
+ if (ds1->extent.u.simple.rank < ds2->extent.u.simple.rank)
+ HRETURN(-1);
+ if (ds1->extent.u.simple.rank > ds2->extent.u.simple.rank)
+ HRETURN(1);
+
+ for (i = 0; i < ds1->extent.u.simple.rank; i++) {
+ if (ds1->extent.u.simple.size[i] < ds2->extent.u.simple.size[i])
+ HRETURN(-1);
+ if (ds1->extent.u.simple.size[i] > ds2->extent.u.simple.size[i])
+ HRETURN(1);
+ }
+
+ /* don't compare max dimensions */
+
+#ifdef LATER
+ for (i = 0; i < ds1->extent.u.simple.rank; i++) {
+ if ((ds1->extent.u.simple.perm ? ds1->extent.u.simple.perm[i] : i) <
+ (ds2->extent.u.simple.perm ? ds2->extent.u.simple.perm[i] : i))
+ HRETURN(-1);
+ if ((ds1->extent.u.simple.perm ? ds2->extent.u.simple.perm[i] : i) >
+ (ds2->extent.u.simple.perm ? ds2->extent.u.simple.perm[i] : i))
+ HRETURN(1);
+ }
+#endif
+
+ break;
+
+ default:
+ assert("not implemented yet" && 0);
}
FUNC_LEAVE(0);
@@ -988,7 +951,7 @@ H5S_is_simple(const H5S_t *sdim)
/* Check args and all the boring stuff. */
assert(sdim);
- ret_value = sdim->type == H5S_SIMPLE ? TRUE : FALSE; /* Currently all dataspaces are simple, but check anyway */
+ ret_value = sdim->extent.type == H5S_SIMPLE ? TRUE : FALSE;
FUNC_LEAVE(ret_value);
}
@@ -1034,310 +997,108 @@ H5Sis_simple (hid_t sid)
/*--------------------------------------------------------------------------
NAME
- H5Sset_space
+ H5Sset_extent_simple
PURPOSE
- Determine the size of a dataspace
+ Sets the size of a simple dataspace
USAGE
- herr_t H5Sset_space(sid, rank, dims)
- hid_t sid; IN: Dataspace object to query
- intn rank; IN: # of dimensions for the dataspace
- const size_t *dims; IN: Size of each dimension for the dataspace
+ herr_t H5Sset_extent_simple(sid, rank, dims, max)
+ hid_t sid; IN: Dataspace object to query
+ intn rank; IN: # of dimensions for the dataspace
+ const size_t *dims; IN: Size of each dimension for the dataspace
+ const size_t *max; IN: Maximum size of each dimension for the dataspace
RETURNS
SUCCEED/FAIL
DESCRIPTION
This function sets the number and size of each dimension in the
- dataspace. Setting RANK to a value of zero allows scalar objects to be
- created. Dimensions are specified from slowest to fastest changing in the
- DIMS array (i.e. 'C' order). Setting the size of a dimension to zero
- indicates that the dimension is of unlimited size and should be allowed to
- expand. Currently, only the first dimension in the array (the slowest) may
- be unlimited in size.
+ dataspace. Setting RANK to a value of zero converts the dataspace to a
+ scalar dataspace. Dimensions are specified from slowest to fastest changing
+ in the DIMS array (i.e. 'C' order). Setting the size of a dimension in the
+ MAX array to zero indicates that the dimension is of unlimited size and
+ should be allowed to expand. If MAX is NULL, the dimensions in the DIMS
+ array are used as the maximum dimensions. Currently, only the first
+ dimension in the array (the slowest) may be unlimited in size.
--------------------------------------------------------------------------*/
herr_t
-H5Sset_space (hid_t sid, int rank, const hsize_t *dims)
+H5Sset_extent_simple (hid_t sid, int rank, const hsize_t *dims, const hsize_t *max)
{
H5S_t *space = NULL; /* dataspace to modify */
intn u; /* local counting variable */
herr_t ret_value = SUCCEED;
- FUNC_ENTER(H5Sset_space, FAIL);
- H5TRACE3("e","iIs*h",sid,rank,dims);
+ FUNC_ENTER(H5Sset_extent_simple, FAIL);
/* Check args */
if ((space = H5I_object(sid)) == NULL) {
- HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space");
+ HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space");
}
if (rank > 0 && dims == NULL) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified");
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified");
}
if (rank<0) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank");
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank");
}
if (dims) {
- for (u=0; u<rank; u++) {
- if (dims[u]<=0) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
- "invalid dimension size");
- }
- }
+ for (u=0; u<rank; u++) {
+ if (((max!=NULL && max[u]!=H5S_UNLIMITED) || max==NULL) && dims[u]==0) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "invalid dimension size");
+ }
+ }
+ }
+ if (max!=NULL) {
+ if(dims==NULL)
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "maximum dimension specified, but no current dimensions specified");
+ for (u=0; u<rank; u++) {
+ if (max[u]!=H5S_UNLIMITED && max[u]<dims[u]) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "invalid maximum dimension size");
+ }
+ }
}
/* shift out of the previous state to a "simple" dataspace */
- switch (space->type) {
- case H5S_SCALAR:
- case H5S_SIMPLE:
- /* do nothing */
- break;
-
- case H5S_COMPLEX:
- /*
- * eventually this will destroy whatever "complex" dataspace info
- * is retained, right now it's an error
- */
- /* Fall through to report error */
-
- default:
- HRETURN_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL,
- "unknown data space class");
- }
- space->type = H5S_SIMPLE;
-
- /* Reset hyperslab definition, if one is defined */
- if(space->hslab_def==TRUE) {
- H5MM_xfree(space->h.start);
- H5MM_xfree(space->h.count);
- H5MM_xfree(space->h.stride);
- space->hslab_def=FALSE;
+ switch (space->extent.type) {
+ case H5S_SCALAR:
+ /* do nothing */
+ break;
+
+ case H5S_SIMPLE:
+ H5S_release_simple(&(space->extent.u.simple));
+ break;
+
+ case H5S_COMPLEX:
+ /*
+ * eventually this will destroy whatever "complex" dataspace info
+ * is retained, right now it's an error
+ */
+ /* Fall through to report error */
+
+ default:
+ HRETURN_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL,
+ "unknown data space class");
}
- /* Free the old space for now */
- if (space->u.simple.size != NULL)
- space->u.simple.size = H5MM_xfree(space->u.simple.size);
- if (space->u.simple.max != NULL)
- space->u.simple.max = H5MM_xfree(space->u.simple.max);
- if (space->u.simple.perm != NULL)
- space->u.simple.max = H5MM_xfree(space->u.simple.perm);
-
if (rank == 0) { /* scalar variable */
- space->type = H5S_SCALAR;
- space->u.simple.rank = 0; /* set to scalar rank */
+ space->extent.type = H5S_SCALAR;
+ space->extent.u.simple.rank = 0; /* set to scalar rank */
} else {
- /* Set the rank and copy the dims */
- space->u.simple.rank = rank;
- if (NULL==(space->u.simple.size=H5MM_calloc(rank*sizeof(hsize_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- HDmemcpy(space->u.simple.size, dims, sizeof(hsize_t) * rank);
+ space->extent.type = H5S_SIMPLE;
+
+ /* Set the rank and copy the dims */
+ space->extent.u.simple.rank = rank;
+ space->extent.u.simple.size = H5MM_malloc(rank*sizeof(hsize_t));
+ HDmemcpy(space->extent.u.simple.size, dims, sizeof(hsize_t) * rank);
+
+ /* Copy the maximum dimensions if specified */
+ if(max!=NULL) {
+ space->extent.u.simple.max = H5MM_malloc(rank*sizeof(hsize_t));
+ HDmemcpy(space->extent.u.simple.max, max, sizeof(hsize_t) * rank);
+ } /* end if */
}
FUNC_LEAVE(ret_value);
}
-/*--------------------------------------------------------------------------
- NAME
- H5Sset_hyperslab
- PURPOSE
- Select a hyperslab from a simple dataspace
- USAGE
- herr_t H5Sset_hyperslab(sid, start, count, stride)
- hid_t sid; IN: Dataspace object to select hyperslab from
- const int *start; IN: Starting location for hyperslab to select
- const size_t *count; IN: Number of elements in hyperslab
- const size_t *stride; IN: Packing of elements in hyperslab
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function selects a hyperslab from a simple dataspace. The stride
- array may be used to sub-sample the hyperslab chosen, a value of 1 in each
- position of the stride array selects contiguous elements in the array,
- a value of 2 selects every other element, etc. If the stride parameter is
- set to NULL, a contiguous hyperslab is chosen. The values in the start and
- count arrays may be negative, to allow for selecting hyperslabs in chunked
- datasets which extend in arbitrary directions.
---------------------------------------------------------------------------*/
-herr_t
-H5Sset_hyperslab (hid_t sid, const hssize_t *start, const hsize_t *count,
- const hsize_t *stride)
-{
- H5S_t *space = NULL; /* dataspace to modify */
- hsize_t *tmp_stride=NULL; /* temp. copy of stride */
- intn u; /* local counting variable */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Sset_hyperslab, FAIL);
- H5TRACE4("e","i*Hs*h*h",sid,start,count,stride);
-
- /* Get the object */
- if (H5_DATASPACE != H5I_group(sid) || (space = H5I_object(sid)) == NULL) {
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a data space");
- }
- if (start == NULL || count==NULL) {
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
- "invalid hyperslab selected");
- }
-
- /* We can't modify other types of dataspaces currently, so error out */
- if (space->type!=H5S_SIMPLE) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL,
- "unknown dataspace type");
- }
-
- /* Set up stride values for later use */
- tmp_stride=H5MM_malloc(space->u.simple.rank*sizeof(tmp_stride[0]));
- if (NULL==tmp_stride) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- for (u=0; u<space->u.simple.rank; u++) {
- tmp_stride[u] = stride ? stride[u] : 1;
- }
-
- /* Range check arguments */
- for (u=0; u<space->u.simple.rank; u++) {
- if (start[u]<0 || (hsize_t)(start[u])>=space->u.simple.size[u]) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
- "hyperslab bounds out of range");
- }
- if (start[u]<0 ||
- start[u]+(count[u]*tmp_stride[u])>space->u.simple.size[u]) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
- "hyperslab bounds out of range");
- }
- }
-
- /* Allocate space for the hyperslab information */
- if (NULL==space->h.start) {
- space->h.start=H5MM_calloc(space->u.simple.rank*sizeof(hsize_t));
- space->h.count=H5MM_calloc(space->u.simple.rank*sizeof(hsize_t));
- space->h.stride=H5MM_calloc(space->u.simple.rank*sizeof(hsize_t));
- if (NULL==space->h.start ||
- NULL==space->h.count ||
- NULL==space->h.stride) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- }
-
- /* Build hyperslab */
- for(u=0; u<space->u.simple.rank; u++) {
- space->h.start[u] = start[u];
- space->h.count[u] = count[u];
- space->h.stride[u] = tmp_stride[u];
- }
- space->hslab_def=TRUE;
-
-done:
- if (ret_value == FAIL) { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
- H5MM_xfree(tmp_stride);
- FUNC_LEAVE(ret_value);
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5Sget_hyperslab
- *
- * Purpose: Retrieves information about the hyperslab from a simple data
- * space. If no hyperslab has been defined then the hyperslab
- * is the same as the entire array.
- *
- * Return: Success: Hyperslab dimensionality.
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Wednesday, January 28, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-int
-H5Sget_hyperslab (hid_t sid, hssize_t offset[]/*out*/, hsize_t size[]/*out*/,
- hsize_t stride[]/*out*/)
-{
- const H5S_t *ds = NULL;
- intn ret_value = FAIL;
-
- FUNC_ENTER (H5Sget_hyperslab, FAIL);
- H5TRACE1("Is","i",sid);
-
- /* Check args */
- if (H5_DATASPACE!=H5I_group (sid) || NULL==(ds=H5I_object (sid))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
-
- /* Get hyperslab info */
- if ((ret_value=H5S_get_hyperslab (ds, offset, size, stride))<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
- "unable to retrieve hyperslab information");
- }
-
- FUNC_LEAVE (ret_value);
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5S_get_hyperslab
- *
- * Purpose: Retrieves information about the hyperslab from a simple data
- * space. If no hyperslab has been defined then the hyperslab
- * is the same as the entire array.
- *
- * Return: Success: Hyperslab dimensionality.
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Wednesday, January 28, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-intn
-H5S_get_hyperslab (const H5S_t *ds, hssize_t offset[]/*out*/,
- hsize_t size[]/*out*/, hsize_t stride[]/*out*/)
-{
- intn i;
- intn ret_value = FAIL;
-
- FUNC_ENTER (H5S_get_hyperslab, FAIL);
-
- /* Check args */
- assert (ds);
- switch (ds->type) {
- case H5S_SCALAR:
- break;
-
- case H5S_SIMPLE:
- if (ds->hslab_def) {
- for (i=0; i<ds->u.simple.rank; i++) {
- if (offset) offset[i] = ds->h.start[i];
- if (size) size[i] = ds->h.count[i];
- if (stride) stride[i] = ds->h.stride[i];
- }
- } else {
- for (i=0; i<ds->u.simple.rank; i++) {
- if (offset) offset[i] = 0;
- if (size) size[i] = ds->u.simple.size[i];
- if (stride) stride[i] = 1;
- }
- }
- ret_value = ds->u.simple.rank;
- break;
-
- case H5S_COMPLEX: /*fall through*/
- default:
- HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
- "hyperslabs not supported for this type of space");
- }
-
- FUNC_LEAVE (ret_value);
-}
-
-
/*-------------------------------------------------------------------------
* Function: H5S_find
*
@@ -1358,44 +1119,138 @@ H5S_get_hyperslab (const H5S_t *ds, hssize_t offset[]/*out*/,
*
*-------------------------------------------------------------------------
*/
-const H5S_conv_t *
-H5S_find (const H5S_t *mem_space, const H5S_t *file_space)
+herr_t
+H5S_find (H5S_conv_t *conv, const H5S_t *mem_space, const H5S_t *file_space)
{
- static H5S_conv_t _conv;
- static const H5S_conv_t *conv = NULL;
-
- FUNC_ENTER (H5S_find, NULL);
+ FUNC_ENTER (H5S_find, FAIL);
/* Check args */
- assert (mem_space && (H5S_SIMPLE==mem_space->type || H5S_SCALAR==mem_space->type));
- assert (file_space && (H5S_SIMPLE==file_space->type || H5S_SCALAR==mem_space->type));
+ assert (conv);
+ assert (mem_space && (H5S_SIMPLE==mem_space->extent.type || H5S_SCALAR==mem_space->extent.type));
+ assert (file_space && (H5S_SIMPLE==file_space->extent.type || H5S_SCALAR==mem_space->extent.type));
/*
* We can't do conversion if the source and destination select a
* different number of data points.
*/
- if (H5S_get_npoints (mem_space) != H5S_get_npoints (file_space)) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_BADRANGE, NULL,
+ if (H5S_select_npoints (mem_space) != H5S_select_npoints (file_space)) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL,
"memory and file data spaces are different sizes");
}
+#ifdef OLD_WAY
/*
* Initialize pointers. This will eventually be a table lookup based
* on the source and destination data spaces, similar to H5T_find(), but
* for now we only support simple data spaces.
*/
if (!conv) {
- _conv.init = H5S_simp_init;
- _conv.fgath = H5S_simp_fgath;
- _conv.mscat = H5S_simp_mscat;
- _conv.mgath = H5S_simp_mgath;
- _conv.fscat = H5S_simp_fscat;
- _conv.read = H5S_simp_read;
- _conv.write = H5S_simp_write;
- conv = &_conv;
+ _conv.init = H5S_simp_init;
+ _conv.fgath = H5S_simp_fgath;
+ _conv.mscat = H5S_simp_mscat;
+ _conv.mgath = H5S_simp_mgath;
+ _conv.fscat = H5S_simp_fscat;
+ _conv.read = H5S_simp_read;
+ _conv.write = H5S_simp_write;
+ conv = &_conv;
}
+#else
+ /* Set up the function pointers for file transfers */
+ switch(file_space->select.type) {
+ case H5S_SEL_POINTS:
+#ifdef QAK
+printf("%s: file space has point selection\n",FUNC);
+#endif /* QAK */
+ conv->finit = H5S_point_init;
+ conv->favail = H5S_point_favail;
+ conv->fgath = H5S_point_fgath;
+ conv->fscat = H5S_point_fscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_ALL:
+#ifdef QAK
+printf("%s: file space has all selection\n",FUNC);
+#endif /* QAK */
+ conv->finit = H5S_all_init;
+ conv->favail = H5S_all_favail;
+ conv->fgath = H5S_all_fgath;
+ conv->fscat = H5S_all_fscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_HYPERSLABS:
+#ifdef QAK
+printf("%s: file space has hyperslab selection\n",FUNC);
+#endif /* QAK */
+ conv->finit = H5S_hyper_init;
+ conv->favail = H5S_hyper_favail;
+ conv->fgath = H5S_hyper_fgath;
+ conv->fscat = H5S_hyper_fscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_NONE:
+ default:
+#ifdef QAK
+printf("%s: file space has unknown selection\n",FUNC);
+#endif /* QAK */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL,
+ "invalid file dataspace selection type");
+ } /* end switch */
+
+ /* Set up the function pointers for background & memory transfers */
+ switch(mem_space->select.type) {
+ case H5S_SEL_POINTS:
+#ifdef QAK
+printf("%s: memory space has point selection\n",FUNC);
+#endif /* QAK */
+ conv->minit = H5S_point_init;
+ conv->binit = H5S_point_init;
+ conv->mgath = H5S_point_mgath;
+ conv->mscat = H5S_point_mscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_ALL:
+#ifdef QAK
+printf("%s: memory space has all selection\n",FUNC);
+#endif /* QAK */
+ conv->minit = H5S_all_init;
+ conv->binit = H5S_all_init;
+ conv->mgath = H5S_all_mgath;
+ conv->mscat = H5S_all_mscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_HYPERSLABS:
+#ifdef QAK
+printf("%s: memory space has hyperslab selection\n",FUNC);
+#endif /* QAK */
+ conv->minit = H5S_hyper_init;
+ conv->binit = H5S_hyper_init;
+ conv->mgath = H5S_hyper_mgath;
+ conv->mscat = H5S_hyper_mscat;
+ conv->read = NULL;
+ conv->write = NULL;
+ break;
+
+ case H5S_SEL_NONE:
+ default:
+#ifdef QAK
+printf("%s: memory space has unknown selection\n",FUNC);
+#endif /* QAK */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL,
+ "invalid file dataspace selection type");
+ } /* end switch */
+#endif /* OLD_WAY */
- FUNC_LEAVE (conv);
+ FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
@@ -1422,30 +1277,97 @@ H5S_extend (H5S_t *space, const hsize_t *size)
FUNC_ENTER (H5S_extend, FAIL);
/* Check args */
- assert (space && H5S_SIMPLE==space->type);
+ assert (space && H5S_SIMPLE==space->extent.type);
assert (size);
- for (i=0; i<space->u.simple.rank; i++) {
- if (space->u.simple.size[i]<size[i]) {
- if (space->u.simple.max &&
- H5S_UNLIMITED!=space->u.simple.max[i] &&
- space->u.simple.max[i]<size[i]) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
- "dimension cannot be increased");
- }
- ret_value++;
- }
+ for (i=0; i<space->extent.u.simple.rank; i++) {
+ if (space->extent.u.simple.size[i]<size[i]) {
+ if (space->extent.u.simple.max &&
+ H5S_UNLIMITED!=space->extent.u.simple.max[i] &&
+ space->extent.u.simple.max[i]<size[i]) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "dimension cannot be increased");
+ }
+ ret_value++;
+ }
}
/* Update */
if (ret_value) {
- for (i=0; i<space->u.simple.rank; i++) {
- if (space->u.simple.size[i]<size[i]) {
- space->u.simple.size[i] = size[i];
- }
- }
+ for (i=0; i<space->extent.u.simple.rank; i++) {
+ if (space->extent.u.simple.size[i]<size[i]) {
+ space->extent.u.simple.size[i] = size[i];
+ }
+ }
}
FUNC_LEAVE (ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Screate_simple
+ *
+ * Purpose: Creates a new simple data space object and opens it for
+ * access. The DIMS argument is the size of the simple dataset
+ * and the MAXDIMS argument is the upper limit on the size of
+ * the dataset. MAXDIMS may be the null pointer in which case
+ * the upper limit is the same as DIMS. If an element of
+ * MAXDIMS is H5S_UNLIMITED then the corresponding dimension is
+ * unlimited, otherwise no element of MAXDIMS should be smaller
+ * than the corresponding element of DIMS.
+ *
+ * Return: Success: The ID for the new simple data space object.
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, January 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Screate_simple (int rank, const hsize_t *dims, const hsize_t *maxdims)
+{
+ hid_t ret_value = FAIL;
+ int i;
+
+ FUNC_ENTER(H5Screate, FAIL);
+
+ /* Check arguments */
+ if (rank<0) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "dimensionality cannot be negative");
+ }
+ if (!dims && dims!=0) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "no dimensions specified");
+ }
+ if (maxdims) {
+ for (i=0; i<rank; i++) {
+ if (H5S_UNLIMITED!=maxdims[i] && maxdims[i]<dims[i]) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "maxdims is smaller than dims");
+ }
+ }
+ }
+
+ if((ret_value=H5Screate(H5S_SIMPLE))==FAIL)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL,
+ "can't create simple dataspace");
+
+ if(H5Sset_extent_simple(ret_value,rank,dims,maxdims)<0) {
+ H5Sclose(ret_value);
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "can't set dimensions");
+ } /* end if */
+
+done:
+ if (ret_value < 0) {
+ }
+ FUNC_LEAVE(ret_value);
+}
diff --git a/src/H5Sall.c b/src/H5Sall.c
new file mode 100644
index 0000000..f35b23b
--- /dev/null
+++ b/src/H5Sall.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Tuesday, June 16, 1998
+ *
+ * Purpose: "All" selection data space I/O functions.
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Sprivate.h>
+#include <H5Vprivate.h>
+
+/* Interface initialization */
+#define PABLO_MASK H5S_all_mask
+#define INTERFACE_INIT NULL
+static intn interface_initialize_g = FALSE;
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_init
+ *
+ * Purpose: Initializes iteration information for all selection.
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_all_init (const struct H5O_layout_t __unused__ *layout,
+ const H5S_t *space, H5S_sel_iter_t *sel_iter)
+{
+ FUNC_ENTER (H5S_all_init, FAIL);
+
+ /* Check args */
+ assert (layout);
+ assert (space && H5S_SEL_ALL==space->select.type);
+ assert (sel_iter);
+
+ /* Initialize the number of elements to iterate over */
+ sel_iter->all.elmt_left=H5S_get_npoints(space);
+
+ /* Start at the upper left location */
+ sel_iter->all.offset=0;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_favail
+ *
+ * Purpose: Figure out the optimal number of elements to transfer to/from the file
+ *
+ * Return: non-negative number of elements on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *sel_iter, size_t max)
+{
+ hsize_t nelmts;
+ int m_ndims; /* file dimensionality */
+ hsize_t size[H5O_LAYOUT_NDIMS]; /*size of selected hyperslab */
+ hsize_t acc;
+ int i;
+
+ FUNC_ENTER (H5S_all_favail, FAIL);
+
+ /* Check args */
+ assert (space && H5S_SEL_ALL==space->select.type);
+ assert (sel_iter);
+
+ /*
+ * The stripmine size is such that only the slowest varying dimension can
+ * be split up. We choose the largest possible strip mine size which is
+ * not larger than the desired size.
+ */
+ m_ndims = H5S_get_dims (space, size, NULL);
+ for (i=m_ndims-1, acc=1; i>0; --i)
+ acc *= size[i];
+ nelmts = (max/acc) * acc;
+ if (nelmts<=0) {
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
+ "strip mine buffer is too small");
+ }
+
+ FUNC_LEAVE (MIN(sel_iter->all.elmt_left,nelmts));
+} /* H5S_all_favail() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_fgath
+ *
+ * Purpose: Gathers data points from file F and accumulates them in the
+ * type conversion buffer BUF. The LAYOUT argument describes
+ * how the data is stored on disk and EFL describes how the data
+ * is organized in external files. ELMT_SIZE is the size in
+ * bytes of a datum which this function treats as opaque.
+ * FILE_SPACE describes the data space of the dataset on disk
+ * and the elements that have been selected for reading (via
+ * hyperslab, etc). This function will copy at most NELMTS elements.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *_buf/*out*/)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ uint8 *buf=(uint8 *)_buf; /* Alias for pointer arithmetic */
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*dimensionality of space*/
+ intn i; /*counters */
+
+ FUNC_ENTER (H5S_all_fgath, 0);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (buf);
+
+ /*
+ * Get hyperslab information to determine what elements are being
+ * selected (there might eventually be other selection methods too).
+ * We only support hyperslabs with unit sample because there's no way to
+ * currently pass sample information into H5F_arr_read() much less
+ * H5F_istore_read().
+ */
+ if ((space_ndims=H5S_get_dims (file_space, hsize, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
+ "unable to retrieve hyperslab parameters");
+ }
+ HDmemset(file_offset,0,sizeof(hssize_t)*space_ndims);
+
+ /* Adjust the slowest varying dimension to take care of strip mining */
+ for (i=1, acc=1; i<space_ndims; i++)
+ acc *= hsize[i];
+ assert (0==file_iter->all.offset % acc);
+ assert (0==nelmts % acc);
+ file_offset[0] += file_iter->all.offset / acc;
+ hsize[0] = nelmts / acc;
+
+ /* The fastest varying dimension is for the data point itself */
+ file_offset[space_ndims] = 0;
+ hsize[space_ndims] = elmt_size;
+ HDmemset (zero, 0, layout->ndims*sizeof(*zero));
+
+ /*
+ * Gather from file.
+ */
+ if (H5F_arr_read (f, layout, comp, efl, hsize, hsize, zero, file_offset,
+ xfer_mode, buf/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
+ }
+
+ /* Advance iterator */
+ file_iter->all.elmt_left--;
+ file_iter->all.offset+=nelmts;
+
+ FUNC_LEAVE (nelmts);
+} /* H5S_all_fgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_fscat
+ *
+ * Purpose: Scatters dataset elements from the type conversion buffer BUF
+ * to the file F where the data points are arranged according to
+ * the file data space FILE_SPACE and stored according to
+ * LAYOUT and EFL. Each element is ELMT_SIZE bytes.
+ * The caller is requesting that NELMTS elements are copied.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *_buf)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */
+ const uint8 *buf=(const uint8 *)_buf; /* Alias for pointer arithmetic */
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*space dimensionality */
+ intn i; /*counters */
+
+ FUNC_ENTER (H5S_all_fscat, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (buf);
+
+ /*
+ * Get information to determine what elements are being selected.
+ */
+ if ((space_ndims=H5S_get_dims (file_space, hsize, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to retrieve hyperslab parameters");
+ }
+ HDmemset(file_offset,0,sizeof(hssize_t)*space_ndims);
+
+ /* Adjust the slowest varying dimension to account for strip mining */
+ for (i=1, acc=1; i<space_ndims; i++)
+ acc *= hsize[i];
+ assert (0==file_iter->all.offset % acc);
+ assert (0==nelmts % acc);
+ file_offset[0] += file_iter->all.offset / acc;
+ hsize[0] = nelmts / acc;
+
+ /* The fastest varying dimension is for the data point itself */
+ file_offset[space_ndims] = 0;
+ hsize[space_ndims] = elmt_size;
+ HDmemset (zero, 0, layout->ndims*sizeof(*zero));
+
+ /*
+ * Scatter to file.
+ */
+ if (H5F_arr_write (f, layout, comp, efl, hsize, hsize, zero,
+ file_offset, xfer_mode, buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
+ }
+
+ /* Advance iterator */
+ file_iter->all.elmt_left--;
+ file_iter->all.offset+=nelmts;
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_all_fscat() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_mgath
+ *
+ * Purpose: Gathers dataset elements from application memory BUF and
+ * copies them into the data type conversion buffer TCONV_BUF.
+ * Each element is ELMT_SIZE bytes and arranged in application
+ * memory according to MEM_SPACE.
+ * The caller is requesting that at most NELMTS be gathered.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_all_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/)
+{
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ const uint8 *buf=(const uint8 *)_buf; /* Get local copies for address arithmetic */
+ uint8 *tconv_buf=(uint8 *)_tconv_buf;
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*dimensionality of space*/
+ intn i; /*counters */
+
+ FUNC_ENTER (H5S_all_mgath, 0);
+
+ /* Check args */
+ assert (buf);
+ assert (elmt_size>0);
+ assert (mem_space && H5S_SEL_ALL==mem_space->select.type);
+ assert (mem_iter);
+ assert (nelmts>0);
+ assert (tconv_buf);
+
+ /*
+ * Retrieve information to determine what elements are being selected.
+ */
+ if ((space_ndims=H5S_get_dims (mem_space, hsize, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
+ "unable to retrieve hyperslab parameters");
+ }
+ HDmemset(mem_offset,0,sizeof(hssize_t)*space_ndims);
+
+ if (H5S_get_dims (mem_space, mem_size, NULL)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
+ "unable to retrieve data space dimensions");
+ }
+
+ /* Adjust the slowest varying dimension to account for strip mining */
+ for (i=1, acc=1; i<space_ndims; i++)
+ acc *= hsize[i];
+ assert (0==mem_iter->all.offset % acc);
+ assert (0==nelmts % acc);
+ mem_offset[0] += mem_iter->all.offset / acc;
+ hsize[0] = nelmts / acc;
+
+ /* The fastest varying dimension is for the data point itself */
+ mem_offset[space_ndims] = 0;
+ mem_size[space_ndims] = elmt_size;
+ hsize[space_ndims] = elmt_size;
+ HDmemset (zero, 0, (space_ndims+1)*sizeof(*zero));
+
+ /*
+ * Scatter from conversion buffer to application memory.
+ */
+ if (H5V_hyper_copy (space_ndims+1, hsize, hsize, zero, tconv_buf,
+ mem_size, mem_offset, buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
+ "unable to scatter data to memory");
+ }
+
+ /* Advance iterator */
+ mem_iter->all.elmt_left--;
+ mem_iter->all.offset+=nelmts;
+
+ FUNC_LEAVE (nelmts);
+} /* H5S_all_mgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_mscat
+ *
+ * Purpose: Scatters NELMTS data points from the type conversion buffer
+ * TCONV_BUF to the application buffer BUF. Each element is
+ * ELMT_SIZE bytes and they are organized in application memory
+ * according to MEM_SPACE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 17, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_all_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/)
+{
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ uint8 *buf=(uint8 *)_buf; /* Get local copies for address arithmetic */
+ const uint8 *tconv_buf=(const uint8 *)_tconv_buf;
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*dimensionality of space*/
+ intn i; /*counters */
+
+ FUNC_ENTER (H5S_all_mscat, FAIL);
+
+ /* Check args */
+ assert (tconv_buf);
+ assert (elmt_size>0);
+ assert (mem_space && H5S_SEL_ALL==mem_space->select.type);
+ assert (mem_iter);
+ assert (nelmts>0);
+ assert (buf);
+
+ /*
+ * Retrieve information to determine what elements are being selected.
+ */
+ if ((space_ndims=H5S_get_dims (mem_space, hsize, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to retrieve hyperslab parameters");
+ }
+ HDmemset(mem_offset,0,sizeof(hssize_t)*space_ndims);
+
+ if (H5S_get_dims (mem_space, mem_size, NULL)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to retrieve data space dimensions");
+ }
+
+ /* Adjust the slowest varying dimension to take care of strip mining */
+ for (i=1, acc=1; i<space_ndims; i++)
+ acc *= hsize[i];
+ assert (0==mem_iter->all.offset % acc);
+ assert (0==nelmts % acc);
+ mem_offset[0] += mem_iter->all.offset / acc;
+ hsize[0] = nelmts / acc;
+
+ /* The fastest varying dimension is for the data point itself */
+ mem_offset[space_ndims] = 0;
+ mem_size[space_ndims] = elmt_size;
+ hsize[space_ndims] = elmt_size;
+ HDmemset (zero, 0, (space_ndims+1)*sizeof(*zero));
+
+ /*
+ * Scatter from conversion buffer to application memory.
+ */
+ if (H5V_hyper_copy (space_ndims+1, hsize, mem_size, mem_offset, buf,
+ hsize, zero, tconv_buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to scatter data to memory");
+ }
+
+ /* Advance iterator */
+ mem_iter->all.elmt_left--;
+ mem_iter->all.offset+=nelmts;
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_all_mscat() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_all_release
+ PURPOSE
+ Release all selection information for a dataspace
+ USAGE
+ herr_t H5S_all_release(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Releases "all" selection information for a dataspace
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_all_release (H5S_t *space)
+{
+ FUNC_ENTER (H5S_all_release, FAIL);
+
+ /* Check args */
+ assert (space);
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_all_release() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_all_npoints
+ PURPOSE
+ Compute number of elements in current selection
+ USAGE
+ hsize_t H5S_all_npoints(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Compute number of elements in current selection. For "all" selections,
+ this is the same as the number of points in the extent.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t
+H5S_all_npoints (H5S_t *space)
+{
+ intn i; /* Counters */
+ hsize_t ret_value;
+
+ FUNC_ENTER (H5S_all_npoints, 0);
+
+ /* Check args */
+ assert (space);
+
+ for(i=0, ret_value=1; i<space->extent.u.simple.rank; i++)
+ ret_value*=space->extent.u.simple.size[i];
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_all_npoints() */
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
new file mode 100644
index 0000000..e1d3109
--- /dev/null
+++ b/src/H5Shyper.c
@@ -0,0 +1,1395 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Thursday, June 18, 1998
+ *
+ * Purpose: Hyperslab selection data space I/O functions.
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Sprivate.h>
+#include <H5Vprivate.h>
+#include <H5MMprivate.h>
+
+/* Interface initialization */
+#define PABLO_MASK H5S_hyper_mask
+#define INTERFACE_INIT NULL
+static intn interface_initialize_g = FALSE;
+
+/* Local datatypes */
+/* Parameter block for H5S_hyper_fread & H5S_hyper_fwrite */
+typedef struct {
+ H5F_t *f;
+ const struct H5O_layout_t *layout;
+ const struct H5O_compress_t *comp;
+ const struct H5O_efl_t *efl;
+ size_t elmt_size;
+ const H5S_t *space;
+ H5S_sel_iter_t *iter;
+ size_t nelmts;
+ H5D_transfer_t xfer_mode;
+ void *_buf;
+ void *tconv_buf;
+ H5S_hyper_bound_t **lo_bounds;
+ H5S_hyper_bound_t **hi_bounds;
+} H5S_hyper_fhyper_info_t;
+
+/* Static function prototypes */
+static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr, size_t count);
+static H5S_hyper_region_t *H5S_hyper_get_regions (size_t *num_regions, intn dim,
+ size_t bound_count, H5S_hyper_bound_t **lo_bounds,
+ H5S_hyper_bound_t **hi_bounds, hssize_t *pos);
+static size_t H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info);
+static size_t H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_init
+ *
+ * Purpose: Initializes iteration information for hyperslab selection.
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_hyper_init (const struct H5O_layout_t __unused__ *layout,
+ const H5S_t *space, H5S_sel_iter_t *sel_iter)
+{
+ FUNC_ENTER (H5S_hyper_init, FAIL);
+
+ /* Check args */
+ assert (layout);
+ assert (space && H5S_SEL_HYPERSLABS==space->select.type);
+ assert (sel_iter);
+
+ /* Initialize the number of points to iterate over */
+ sel_iter->hyp.elmt_left=space->select.num_elem;
+
+ /* Start at the origin of the array */
+ sel_iter->hyp.pos = H5MM_calloc(space->extent.u.simple.rank*sizeof(hssize_t));
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_init() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_favail
+ *
+ * Purpose: Figure out the optimal number of elements to transfer to/from the file
+ *
+ * Return: non-negative number of elements on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_hyper_favail (const H5S_t __unused__ *space, const H5S_sel_iter_t *sel_iter, size_t max)
+{
+ FUNC_ENTER (H5S_hyper_favail, FAIL);
+
+ /* Check args */
+ assert (space && H5S_SEL_HYPERSLABS==space->select.type);
+ assert (sel_iter);
+
+ FUNC_LEAVE (MIN(sel_iter->hyp.elmt_left,max));
+} /* H5S_hyper_favail() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_get_regions
+ *
+ * Purpose: Builds a sorted array of the overlaps in a dimension
+ *
+ * Return: Success: Pointer to valid array (num_regions parameter set to
+ * array size)
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Monday, June 29, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5S_hyper_region_t *
+H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
+ H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos)
+{
+ H5S_hyper_region_t *ret_value=NULL; /* Pointer to array to return */
+ size_t num_reg=0, /* Number of regions in array */
+ curr_reg=0; /* The current region we are working with */
+ intn next_dim, /* Next fastest dimension */
+ temp_dim; /* Temporary dim. holder */
+ size_t i; /* Counters */
+
+ FUNC_ENTER (H5S_hyper_get_regions, NULL);
+
+ assert(num_regions);
+ assert(lo_bounds);
+ assert(hi_bounds);
+ assert(pos);
+
+#ifdef QAK
+printf("%s: check 1.0, dim=%d\n",FUNC,dim);
+#endif /* QAK */
+
+ /* Check if we need to generate a list of regions for the 0th dim. */
+ if(dim<0) {
+#ifdef QAK
+printf("%s: check 1.1, bound_count=%d\n",FUNC,bound_count);
+#endif /* QAK */
+ for(i=0; i<bound_count; i++) {
+ /* Check if we've allocated the array yet */
+ if(num_reg==0) {
+ /* Allocate array */
+ ret_value=H5MM_malloc(sizeof(H5S_hyper_node_t));
+
+ /* Initialize with first region */
+ ret_value[0].start=lo_bounds[0][i].bound;
+ ret_value[0].end=hi_bounds[0][i].bound;
+
+ /* Increment the number of regions */
+ num_reg++;
+ } else {
+ /* Check if we should merge this region into the current region */
+ if(lo_bounds[0][i].bound<ret_value[curr_reg].end)
+ ret_value[curr_reg].end=MAX(hi_bounds[0][i].bound,ret_value[curr_reg].end);
+ else { /* no overlap with previous region, add new region */
+ /* Enlarge array */
+ ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_node_t)*(num_reg+1));
+
+ /* Initialize with new region */
+ ret_value[num_reg].start=lo_bounds[0][i].bound;
+ ret_value[num_reg].end=hi_bounds[0][i].bound;
+
+ /* Increment the number of regions & the current region */
+ num_reg++;
+ curr_reg++;
+ } /* end else */
+ } /* end else */
+ } /* end for */
+ } else { /* Generate list of regions based on the current position */
+#ifdef QAK
+printf("%s: check 2.0, bound_count=%d\n",FUNC,bound_count);
+#endif /* QAK */
+ next_dim=dim+1;
+ for(i=0; i<bound_count; i++) {
+
+ /* Check if each boundary overlaps in the higher dimensions */
+ temp_dim=dim;
+ while(temp_dim>=0 && pos[temp_dim]>=lo_bounds[temp_dim][i].bound &&
+ pos[temp_dim]<=hi_bounds[temp_dim][i].bound)
+ temp_dim--;
+
+ /* Yes, all previous positions match, this is a valid region */
+ if(temp_dim<0) {
+ /* Check if we've allocated the array yet */
+ if(num_reg==0) {
+ /* Allocate array */
+ ret_value=H5MM_malloc(sizeof(H5S_hyper_node_t));
+
+ /* Initialize with first region */
+ ret_value[0].start=lo_bounds[next_dim][i].bound;
+ ret_value[0].end=hi_bounds[next_dim][i].bound;
+
+ /* Increment the number of regions */
+ num_reg++;
+ } else {
+ /* Check if we should merge this region into the current region */
+ if(lo_bounds[next_dim][i].bound<ret_value[curr_reg].end)
+ ret_value[curr_reg].end=MAX(hi_bounds[next_dim][i].bound,ret_value[curr_reg].end);
+ else { /* no overlap with previous region, add new region */
+ /* Enlarge array */
+ ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_node_t)*(num_reg+1));
+
+ /* Initialize with new region */
+ ret_value[num_reg].start=lo_bounds[next_dim][i].bound;
+ ret_value[num_reg].end=hi_bounds[next_dim][i].bound;
+
+ /* Increment the number of regions & the current region */
+ num_reg++;
+ curr_reg++;
+ } /* end else */
+ } /* end else */
+ } /* end if */
+ } /* end for */
+ } /* end else */
+
+ /* Save the number of regions we generated */
+ *num_regions=num_reg;
+
+#ifdef QAK
+printf("%s: check 10.0, ret_value=%p, num_reg=%d\n",FUNC,ret_value,num_reg);
+#endif /* QAK */
+
+ FUNC_LEAVE (ret_value);
+} /* end H5S_hyper_get_regions() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_fread
+ *
+ * Purpose: Recursively gathers data points from a file using the parameters
+ * passed to H5S_hyper_fgath.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
+ size_t num_regions; /* number of regions overlapped */
+ size_t i; /* Counters */
+ intn j;
+ size_t num_read=0; /* Number of elements read */
+
+ FUNC_ENTER (H5S_hyper_fread, 0);
+
+ assert(fhyper_info);
+
+#ifdef QAK
+printf("%s: check 1.0, dim=%d\n",FUNC,dim);
+#endif /* QAK */
+
+ /* Get a sorted list (in the next dimension down) of the regions which */
+ /* overlap the current index in this dim */
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ fhyper_info->space->select.sel_info.hyper_lst->count,
+ fhyper_info->lo_bounds, fhyper_info->hi_bounds,
+ fhyper_info->iter->hyp.pos))!=NULL) {
+
+ /* Check if this is the second to last dimension in dataset */
+ /* (Which means that we've got a list of the regions in the fastest */
+ /* changing dimension and should input those regions) */
+#ifdef QAK
+printf("%s: check 2.0, rank=%d\n",FUNC,(int)fhyper_info->space->extent.u.simple.rank);
+for(i=0; i<num_regions; i++)
+ printf("%s: check 2.1, region #%d: start=%d, end=%d\n",FUNC,i,(int)regions[i].start,(int)regions[i].end);
+#endif /* QAK */
+ if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+
+ /* Set up hyperslab I/O parameters which apply to all regions */
+
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset,fhyper_info->iter->hyp.pos,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Set the memory offset to the origin */
+ HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero));
+
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions; i++) {
+#ifdef QAK
+printf("%s: check 2.1, i=%d\n",FUNC,(int)i);
+#endif /* QAK */
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1;
+ file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /*
+ * Gather from file.
+ */
+ if (H5F_arr_read (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->comp, fhyper_info->efl, hsize, hsize, zero,
+ file_offset, fhyper_info->xfer_mode,
+ fhyper_info->_buf/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
+ }
+#ifdef QAK
+printf("%s: check 2.2\n",FUNC);
+#endif /* QAK */
+
+ /* Advance the pointer in the buffer */
+ fhyper_info->_buf=((uint8 *)fhyper_info->_buf)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size;
+
+ /* Increment the number of elements read */
+ num_read+=(regions[i].end-regions[i].start)+1;
+
+ /* Decrement the iterator count */
+ fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1;
+ } /* end for */
+ } else { /* recurse on each region to next dimension down */
+#ifdef QAK
+printf("%s: check 3.0, num_regions=%d\n",FUNC,(int)num_regions);
+#endif /* QAK */
+
+ /* Increment the dimension we are working with */
+ dim++;
+
+ /* Step through each region in this dimension */
+ for(i=0; i<num_regions; i++) {
+ /* Step through each location in each region */
+ for(j=regions[i].start; j<=regions[i].end; j++) {
+#ifdef QAK
+printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j);
+#endif /* QAK */
+
+ /* Set the correct position we are working on */
+ fhyper_info->iter->hyp.pos[dim]=j;
+
+ /* Go get the regions in the next lower dimension */
+ num_read+=H5S_hyper_fread(dim, fhyper_info);
+ } /* end for */
+ } /* end for */
+ } /* end else */
+
+ /* Free the region space */
+ H5MM_xfree(regions);
+ } /* end if */
+
+ FUNC_LEAVE (num_read);
+} /* H5S_hyper_fread() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_fgath
+ *
+ * Purpose: Gathers data points from file F and accumulates them in the
+ * type conversion buffer BUF. The LAYOUT argument describes
+ * how the data is stored on disk and EFL describes how the data
+ * is organized in external files. ELMT_SIZE is the size in
+ * bytes of a datum which this function treats as opaque.
+ * FILE_SPACE describes the data space of the dataset on disk
+ * and the elements that have been selected for reading (via
+ * hyperslab, etc). This function will copy at most NELMTS elements.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *_buf/*out*/)
+{
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ intn i; /*counters */
+ size_t num_read; /* number of elements read into buffer */
+
+ FUNC_ENTER (H5S_hyper_fgath, 0);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (_buf);
+
+#ifdef QAK
+printf("%s: check 1.0\n", FUNC);
+#endif /* QAK */
+ /* Allocate space for the low & high bound arrays */
+ lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+
+ /* Initialize to correct order to walk through arrays.
+ (When another iteration order besides the default 'C' order is chosen,
+ this is the correct place to change the order of the array iterations)
+ */
+ for(i=0; i<file_space->extent.u.simple.rank; i++) {
+ lo_bounds[i]=file_space->select.sel_info.hyper_lst->lo_bounds[i];
+ hi_bounds[i]=file_space->select.sel_info.hyper_lst->hi_bounds[i];
+ } /* end for */
+
+ /* Initialize parameter block for recursive calls */
+ fhyper_info.f=f;
+ fhyper_info.layout=layout;
+ fhyper_info.comp=comp;
+ fhyper_info.efl=efl;
+ fhyper_info.elmt_size=elmt_size;
+ fhyper_info.space=file_space;
+ fhyper_info.iter=file_iter;
+ fhyper_info.nelmts=nelmts;
+ fhyper_info.xfer_mode=xfer_mode;
+ fhyper_info._buf=_buf;
+ fhyper_info.lo_bounds=lo_bounds;
+ fhyper_info.hi_bounds=hi_bounds;
+
+ /* Recursively input the hyperslabs currently defined */
+ /* starting with the slowest changing dimension */
+#ifdef QAK
+printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+ num_read=H5S_hyper_fread(-1,&fhyper_info);
+#ifdef QAK
+printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read);
+#endif /* QAK */
+
+ /* Release the memory we allocated */
+ H5MM_xfree(lo_bounds);
+ H5MM_xfree(hi_bounds);
+
+ FUNC_LEAVE (num_read);
+} /* H5S_hyper_fgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_fwrite
+ *
+ * Purpose: Recursively scatters data points to a file using the parameters
+ * passed to H5S_hyper_fscat.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
+ size_t num_regions; /* number of regions overlapped */
+ size_t i; /* Counters */
+ intn j;
+ size_t num_written=0; /* Number of elements read */
+
+ FUNC_ENTER (H5S_hyper_fwrite, 0);
+
+ assert(fhyper_info);
+
+ /* Get a sorted list (in the next dimension down) of the regions which */
+ /* overlap the current index in this dim */
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ fhyper_info->space->select.sel_info.hyper_lst->count,
+ fhyper_info->lo_bounds, fhyper_info->hi_bounds,
+ fhyper_info->iter->hyp.pos))!=NULL) {
+
+ /* Check if this is the second to last dimension in dataset */
+ /* (Which means that we've got a list of the regions in the fastest */
+ /* changing dimension and should input those regions) */
+ if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+
+ /* Set up hyperslab I/O parameters which apply to all regions */
+
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset,fhyper_info->iter->hyp.pos,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Set the memory offset to the origin */
+ HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero));
+
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions; i++) {
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1;
+ file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /*
+ * Scatter from file.
+ */
+ if (H5F_arr_write (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->comp, fhyper_info->efl, hsize, hsize, zero,
+ file_offset, fhyper_info->xfer_mode,
+ fhyper_info->_buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
+ }
+
+ /* Advance the pointer in the buffer */
+ fhyper_info->_buf=((uint8 *)fhyper_info->_buf)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size;
+
+ /* Increment the number of elements read */
+ num_written+=(regions[i].end-regions[i].start)+1;
+
+ /* Decrement the iterator count */
+ fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1;
+ } /* end for */
+ } else { /* recurse on each region to next dimension down */
+
+ /* Increment the dimension we are working with */
+ dim++;
+
+ /* Step through each region in this dimension */
+ for(i=0; i<num_regions; i++) {
+ /* Step through each location in each region */
+ for(j=regions[i].start; j<=regions[i].end; j++) {
+
+ /* Set the correct position we are working on */
+ fhyper_info->iter->hyp.pos[dim]=j;
+
+ /* Go get the regions in the next lower dimension */
+ num_written+=H5S_hyper_fwrite(dim, fhyper_info);
+ } /* end for */
+ } /* end for */
+ } /* end else */
+
+ /* Free the region space */
+ H5MM_xfree(regions);
+ } /* end if */
+
+ FUNC_LEAVE (num_written);
+} /* H5S_hyper_fwrite() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_fscat
+ *
+ * Purpose: Scatters dataset elements from the type conversion buffer BUF
+ * to the file F where the data points are arranged according to
+ * the file data space FILE_SPACE and stored according to
+ * LAYOUT and EFL. Each element is ELMT_SIZE bytes.
+ * The caller is requesting that NELMTS elements are copied.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *_buf)
+{
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ intn i; /*counters */
+ size_t num_written; /* number of elements read into buffer */
+
+ FUNC_ENTER (H5S_hyper_fscat, 0);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (_buf);
+
+#ifdef QAK
+printf("%s: check 1.0\n", FUNC);
+#endif /* QAK */
+ /* Allocate space for the low & high bound arrays */
+ lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+
+ /* Initialize to correct order to walk through arrays.
+ (When another iteration order besides the default 'C' order is chosen,
+ this is the correct place to change the order of the array iterations)
+ */
+ for(i=0; i<file_space->extent.u.simple.rank; i++) {
+ lo_bounds[i]=file_space->select.sel_info.hyper_lst->lo_bounds[i];
+ hi_bounds[i]=file_space->select.sel_info.hyper_lst->hi_bounds[i];
+ } /* end for */
+
+ /* Initialize parameter block for recursive calls */
+ fhyper_info.f=f;
+ fhyper_info.layout=layout;
+ fhyper_info.comp=comp;
+ fhyper_info.efl=efl;
+ fhyper_info.elmt_size=elmt_size;
+ fhyper_info.space=file_space;
+ fhyper_info.iter=file_iter;
+ fhyper_info.nelmts=nelmts;
+ fhyper_info.xfer_mode=xfer_mode;
+ fhyper_info._buf=_buf;
+ fhyper_info.lo_bounds=lo_bounds;
+ fhyper_info.hi_bounds=hi_bounds;
+
+ /* Recursively input the hyperslabs currently defined */
+ /* starting with the slowest changing dimension */
+ num_written=H5S_hyper_fwrite(-1,&fhyper_info);
+
+ /* Release the memory we allocated */
+ H5MM_xfree(lo_bounds);
+ H5MM_xfree(hi_bounds);
+
+ FUNC_LEAVE (num_written);
+} /* H5S_hyper_fscat() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_mread
+ *
+ * Purpose: Recursively gathers data points from memory using the parameters
+ * passed to H5S_hyper_mgath.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+{
+ hssize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in memory*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
+ size_t num_regions; /* number of regions overlapped */
+ size_t i; /* Counters */
+ intn j;
+ size_t num_read=0; /* Number of elements read */
+
+ FUNC_ENTER (H5S_hyper_mread, 0);
+
+ assert(fhyper_info);
+
+#ifdef QAK
+printf("%s: check 1.0, dim=%d\n",FUNC,dim);
+#endif /* QAK */
+
+ /* Get a sorted list (in the next dimension down) of the regions which */
+ /* overlap the current index in this dim */
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ fhyper_info->space->select.sel_info.hyper_lst->count,
+ fhyper_info->lo_bounds, fhyper_info->hi_bounds,
+ fhyper_info->iter->hyp.pos))!=NULL) {
+
+ /* Check if this is the second to last dimension in dataset */
+ /* (Which means that we've got a list of the regions in the fastest */
+ /* changing dimension and should input those regions) */
+#ifdef QAK
+printf("%s: check 2.0, rank=%d\n",FUNC,(int)fhyper_info->space->extent.u.simple.rank);
+for(i=0; i<num_regions; i++)
+ printf("%s: check 2.1, region #%d: start=%d, end=%d\n",FUNC,i,(int)regions[i].start,(int)regions[i].end);
+#endif /* QAK */
+
+ if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+
+ /* Set up hyperslab I/O parameters which apply to all regions */
+
+ /* Set up the size of the memory space */
+ HDmemcpy(mem_size,fhyper_info->space->extent.u.simple.size,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Copy the location of the region in the file */
+ HDmemcpy(mem_offset,fhyper_info->iter->hyp.pos,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ mem_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Set the memory offset to the origin */
+ HDmemset (zero, 0, (fhyper_info->space->extent.u.simple.rank+1)*sizeof(*zero));
+
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions; i++) {
+#ifdef QAK
+printf("%s: check 2.1, i=%d\n",FUNC,(int)i);
+#endif /* QAK */
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1;
+ mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /*
+ * Gather from memory.
+ */
+ if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1,
+ hsize, hsize, zero, fhyper_info->tconv_buf,
+ mem_size, mem_offset, fhyper_info->_buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory");
+ }
+
+ /* Advance the pointer in the buffer */
+ fhyper_info->tconv_buf=((uint8 *)fhyper_info->tconv_buf)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size;
+
+ /* Increment the number of elements read */
+ num_read+=(regions[i].end-regions[i].start)+1;
+
+ /* Decrement the iterator count */
+ fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1;
+ } /* end for */
+ } else { /* recurse on each region to next dimension down */
+#ifdef QAK
+printf("%s: check 3.0, num_regions=%d\n",FUNC,(int)num_regions);
+#endif /* QAK */
+
+ /* Increment the dimension we are working with */
+ dim++;
+
+ /* Step through each region in this dimension */
+ for(i=0; i<num_regions; i++) {
+ /* Step through each location in each region */
+ for(j=regions[i].start; j<=regions[i].end; j++) {
+#ifdef QAK
+printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j);
+#endif /* QAK */
+
+ /* Set the correct position we are working on */
+ fhyper_info->iter->hyp.pos[dim]=j;
+
+ /* Go get the regions in the next lower dimension */
+ num_read+=H5S_hyper_mread(dim, fhyper_info);
+ } /* end for */
+ } /* end for */
+ } /* end else */
+
+ /* Free the region space */
+ H5MM_xfree(regions);
+ } /* end if */
+
+ FUNC_LEAVE (num_read);
+} /* H5S_hyper_mread() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_mgath
+ *
+ * Purpose: Gathers dataset elements from application memory BUF and
+ * copies them into the data type conversion buffer TCONV_BUF.
+ * Each element is ELMT_SIZE bytes and arranged in application
+ * memory according to MEM_SPACE.
+ * The caller is requesting that at most NELMTS be gathered.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_hyper_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/)
+{
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ intn i,j; /* Counters */
+ size_t num_read; /* number of elements read into buffer */
+
+ FUNC_ENTER (H5S_hyper_mgath, 0);
+
+#ifdef QAK
+printf("%s: check 1.0, elmt_size=%d, mem_space=%p\n",FUNC,(int)elmt_size,mem_space);
+printf("%s: check 1.0, mem_iter=%p, nelmts=%d\n",FUNC,mem_iter,nelmts);
+printf("%s: check 1.0, _buf=%p, _tconv_buf=%p\n",FUNC,_buf,_tconv_buf);
+#endif /* QAK */
+
+ /* Check args */
+ assert (elmt_size>0);
+ assert (mem_space);
+ assert (mem_iter);
+ assert (nelmts>0);
+ assert (_buf);
+ assert (_tconv_buf);
+
+#ifdef QAK
+printf("%s: check 2.0, mem_space->extent.u.simple.rank=%d\n",FUNC, (int)mem_space->extent.u.simple.rank);
+#endif /* QAK */
+
+ /* Allocate space for the low & high bound arrays */
+ lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+
+ /* Initialize to correct order to walk through arrays.
+ (When another iteration order besides the default 'C' order is chosen,
+ this is the correct place to change the order of the array iterations)
+ */
+#ifdef QAK
+printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
+ for(i=0; i<mem_space->extent.u.simple.rank; i++) {
+ lo_bounds[i]=mem_space->select.sel_info.hyper_lst->lo_bounds[i];
+ hi_bounds[i]=mem_space->select.sel_info.hyper_lst->hi_bounds[i];
+#ifdef QAK
+printf("%s: check 3.1, lo[%d]=%p, hi[%d]=%p\n",FUNC,i,lo_bounds[i],i,hi_bounds[i]);
+ for(j=0; j<mem_space->select.sel_info.hyper_lst->count; j++)
+printf("%s: check 3.2, lo[%d][%d]=%d, hi[%d][%d]=%d\n",FUNC,i,j,(int)lo_bounds[i][j].bound,i,j,(int)hi_bounds[i][j].bound);
+#endif /* QAK */
+ } /* end for */
+
+ /* Initialize parameter block for recursive calls */
+ fhyper_info.elmt_size=elmt_size;
+ fhyper_info.space=mem_space;
+ fhyper_info.iter=mem_iter;
+ fhyper_info.nelmts=nelmts;
+ fhyper_info._buf=_buf;
+ fhyper_info.tconv_buf=_tconv_buf;
+ fhyper_info.lo_bounds=lo_bounds;
+ fhyper_info.hi_bounds=hi_bounds;
+
+ /* Recursively input the hyperslabs currently defined */
+ /* starting with the slowest changing dimension */
+#ifdef QAK
+printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+ num_read=H5S_hyper_mread(-1,&fhyper_info);
+#ifdef QAK
+printf("%s: check 5.0\n",FUNC);
+#endif /* QAK */
+
+ /* Release the memory we allocated */
+ H5MM_xfree(lo_bounds);
+ H5MM_xfree(hi_bounds);
+
+ FUNC_LEAVE (num_read);
+} /* H5S_hyper_mgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_mwrite
+ *
+ * Purpose: Recursively scatters data points from memory using the parameters
+ * passed to H5S_hyper_mscat.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+{
+ hssize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
+ size_t num_regions; /* number of regions overlapped */
+ size_t i; /* Counters */
+ intn j;
+ size_t num_read=0; /* Number of elements read */
+
+ FUNC_ENTER (H5S_hyper_mwrite, 0);
+
+ assert(fhyper_info);
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+
+ /* Get a sorted list (in the next dimension down) of the regions which */
+ /* overlap the current index in this dim */
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ fhyper_info->space->select.sel_info.hyper_lst->count,
+ fhyper_info->lo_bounds, fhyper_info->hi_bounds,
+ fhyper_info->iter->hyp.pos))!=NULL) {
+
+#ifdef QAK
+printf("%s: check 2.0, rank=%d\n",FUNC,(int)fhyper_info->space->extent.u.simple.rank);
+for(i=0; i<num_regions; i++)
+ printf("%s: check 2.1, region #%d: start=%d, end=%d\n",FUNC,i,(int)regions[i].start,(int)regions[i].end);
+#endif /* QAK */
+ /* Check if this is the second to last dimension in dataset */
+ /* (Which means that we've got a list of the regions in the fastest */
+ /* changing dimension and should input those regions) */
+ if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+
+ /* Set up hyperslab I/O parameters which apply to all regions */
+
+ /* Set up the size of the memory space */
+ HDmemcpy(mem_size,fhyper_info->space->extent.u.simple.size,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Copy the location of the region in the file */
+ HDmemcpy(mem_offset,fhyper_info->iter->hyp.pos,fhyper_info->space->extent.u.simple.rank*sizeof(hssize_t));
+ mem_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Set the memory offset to the origin */
+ HDmemset (zero, 0, (fhyper_info->space->extent.u.simple.rank+1)*sizeof(*zero));
+
+#ifdef QAK
+printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions; i++) {
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1;
+ mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /*
+ * Gather from memory.
+ */
+ if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1,
+ hsize, mem_size, mem_offset, fhyper_info->_buf,
+ hsize, zero, fhyper_info->tconv_buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory");
+ }
+
+ /* Advance the pointer in the buffer */
+ fhyper_info->tconv_buf=((uint8 *)fhyper_info->tconv_buf)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size;
+
+ /* Increment the number of elements read */
+ num_read+=(regions[i].end-regions[i].start)+1;
+
+ /* Decrement the iterator count */
+ fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1;
+ } /* end for */
+ } else { /* recurse on each region to next dimension down */
+
+ /* Increment the dimension we are working with */
+ dim++;
+
+ /* Step through each region in this dimension */
+ for(i=0; i<num_regions; i++) {
+ /* Step through each location in each region */
+ for(j=regions[i].start; j<=regions[i].end; j++) {
+
+ /* Set the correct position we are working on */
+ fhyper_info->iter->hyp.pos[dim]=j;
+
+ /* Go get the regions in the next lower dimension */
+ num_read+=H5S_hyper_mwrite(dim, fhyper_info);
+ } /* end for */
+ } /* end for */
+ } /* end else */
+
+ /* Free the region space */
+ H5MM_xfree(regions);
+ } /* end if */
+
+ FUNC_LEAVE (num_read);
+} /* H5S_hyper_mwrite() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_mscat
+ *
+ * Purpose: Scatters NELMTS data points from the type conversion buffer
+ * TCONV_BUF to the application buffer BUF. Each element is
+ * ELMT_SIZE bytes and they are organized in application memory
+ * according to MEM_SPACE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 17, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/)
+{
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ intn i; /*counters */
+ size_t num_read; /* number of elements read into buffer */
+
+ FUNC_ENTER (H5S_hyper_mscat, 0);
+
+ /* Check args */
+ assert (elmt_size>0);
+ assert (mem_space);
+ assert (mem_iter);
+ assert (nelmts>0);
+ assert (_buf);
+ assert (_tconv_buf);
+
+ /* Allocate space for the low & high bound arrays */
+ lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+
+ /* Initialize to correct order to walk through arrays.
+ (When another iteration order besides the default 'C' order is chosen,
+ this is the correct place to change the order of the array iterations)
+ */
+ for(i=0; i<mem_space->extent.u.simple.rank; i++) {
+ lo_bounds[i]=mem_space->select.sel_info.hyper_lst->lo_bounds[i];
+ hi_bounds[i]=mem_space->select.sel_info.hyper_lst->hi_bounds[i];
+ } /* end for */
+
+ /* Initialize parameter block for recursive calls */
+ fhyper_info.elmt_size=elmt_size;
+ fhyper_info.space=mem_space;
+ fhyper_info.iter=mem_iter;
+ fhyper_info.nelmts=nelmts;
+ fhyper_info._buf=_buf;
+ fhyper_info.tconv_buf=_tconv_buf;
+ fhyper_info.lo_bounds=lo_bounds;
+ fhyper_info.hi_bounds=hi_bounds;
+
+ /* Recursively input the hyperslabs currently defined */
+ /* starting with the slowest changing dimension */
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+ num_read=H5S_hyper_mwrite(-1,&fhyper_info);
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
+
+ /* Release the memory we allocated */
+ H5MM_xfree(lo_bounds);
+ H5MM_xfree(hi_bounds);
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_mscat() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_bsearch
+ PURPOSE
+ Search for a boundary
+ USAGE
+ herr_t H5S_hyper_bsearch(key,barr,count)
+ hssize_t size; IN: Key we are searching for
+ H5S_hyper_bount_t *barr; IN: Pointer to the array of bounds
+ size_t count; IN: Number of elements in the bound array
+ RETURNS
+ The element number to insert in front of on success (the value in the 'count'
+ parameter if the new bound should be added to end) or negative on failure.
+ DESCRIPTION
+ Finds the proper place to insert a boundary in a sorted boundary array.
+ Uses a binary search algorithm for the actual searching.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr, size_t count)
+{
+ intn lo, mid, hi; /* Indices for the search */
+ intn ret_value=-1; /* Return value index */
+
+ FUNC_ENTER (H5S_hyper_bsearch, FAIL);
+
+ assert(barr);
+ assert(count>0);
+
+ /* Check bounds first */
+ if(size<barr[0].bound)
+ ret_value=0;
+ else if(size>barr[count-1].bound)
+ ret_value=count;
+ else { /* must be in the middle somewhere, go get it */
+ lo=0;
+ hi=count-1;
+ do {
+ /* Calc. the mid-point */
+ mid=(hi+lo)/2;
+
+ /* check for bounds only seperated by one element */
+ if((hi-lo)<=1) {
+ ret_value=hi;
+ break;
+ } else { /* Divide and conquer! */
+ if(size>barr[mid].bound)
+ lo=mid;
+ else
+ hi=mid;
+ } /* end else */
+ } while(lo!=hi);
+ } /* end else */
+ FUNC_LEAVE (ret_value);
+} /* H5S_hyper_bsearch() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_add
+ PURPOSE
+ Add a block to hyperslab selection
+ USAGE
+ herr_t H5S_hyper_add(space, start, size)
+ H5S_t *space; IN: Pointer to dataspace
+ hssize_t *start; IN: Offset of block
+ hssize_t *size; IN: Size of block
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Adds a block to an existing hyperslab selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_add (H5S_t *space, hssize_t *start, hssize_t *size)
+{
+ H5S_hyper_node_t *slab; /* New hyperslab node to insert */
+ H5S_hyper_bound_t *tmp; /* Temporary pointer to an hyperslab bound array */
+ intn bound_loc; /* Boundary location to insert hyperslab */
+ size_t elem_count; /* Number of elements in hyperslab selection */
+ intn i; /* Counters */
+ herr_t ret_value=FAIL;
+extern int qak_debug;
+
+ FUNC_ENTER (H5S_hyper_add, FAIL);
+
+ /* Check args */
+ assert (space);
+ assert (start);
+ assert (size);
+
+qak_debug=1;
+
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+ /* Create new hyperslab node to insert */
+ if((slab = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab node");
+ if((slab->start = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab start boundary");
+ if((slab->end = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab end boundary");
+
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
+ /* Set boundary on new node */
+ for(i=0,elem_count=1; i<space->extent.u.simple.rank; i++) {
+ slab->start[i]=start[i];
+ slab->end[i]=start[i]+size[i]-1;
+ elem_count*=size[i];
+ } /* end for */
+
+#ifdef QAK
+printf("%s: check 3.0, lo_bounds=%p, hi_bounds=%p\n",FUNC,
+ space->select.sel_info.hyper_lst->lo_bounds, space->select.sel_info.hyper_lst->hi_bounds);
+#endif /* QAK */
+ /* Increase size of boundary arrays for dataspace's selection */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+#ifdef QAK
+printf("%s: check 3.1, i=%d\n",FUNC,(int)i);
+#endif /* QAK */
+ tmp=space->select.sel_info.hyper_lst->lo_bounds[i];
+ if((space->select.sel_info.hyper_lst->lo_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count+1)))==NULL) {
+ space->select.sel_info.hyper_lst->lo_bounds[i]=tmp;
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab lo boundary array");
+ } /* end if */
+#ifdef QAK
+printf("%s: check 3.2, i=%d\n",FUNC,(int)i);
+#endif /* QAK */
+ tmp=space->select.sel_info.hyper_lst->hi_bounds[i];
+ if((space->select.sel_info.hyper_lst->hi_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count+1)))==NULL) {
+ space->select.sel_info.hyper_lst->hi_bounds[i]=tmp;
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab hi boundary array");
+ } /* end if */
+ } /* end for */
+
+#ifdef QAK
+printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+ /* Insert each boundary of the hyperslab into the sorted lists of bounds */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ /* Check if this is the first hyperslab inserted */
+ if(space->select.sel_info.hyper_lst->count==0) {
+ space->select.sel_info.hyper_lst->lo_bounds[i][0].bound=slab->start[i];
+ space->select.sel_info.hyper_lst->lo_bounds[i][0].node=slab;
+ space->select.sel_info.hyper_lst->hi_bounds[i][0].bound=slab->end[i];
+ space->select.sel_info.hyper_lst->hi_bounds[i][0].node=slab;
+ } /* end if */
+ else {
+ /* Take care of the low boundary first */
+ /* Find the location to insert in front of */
+ if((bound_loc=H5S_hyper_bsearch(slab->start[i],space->select.sel_info.hyper_lst->lo_bounds[i],
+ space->select.sel_info.hyper_lst->count))<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't find location to insert hyperslab boundary");
+
+ /* Check if we need to move boundary elements */
+ if(bound_loc!=(intn)space->select.sel_info.hyper_lst->count) {
+ HDmemmove(space->select.sel_info.hyper_lst->lo_bounds[bound_loc+1],
+ space->select.sel_info.hyper_lst->lo_bounds[bound_loc],
+ sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count-bound_loc));
+ } /* end if */
+ space->select.sel_info.hyper_lst->lo_bounds[bound_loc][i].bound=slab->start[i];
+ space->select.sel_info.hyper_lst->lo_bounds[bound_loc][i].node=slab;
+
+ /* Take care of the high boundary next */
+ /* Find the location to insert in front of */
+ if((bound_loc=H5S_hyper_bsearch(slab->end[i],space->select.sel_info.hyper_lst->hi_bounds[i],
+ space->select.sel_info.hyper_lst->count))<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't find location to insert hyperslab boundary");
+
+ /* Check if we need to move boundary elements */
+ if(bound_loc!=(intn)space->select.sel_info.hyper_lst->count) {
+ HDmemmove(space->select.sel_info.hyper_lst->hi_bounds[bound_loc+1],
+ space->select.sel_info.hyper_lst->hi_bounds[bound_loc],
+ sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hyper_lst->count-bound_loc));
+ } /* end if */
+ space->select.sel_info.hyper_lst->hi_bounds[bound_loc][i].bound=slab->end[i];
+ space->select.sel_info.hyper_lst->hi_bounds[bound_loc][i].node=slab;
+ } /* end else */
+ } /* end for */
+#ifdef QAK
+printf("%s: check 5.0\n",FUNC);
+#endif /* QAK */
+
+ /* Increment the number of bounds in the array */
+ space->select.sel_info.hyper_lst->count++;
+
+ /* Prepend on list of hyperslabs for this selection */
+ slab->next=space->select.sel_info.hyper_lst->head;
+ space->select.sel_info.hyper_lst->head=slab;
+
+ /* Increment the number of elements in the hyperslab selection */
+ space->select.num_elem+=elem_count;
+#ifdef QAK
+printf("%s: check 6.0\n",FUNC);
+#endif /* QAK */
+
+done:
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_add() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_release
+ PURPOSE
+ Release hyperslab selection information for a dataspace
+ USAGE
+ herr_t H5S_hyper_release(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Releases all hyperslab selection information for a dataspace
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_release (H5S_t *space)
+{
+ H5S_hyper_node_t *curr,*next; /* Pointer to hyperslab nodes */
+ intn i; /* Counters */
+
+ FUNC_ENTER (H5S_hyper_release, FAIL);
+
+ /* Check args */
+ assert (space && H5S_SEL_HYPERSLABS==space->select.type);
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+
+ /* Reset the number of points selected */
+ space->select.num_elem=0;
+
+ /* Release hi and lo boundary information */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ H5MM_xfree(space->select.sel_info.hyper_lst->lo_bounds[i]);
+ H5MM_xfree(space->select.sel_info.hyper_lst->hi_bounds[i]);
+ } /* end for */
+ H5MM_xfree(space->select.sel_info.hyper_lst->lo_bounds);
+ H5MM_xfree(space->select.sel_info.hyper_lst->hi_bounds);
+
+ /* Release list of selected regions */
+ curr=space->select.sel_info.hyper_lst->head;
+ while(curr!=NULL) {
+ next=curr->next;
+ H5MM_xfree(curr->start);
+ H5MM_xfree(curr->end);
+ H5MM_xfree(curr);
+ curr=next;
+ } /* end while */
+
+ /* Release hyperslab selection node itself */
+ H5MM_xfree(space->select.sel_info.hyper_lst);
+ space->select.sel_info.hyper_lst=NULL;
+
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
+
+done:
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_release() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_npoints
+ PURPOSE
+ Compute number of elements in current selection
+ USAGE
+ hsize_t H5S_hyper_npoints(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Compute number of elements in current selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t
+H5S_point_npoints (H5S_t *space)
+{
+ FUNC_ENTER (H5S_point_npoints, 0);
+
+ /* Check args */
+ assert (space);
+
+ FUNC_LEAVE (space->select.num_elem);
+} /* H5S_point_npoints() */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
new file mode 100644
index 0000000..86b1bc9
--- /dev/null
+++ b/src/H5Spoint.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Tuesday, June 16, 1998
+ *
+ * Purpose: Point selection data space I/O functions.
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Sprivate.h>
+#include <H5Vprivate.h>
+
+/* Interface initialization */
+#define PABLO_MASK H5S_point_mask
+#define INTERFACE_INIT NULL
+static intn interface_initialize_g = FALSE;
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_init
+ *
+ * Purpose: Initializes iteration information for point selection.
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_point_init (const struct H5O_layout_t __unused__ *layout,
+ const H5S_t *space, H5S_sel_iter_t *sel_iter)
+{
+ FUNC_ENTER (H5S_point_init, FAIL);
+
+ /* Check args */
+ assert (layout);
+ assert (space && H5S_SEL_POINTS==space->select.type);
+ assert (sel_iter);
+
+ /* Initialize the number of points to iterate over */
+ sel_iter->pnt.elmt_left=space->select.num_elem;
+
+ /* Start at the head of the list of points */
+ sel_iter->pnt.curr=space->select.sel_info.pnt_lst->head;
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_favail
+ *
+ * Purpose: Figure out the optimal number of elements to transfer to/from the file
+ *
+ * Return: non-negative number of elements on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_point_favail (const H5S_t __unused__ *space, const H5S_sel_iter_t *sel_iter, size_t max)
+{
+ FUNC_ENTER (H5S_point_favail, FAIL);
+
+ /* Check args */
+ assert (space && H5S_SEL_POINTS==space->select.type);
+ assert (sel_iter);
+
+ FUNC_LEAVE (MIN(sel_iter->pnt.elmt_left,max));
+} /* H5S_point_favail() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_fgath
+ *
+ * Purpose: Gathers data points from file F and accumulates them in the
+ * type conversion buffer BUF. The LAYOUT argument describes
+ * how the data is stored on disk and EFL describes how the data
+ * is organized in external files. ELMT_SIZE is the size in
+ * bytes of a datum which this function treats as opaque.
+ * FILE_SPACE describes the data space of the dataset on disk
+ * and the elements that have been selected for reading (via
+ * hyperslab, etc). This function will copy at most NELMTS elements.
+ *
+ * Notes: This could be optimized by gathering selected elements near (how
+ * near?) each other into one I/O request and then moving the correct
+ * elements into the return buffer
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *_buf/*out*/)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ uint8 *buf=(uint8 *)_buf; /* Alias for pointer arithmetic */
+ intn i; /*counters */
+ size_t num_read; /* number of elements read into buffer */
+
+ FUNC_ENTER (H5S_point_fgath, 0);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (buf);
+
+ /* initialize hyperslab size and offset in memory buffer */
+ for(i=0; i<layout->ndims; i++) {
+ hsize[i]=1; /* hyperslab size is 1, except for last element */
+ zero[i]=0; /* memory offset is 0 */
+ } /* end for */
+ hsize[layout->ndims] = elmt_size;
+
+ /* Walk though and request each element we need and put it into the buffer */
+ num_read=0;
+ while(num_read<nelmts) {
+ if(file_iter->pnt.elmt_left>0) {
+ /* Copy the location of the point to get */
+ HDmemcpy(file_offset,file_iter->pnt.curr->pnt,layout->ndims);
+ file_offset[layout->ndims] = 0;
+
+ /* Go read the point */
+ if (H5F_arr_read (f, layout, comp, efl, hsize, hsize, zero, file_offset,
+ xfer_mode, buf/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
+ }
+
+ /* Increment the offset of the buffer */
+ buf+=elmt_size;
+
+ /* Increment the count read */
+ num_read++;
+
+ /* Advance the point iterator */
+ file_iter->pnt.elmt_left--;
+ file_iter->pnt.curr=file_iter->pnt.curr->next;
+ } else {
+ break; /* out of elements in the selection */
+ } /* end else */
+ } /* end while */
+
+ FUNC_LEAVE (num_read);
+} /* H5S_point_fgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_fscat
+ *
+ * Purpose: Scatters dataset elements from the type conversion buffer BUF
+ * to the file F where the data points are arranged according to
+ * the file data space FILE_SPACE and stored according to
+ * LAYOUT and EFL. Each element is ELMT_SIZE bytes.
+ * The caller is requesting that NELMTS elements are copied.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *_buf)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */
+ const uint8 *buf=(const uint8 *)_buf; /* Alias for pointer arithmetic */
+ intn i; /*counters */
+ size_t num_written; /* number of elements written from buffer */
+
+ FUNC_ENTER (H5S_point_fscat, FAIL);
+
+ /* Check args */
+ assert (f);
+ assert (layout);
+ assert (elmt_size>0);
+ assert (file_space);
+ assert (file_iter);
+ assert (nelmts>0);
+ assert (buf);
+
+ /* initialize hyperslab size and offset in memory buffer */
+ for(i=0; i<layout->ndims; i++) {
+ hsize[i]=1; /* hyperslab size is 1, except for last element */
+ zero[i]=0; /* memory offset is 0 */
+ } /* end for */
+ hsize[layout->ndims] = elmt_size;
+
+ /* Walk though and request each element we need and put it into the buffer */
+ num_written=0;
+ while(num_written<nelmts) {
+ if(file_iter->pnt.elmt_left>0) {
+ /* Copy the location of the point to get */
+ HDmemcpy(file_offset,file_iter->pnt.curr->pnt,layout->ndims);
+ file_offset[layout->ndims] = 0;
+
+ /* Go read the point */
+ if (H5F_arr_write (f, layout, comp, efl, hsize, hsize, zero, file_offset,
+ xfer_mode, buf)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
+ }
+
+ /* Increment the offset of the buffer */
+ buf+=elmt_size;
+
+ /* Increment the count read */
+ num_written++;
+
+ /* Advance the point iterator */
+ file_iter->pnt.elmt_left--;
+ file_iter->pnt.curr=file_iter->pnt.curr->next;
+ } else {
+ break; /* out of elements in the selection */
+ } /* end else */
+ } /* end while */
+
+ FUNC_LEAVE (num_written);
+} /* H5S_point_fscat() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_mgath
+ *
+ * Purpose: Gathers dataset elements from application memory BUF and
+ * copies them into the data type conversion buffer TCONV_BUF.
+ * Each element is ELMT_SIZE bytes and arranged in application
+ * memory according to MEM_SPACE.
+ * The caller is requesting that at most NELMTS be gathered.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5S_point_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/)
+{
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
+ const uint8 *buf=(const uint8 *)_buf; /* Get local copies for address arithmetic */
+ uint8 *tconv_buf=(uint8 *)_tconv_buf;
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*dimensionality of space*/
+ intn i; /*counters */
+ size_t num_gath; /* number of elements gathered */
+
+ FUNC_ENTER (H5S_point_mgath, 0);
+
+ /* Check args */
+ assert (buf);
+ assert (elmt_size>0);
+ assert (mem_space && H5S_SEL_POINTS==mem_space->select.type);
+ assert (nelmts>0);
+ assert (tconv_buf);
+
+ if ((space_ndims=H5S_get_dims (mem_space, mem_size, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0,
+ "unable to retrieve data space dimensions");
+ }
+
+ for(num_gath=0; num_gath<nelmts; num_gath++) {
+ if(mem_iter->pnt.elmt_left>0) {
+ /* Compute the location of the point to get */
+ for(i=0,acc=0; i<space_ndims; i++)
+ acc+=mem_size[i]*mem_iter->pnt.curr->pnt[i];
+
+ /* Copy the elements into the type conversion buffer */
+ *tconv_buf=*(buf+acc);
+
+ /* Increment the offset of the buffers */
+ tconv_buf+=elmt_size;
+
+ /* Advance the point iterator */
+ mem_iter->pnt.elmt_left--;
+ mem_iter->pnt.curr=mem_iter->pnt.curr->next;
+ } else {
+ break; /* out of elements in the selection */
+ } /* end else */
+ } /* end for */
+
+ FUNC_LEAVE (num_gath);
+} /* H5S_point_mgath() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_mscat
+ *
+ * Purpose: Scatters NELMTS data points from the type conversion buffer
+ * TCONV_BUF to the application buffer BUF. Each element is
+ * ELMT_SIZE bytes and they are organized in application memory
+ * according to MEM_SPACE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 17, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/)
+{
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
+ uint8 *buf=(uint8 *)_buf; /* Get local copies for address arithmetic */
+ const uint8 *tconv_buf=(const uint8 *)_tconv_buf;
+ hsize_t acc; /*accumulator */
+ intn space_ndims; /*dimensionality of space*/
+ intn i; /*counters */
+ size_t num_scat; /* Number of elements scattered */
+
+ FUNC_ENTER (H5S_point_mscat, FAIL);
+
+ /* Check args */
+ assert (tconv_buf);
+ assert (elmt_size>0);
+ assert (mem_space && H5S_SEL_POINTS==mem_space->select.type);
+ assert (nelmts>0);
+ assert (buf);
+
+ /*
+ * Retrieve hyperslab information to determine what elements are being
+ * selected (there might be other selection methods in the future). We
+ * only handle hyperslabs with unit sample because there's currently no
+ * way to pass sample information to H5V_hyper_copy().
+ */
+ if ((space_ndims=H5S_get_dims (mem_space, mem_size, NULL))<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to retrieve data space dimensions");
+ }
+
+ for(num_scat=0; num_scat<nelmts; num_scat++) {
+ if(mem_iter->pnt.elmt_left>0) {
+ /* Compute the location of the point to get */
+ for(i=0,acc=0; i<space_ndims; i++)
+ acc+=mem_size[i]*mem_iter->pnt.curr->pnt[i];
+
+ /* Copy the elements into the type conversion buffer */
+ *(buf+acc)=*tconv_buf;
+
+ /* Increment the offset of the buffers */
+ tconv_buf+=elmt_size;
+
+ /* Advance the point iterator */
+ mem_iter->pnt.elmt_left--;
+ mem_iter->pnt.curr=mem_iter->pnt.curr->next;
+ } else {
+ break; /* out of elements in the selection */
+ } /* end else */
+ } /* end for */
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_point_mscat() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_point_release
+ PURPOSE
+ Release point selection information for a dataspace
+ USAGE
+ herr_t H5S_point_release(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Releases all point selection information for a dataspace
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_release (H5S_t *space)
+{
+ intn i; /* Counters */
+
+ FUNC_ENTER (H5S_point_release, FAIL);
+
+ /* Check args */
+ assert (space);
+
+done:
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_point_release() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_point_npoints
+ PURPOSE
+ Compute number of elements in current selection
+ USAGE
+ hsize_t H5S_point_npoints(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Compute number of elements in current selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t
+H5S_hyper_npoints (H5S_t *space)
+{
+ FUNC_ENTER (H5S_hyper_npoints, 0);
+
+ /* Check args */
+ assert (space);
+
+ FUNC_LEAVE (space->select.num_elem);
+} /* H5S_hyper_npoints() */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 084c282..a523405 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -29,71 +29,162 @@
#define H5S_VALID_MAX 0x01
#define H5S_VALID_PERM 0x02
-typedef struct H5S_hyperslab_t {
- hssize_t *start; /* Location of start of hyperslab */
- hsize_t *count; /* Number of elements in hyperslab */
- hsize_t *stride; /* Packing of values of hyperslab */
-} H5S_hyperslab_t;
-
+/*
+ * Dataspace extent information
+ */
+/* Simple extent container */
typedef struct H5S_simple_t {
- intn rank; /*number of dimensions */
- hsize_t *size; /*dimension sizes */
- hsize_t *max; /*maximum dimension sizes or NULL */
- intn *perm; /*dimension permutations or NULL */
+ intn rank; /* Number of dimensions */
+ hsize_t *size; /* Current size of the dimensions */
+ hsize_t *max; /* Maximum size of the dimensions */
} H5S_simple_t;
-typedef struct H5S_t {
- H5S_class_t type; /*type of dimensionality object */
+/* Extent container */
+typedef struct {
+ H5S_class_t type; /* Type of extent */
union {
- H5S_simple_t simple; /*simple dimensionality information */
+ H5S_simple_t simple; /* Simple dimensionality information */
} u;
- uintn hslab_def; /* Whether the hyperslab is defined */
- H5S_hyperslab_t h; /* Hyperslab information */
-} H5S_t;
+} H5S_extent_t;
-/*
- * This structure contains information about how the elements of a data space
- * are numbered.
+/*
+ * Dataspace selection information
*/
-typedef struct H5S_number_t {
- int _place_holder; /*remove this field! */
-} H5S_number_t;
+/* Enumerated type for the type of selection */
+typedef enum {
+ H5S_SEL_NONE, /* Nothing selected */
+ H5S_SEL_POINTS, /* Sequence of points selected */
+ H5S_SEL_HYPERSLABS, /* Hyperslab selection defined */
+ H5S_SEL_ALL /* Entire extent selected */
+}H5S_sel_type;
+
+/* Node in point selection list */
+typedef struct H5S_pnt_node_tag {
+ hssize_t *pnt; /* Pointer to a selected point */
+ struct H5S_pnt_node_tag *next; /* pointer to next point in list */
+} H5S_pnt_node_t;
+
+/* Information about point selection list */
+typedef struct {
+ H5S_pnt_node_t *head; /* Pointer to head of point list */
+} H5S_pnt_list_t;
+
+/* Region in dimension */
+typedef struct H5S_hyper_region_tag {
+ hssize_t start; /* The low bound of a region in a dimension */
+ hssize_t end; /* The high bound of a region in a dimension */
+} H5S_hyper_region_t;
+
+/* Node in hyperslab selection list */
+typedef struct H5S_hyper_node_tag {
+ hssize_t *start; /* Pointer to a corner of a hyperslab closest to the origin */
+ hssize_t *end; /* Pointer to a corner of a hyperslab furthest from the origin */
+ struct H5S_hyper_node_tag *next; /* pointer to next hyperslab in list */
+} H5S_hyper_node_t;
+
+/* Information about hyperslab boundary and pointer to hyperslab node */
+typedef struct {
+ hssize_t bound; /* Location of boundary */
+ H5S_hyper_node_t *node; /* Boundary's node */
+} H5S_hyper_bound_t;
+
+/* Information about hyperslab selection */
+typedef struct {
+ size_t count; /* Number of nodes in list */
+ H5S_hyper_node_t *head; /* Pointer to head of hyperslab list */
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+} H5S_hyper_list_t;
+
+/* Selection information container */
+typedef struct {
+ H5S_sel_type type; /* Type of selection (list of points or hyperslabs) */
+ hsize_t *offset; /* Offset within the extent (NULL means a 0 offset) */
+ hsize_t *order; /* Selection order. (NULL means a specific ordering of points) */
+ hsize_t num_elem; /* Number of elements in selection */
+ union {
+ H5S_pnt_list_t *pnt_lst; /* List of selected points (order is important) */
+ H5S_hyper_list_t *hyper_lst; /* List of selected hyperslabs (order is not important) */
+ } sel_info;
+} H5S_select_t;
+
+/* Point selection iteration container */
+typedef struct {
+ hsize_t elmt_left; /* Number of elements left to iterate over */
+ H5S_pnt_node_t *curr; /* Pointer to next node to output */
+} H5S_point_iter_t;
+
+/* Hyperslab selection iteration container */
+typedef struct {
+ hsize_t elmt_left; /* Number of elements left to iterate over */
+ hssize_t *pos; /* Position to start iterating at */
+} H5S_hyper_iter_t;
+
+/* "All" selection iteration container */
+typedef struct {
+ hsize_t elmt_left; /* Number of elements left to iterate over */
+ hsize_t offset; /* Next element to output */
+} H5S_all_iter_t;
+
+/* Selection iteration container */
+typedef union {
+ H5S_point_iter_t pnt; /* Point selection iteration information */
+ H5S_hyper_iter_t hyp; /* Hyperslab selection iteration information */
+ H5S_all_iter_t all; /* "All" selection iteration information */
+} H5S_sel_iter_t;
+
+/* Main dataspace structure */
+typedef struct H5S_t {
+ H5S_extent_t extent; /* Dataspace extent */
+ H5S_select_t select; /* Dataspace selection */
+} H5S_t;
/*
* Callbacks for data space conversion.
*/
typedef struct H5S_tconv_t {
- /* Initialize element numbering information */
- size_t (*init)(const struct H5O_layout_t *layout, const H5S_t *mem_space,
- const H5S_t *file_space, size_t desired_nelmts,
- H5S_number_t *numbering/*out*/);
+ /* Initialize file element numbering information */
+ herr_t (*finit)(const struct H5O_layout_t *layout, const H5S_t *space,
+ H5S_sel_iter_t *iter);
+
+ /* Initialize memory element numbering information */
+ herr_t (*minit)(const struct H5O_layout_t *layout, const H5S_t *space,
+ H5S_sel_iter_t *iter);
+
+ /* Initialize background element numbering information */
+ herr_t (*binit)(const struct H5O_layout_t *layout, const H5S_t *space,
+ H5S_sel_iter_t *iter);
+
+ /* Figure out the optimal number of elements to transfer to/from the file */
+ size_t (*favail)(const H5S_t *file_space, const H5S_sel_iter_t *file_iter,
+ size_t max);
/* Gather elements from disk to type conversion buffer */
size_t (*fgath)(H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp,
const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, const H5S_number_t *numbering,
- size_t start, size_t nelmts,
+ const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
const H5D_transfer_t xfer_mode, void *tconv_buf/*out*/);
- /* Scatter elements from type conversion buffer to application buffer */
- herr_t (*mscat)(const void *tconv_buf, size_t elmt_size,
- const H5S_t *mem_space, const H5S_number_t *numbering,
- size_t start, size_t nelmts, void *buf/*out*/);
-
- /* Gather elements from app buffer to type conversion buffer */
- size_t (*mgath)(const void *buf, size_t elmt_size,
- const H5S_t *mem_space, const H5S_number_t *numbering,
- size_t start, size_t nelmts, void *tconv_buf/*out*/);
-
/* Scatter elements from type conversion buffer to disk */
herr_t (*fscat)(H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *compress,
const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, const H5S_number_t *numbering,
- size_t start, size_t nelmts,
+ const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
const H5D_transfer_t xfer_mode, const void *tconv_buf);
+ /* Gather elements from app buffer to type conversion buffer */
+ size_t (*mgath)(const void *buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *tconv_buf/*out*/);
+
+ /* Scatter elements from type conversion buffer to application buffer */
+ herr_t (*mscat)(const void *tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *buf/*out*/);
+
/* Read from file to application w/o intermediate scratch buffer */
herr_t (*read)(H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp,
@@ -109,6 +200,7 @@ typedef struct H5S_tconv_t {
const H5D_transfer_t xfer_mode, const void *buf);
} H5S_conv_t;
+H5S_t *H5S_create (H5S_class_t type);
H5S_t *H5S_copy (const H5S_t *src);
herr_t H5S_close_simple (H5S_simple_t *simple);
herr_t H5S_close (H5S_t *ds);
@@ -122,31 +214,36 @@ H5S_t *H5S_read (H5G_entry_t *ent);
intn H5S_cmp (const H5S_t *ds1, const H5S_t *ds2);
hbool_t H5S_is_simple (const H5S_t *sdim);
uintn H5S_nelem (const H5S_t *space);
-const H5S_conv_t *H5S_find (const H5S_t *mem_space, const H5S_t *file_space);
+herr_t H5S_find (H5S_conv_t *conv, const H5S_t *mem_space, const H5S_t *file_space);
intn H5S_get_hyperslab (const H5S_t *ds, hssize_t offset[]/*out*/,
hsize_t size[]/*out*/, hsize_t stride[]/*out*/);
+herr_t H5S_release_simple(H5S_simple_t *simple);
+herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src);
+herr_t H5S_select_copy (H5S_t *dst, const H5S_t *src);
+herr_t H5S_select_release (H5S_t *space);
+hsize_t H5S_select_npoints (H5S_t *space);
intn H5S_extend (H5S_t *space, const hsize_t *size);
/* Conversion functions for simple data spaces */
size_t H5S_simp_init (const struct H5O_layout_t *layout,
const H5S_t *mem_space, const H5S_t *file_space,
- size_t desired_nelmts, H5S_number_t *numbering/*out*/);
+ size_t desired_nelmts);
size_t H5S_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp,
const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, const H5S_number_t *numbering,
+ const H5S_t *file_space,
size_t start, size_t nelmts,
const H5D_transfer_t xfer_mode, void *tconv_buf/*out*/);
herr_t H5S_simp_mscat (const void *tconv_buf, size_t elmt_size,
- const H5S_t *mem_space, const H5S_number_t *numbering,
+ const H5S_t *mem_space,
size_t start, size_t nelmts, void *buf/*out*/);
size_t H5S_simp_mgath (const void *buf, size_t elmt_size,
- const H5S_t *mem_space, const H5S_number_t *numbering,
+ const H5S_t *mem_space,
size_t start, size_t nelmts, void *tconv_buf/*out*/);
herr_t H5S_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp,
const struct H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *file_space, const H5S_number_t *numbering,
+ const H5S_t *file_space,
size_t start, size_t nelmts,
const H5D_transfer_t xfer_mode, const void *tconv_buf);
herr_t H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout,
@@ -159,4 +256,78 @@ herr_t H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space,
const H5D_transfer_t xfer_mode, const void *buf);
+
+/* Point select functions */
+herr_t H5S_point_init (const struct H5O_layout_t *layout,
+ const H5S_t *space, H5S_sel_iter_t *iter);
+size_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
+ size_t max);
+size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *buf/*out*/);
+herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *buf);
+size_t H5S_point_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/);
+herr_t H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/);
+herr_t H5S_point_release (H5S_t *space);
+hsize_t H5S_point_npoints (H5S_t *space);
+
+/* "All" select functions */
+herr_t H5S_all_init (const struct H5O_layout_t *layout,
+ const H5S_t *space, H5S_sel_iter_t *iter);
+size_t H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
+ size_t max);
+size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *buf/*out*/);
+herr_t H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *buf);
+size_t H5S_all_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/);
+herr_t H5S_all_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/);
+herr_t H5S_all_release (H5S_t *space);
+hsize_t H5S_all_npoints (H5S_t *space);
+
+/* Hyperslab selection functions */
+herr_t H5S_hyper_init (const struct H5O_layout_t *layout,
+ const H5S_t *space, H5S_sel_iter_t *iter);
+size_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
+ size_t max);
+size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, void *buf/*out*/);
+herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
+ const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
+ size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter,
+ size_t nelmts,
+ const H5D_transfer_t xfer_mode, const void *buf);
+size_t H5S_hyper_mgath (const void *_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_tconv_buf/*out*/);
+herr_t H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
+ const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
+ size_t nelmts, void *_buf/*out*/);
+herr_t H5S_hyper_add (H5S_t *space, hssize_t *start, hssize_t *size);
+herr_t H5S_hyper_release (H5S_t *space);
+hsize_t H5S_hyper_npoints (H5S_t *space);
+
#endif
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 39b6502..b7c0f01 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -13,8 +13,8 @@
/*
* This file contains public declarations for the H5S module.
*/
-#ifndef _H5pproto_H
-#define _H5Sproto_H
+#ifndef _H5Spublic_H
+#define _H5Spublic_H
/* Public headers needed by this file */
#include <H5public.h>
@@ -32,13 +32,20 @@ typedef enum H5S_class_t {
H5S_COMPLEX = 2 /*complex data space */
} H5S_class_t;
+/* Different ways of combining selections */
+typedef enum H5S_seloper_t {
+ H5S_NOOP = -1, /*error */
+ H5S_SELECT_SET = 0 /* Select "set" operation */
+} H5S_seloper_t;
+
#ifdef __cplusplus
extern "C" {
#endif
/* Functions in H5S.c */
-hid_t H5Screate_simple (int rank, const hsize_t dims[],
- const hsize_t maxdims[]);
+hid_t H5Screate(H5S_class_t type);
+hid_t H5Screate_simple (int rank, const hsize_t dims[], const hsize_t maxdims[]);
+herr_t H5Sset_extent_simple (hid_t sid, int rank, const hsize_t *dims, const hsize_t *max);
hid_t H5Scopy (hid_t space_id);
herr_t H5Sclose (hid_t space_id);
hsize_t H5Sget_npoints (hid_t space_id);
@@ -46,10 +53,9 @@ int H5Sget_ndims (hid_t space_id);
int H5Sget_dims (hid_t space_id, hsize_t dims[], hsize_t maxdims[]);
hbool_t H5Sis_simple (hid_t space_id);
herr_t H5Sset_space (hid_t space_id, int rank, const hsize_t *dims);
-herr_t H5Sset_hyperslab(hid_t sid, const hssize_t *start, const hsize_t *count,
- const hsize_t *stride);
-int H5Sget_hyperslab (hid_t sid, hssize_t offset[]/*out*/,
- hsize_t size[]/*out*/, hsize_t stride[]/*out*/);
+hsize_t H5Sselect_npoints (hid_t spaceid);
+herr_t H5Sselect_hyperslab (hid_t spaceid, H5S_seloper_t op, hssize_t *start,
+ hssize_t *_stride, hssize_t *count, hssize_t *_block);
#ifdef __cplusplus
}
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
new file mode 100644
index 0000000..e07b60b
--- /dev/null
+++ b/src/H5Sselect.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.ued>
+ * Friday, May 29, 1998
+ *
+ * Purpose: Dataspace functions.
+ */
+
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Iprivate.h>
+#include <H5MMprivate.h>
+#include <H5Sprivate.h>
+#include <H5Vprivate.h>
+
+/* Interface initialization */
+#define PABLO_MASK H5S_select_mask
+#define INTERFACE_INIT H5S_select_init
+static intn interface_initialize_g = FALSE;
+static herr_t H5S_select_init(void);
+static void H5S_select_term(void);
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_init
+ PURPOSE
+ Initialize selection interface
+ USAGE
+ herr_t H5S_select_init(void)
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5S_select_init (void)
+{
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER (H5S_select_init, FAIL);
+
+ /* Register the atexit function for this (sub)interface */
+ ret_value = H5_add_exit(&H5S_select_term);
+ FUNC_LEAVE(ret_value);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_term
+ PURPOSE
+ Terminate various H5S selection objects and free lists
+ USAGE
+ void H5S_select_term()
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Release the selection resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static void
+H5S_select_term(void)
+{
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_copy
+ PURPOSE
+ Copy a selection from one dataspace to another
+ USAGE
+ herr_t H5S_select_copy(dst, src)
+ H5S_t *dst; OUT: Pointer to the destination dataspace
+ H5S_t *src; IN: Pointer to the source dataspace
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Copies all the selection information (include offset) from the source
+ dataspace to the destination dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5S_select_copy (H5S_t *dst, const H5S_t *src)
+{
+ FUNC_ENTER (H5S_select_copy, FAIL);
+
+ /* Check args */
+ assert(dst);
+ assert(src);
+
+
+ /* Perform correct type of copy based on the type of selection */
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_select_copy() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_release
+ PURPOSE
+ Release selection information for a dataspace
+ USAGE
+ herr_t H5S_select_release(space)
+ H5S_t *space; IN: Pointer to dataspace
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Releases all selection information for a dataspace
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_release (H5S_t *space)
+{
+ herr_t ret_value; /* Counters */
+
+ FUNC_ENTER (H5S_select_release, FAIL);
+
+ /* Check args */
+ assert (space);
+
+ switch(space->select.type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value=H5S_point_release(space);
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value=H5S_hyper_release(space);
+ break;
+
+ case H5S_SEL_ALL: /* Entire extent selected */
+ ret_value=H5S_all_release(space);
+ break;
+
+ case H5S_SEL_NONE: /* Nothing selected */
+ break;
+ } /* end switch() */
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_select_release() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_hyperslab
+ PURPOSE
+ Specify a hyperslab to combine with the current hyperslab selection
+ USAGE
+ herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ H5S_seloper_t op; IN: Operation to perform on current selection
+ hssize_t *start; IN: Offset of start of hyperslab
+ hssize_t *stride; IN: Hyperslab stride
+ hssize_t *count; IN: Number of blocks included in hyperslab
+ hssize_t *block; IN: Size of block in hyperslab
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Combines a hyperslab selection with the current selection for a dataspace.
+ If the current selection is not a hyperslab, it is freed and the hyperslab
+ parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a
+ selection composing the entire current extent). Currently, only the
+ H5S_SELECT_SET operation is supported. If STRIDE or BLOCK is NULL, they
+ are assumed to be set to all '1'.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5Sselect_hyperslab (hid_t spaceid, H5S_seloper_t op, hssize_t *start,
+ hssize_t *_stride, hssize_t *count, hssize_t *_block)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ hssize_t *stride, /* Stride array */
+ *block; /* Block size array */
+ uintn contig; /* whether selection is contiguous or not */
+ int i; /* Counters */
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5Sselect_hyperslab, FAIL);
+
+ /* Check args */
+ if (H5_DATASPACE != H5I_group(spaceid) ||
+ NULL == (space=H5I_object(spaceid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+ if(start==NULL || count==NULL) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified");
+ } /* end if */
+ if(op!=H5S_SELECT_SET) {
+ HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL,
+ "operations other than H5S_SELECT_SET not supported currently");
+ } /* end if */
+
+ /* Fill in the correct stride values */
+ if(_stride==NULL) {
+ hssize_t fill=1;
+
+ if((stride = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate stride vector");
+ H5V_array_fill(stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
+ } else {
+ stride=_stride;
+ } /* end else */
+
+ /* Fill in the correct block values */
+ if(_block==NULL) {
+ hssize_t fill=1;
+
+ if((block = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate stride vector");
+ H5V_array_fill(block,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
+ } else {
+ block=_block;
+ } /* end else */
+
+/* Check for overlapping blocks (remove when real block-merging algorithm is in place) */
+if(op==H5S_SELECT_SET && _block!=NULL) {
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ if(stride[i]<block[i]) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "hyperslab blocks overlap");
+ } /* end if */
+ } /* end for */
+} /* end if */
+
+ /* Determine if selection is contiguous */
+ contig=1; /* assume hyperslab is contiguous, until proven otherwise */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ /* contiguous hyperslabs have the block size equal to the stride */
+ if(stride[i]!=block[i]) {
+ contig=0; /* hyperslab isn't contiguous */
+ break; /* no use looking further */
+ } /* end if */
+ } /* end for */
+
+#ifdef QAK
+printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+ /* If we are setting a new selection, remove current selection first */
+ if(op==H5S_SELECT_SET) {
+ if(H5S_select_release(space)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
+ "can't release hyperslab");
+ } /* end if */
+ } /* end if */
+
+#ifdef QAK
+printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
+ /* Allocate space for the hyperslab selection information if necessary */
+ if(space->select.type!=H5S_SEL_HYPERSLABS || space->select.sel_info.hyper_lst==NULL) {
+ if((space->select.sel_info.hyper_lst = H5MM_calloc(sizeof(H5S_hyper_list_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab information");
+ if((space->select.sel_info.hyper_lst->lo_bounds = H5MM_calloc(space->extent.u.simple.rank*sizeof(H5S_hyper_bound_t *)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab lo bound information");
+ if((space->select.sel_info.hyper_lst->hi_bounds = H5MM_calloc(space->extent.u.simple.rank*sizeof(H5S_hyper_bound_t *)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab lo bound information");
+ } /* end if */
+
+#ifdef QAK
+printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
+ /* Add hyperslab to selection */
+ if(contig) { /* Check for trivial case */
+ if(H5S_hyper_add(space,start,count)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL,
+ "can't insert hyperslab");
+ }
+ } else {
+/* Generate list of blocks to add/remove based on selection operation */
+/* Add/Remove blocks to/from selection */
+ assert("complex hyperslabs not supported yet" && 0);
+ } /* end if */
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_HYPERSLABS;
+ ret_value=SUCCEED;
+#ifdef QAK
+printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+
+done:
+ if(_stride==NULL && stride!=NULL)
+ H5MM_xfree(stride);
+ if(_block==NULL && block!=NULL)
+ H5MM_xfree(block);
+
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_hyperslab() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_npoints
+ PURPOSE
+ Get the number of elements in current selection
+ USAGE
+ herr_t H5Sselect_hyperslab(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to query
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Returns the number of elements in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t H5Sselect_npoints (hid_t spaceid)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ hsize_t ret_value=0; /* return value */
+
+ FUNC_ENTER (H5Sselect_npoints, 0);
+
+ /* Check args */
+ if (H5_DATASPACE != H5I_group(spaceid) ||
+ NULL == (space=H5I_object(spaceid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data space");
+ }
+
+ ret_value = H5S_select_npoints(space);
+
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_npoints() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_npoints
+ PURPOSE
+ Get the number of elements in current selection
+ USAGE
+ herr_t H5Sselect_hyperslab(ds)
+ H5S_t *ds; IN: Dataspace pointer
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Returns the number of elements in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t H5S_select_npoints (H5S_t *space)
+{
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5Sselect_npoints, FAIL);
+
+ assert(space);
+
+ switch(space->select.type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value=H5S_point_npoints(space);
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value=H5S_hyper_npoints(space);
+ break;
+
+ case H5S_SEL_ALL: /* Entire extent selected */
+ ret_value=H5S_all_npoints(space);
+ break;
+
+ case H5S_SEL_NONE: /* Nothing selected */
+ ret_value=0;
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_npoints() */
diff --git a/src/H5Ssimp.c b/src/H5Ssimp.c
index 64be705..1f47b45 100644
--- a/src/H5Ssimp.c
+++ b/src/H5Ssimp.c
@@ -5,7 +5,7 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Wednesday, January 21, 1998
*
- * Purpose: Simple data space functions.
+ * Purpose: Simple selection data space I/O functions.
*/
#include <H5private.h>
#include <H5Eprivate.h>
@@ -38,7 +38,7 @@ static intn interface_initialize_g = FALSE;
size_t
H5S_simp_init (const struct H5O_layout_t __unused__ *layout,
const H5S_t *mem_space, const H5S_t *file_space,
- size_t desired_nelmts, H5S_number_t *numbering/*out*/)
+ size_t desired_nelmts)
{
hsize_t nelmts;
int m_ndims, f_ndims; /*mem, file dimensionality */
@@ -50,12 +50,8 @@ H5S_simp_init (const struct H5O_layout_t __unused__ *layout,
/* Check args */
assert (layout);
- assert (mem_space && H5S_SIMPLE==mem_space->type);
- assert (file_space && H5S_SIMPLE==file_space->type);
- assert (numbering);
-
- /* Numbering is implied by the hyperslab, C order, no data here */
- HDmemset (numbering, 0, sizeof(H5S_number_t));
+ assert (mem_space && H5S_SIMPLE==mem_space->extent.type);
+ assert (file_space && H5S_SIMPLE==file_space->extent.type);
/*
* The stripmine size is such that only the slowest varying dimension can
@@ -66,7 +62,7 @@ H5S_simp_init (const struct H5O_layout_t __unused__ *layout,
for (i=m_ndims-1, acc=1; i>0; --i) acc *= size[i];
nelmts = (desired_nelmts/acc) * acc;
if (nelmts<=0) {
- HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
"strip mine buffer is too small");
}
@@ -76,20 +72,19 @@ H5S_simp_init (const struct H5O_layout_t __unused__ *layout,
*/
f_ndims = H5S_get_hyperslab (file_space, NULL, size, NULL);
if (m_ndims!=f_ndims) {
- nelmts = H5S_get_npoints (file_space);
- if (nelmts>desired_nelmts) {
- HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
- "strip mining not supported across "
- "dimensionalities");
- }
- assert (nelmts==H5S_get_npoints (mem_space));
+ nelmts = H5S_get_npoints (file_space);
+ if (nelmts>desired_nelmts) {
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
+ "strip mining not supported across dimensionalities");
+ }
+ assert (nelmts==H5S_get_npoints (mem_space));
} else {
- for (i=f_ndims-1, acc=1; i>0; --i) acc *= size[i];
- acc *= (desired_nelmts/acc);
- if (nelmts!=acc) {
- HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
- "unsupported strip mine size for shape change");
- }
+ for (i=f_ndims-1, acc=1; i>0; --i) acc *= size[i];
+ acc *= (desired_nelmts/acc);
+ if (nelmts!=acc) {
+ HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, 0,
+ "unsupported strip mine size for shape change");
+ }
}
assert (nelmts < MAX_SIZET);
@@ -128,7 +123,6 @@ size_t
H5S_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
size_t elmt_size, const H5S_t *file_space,
- const H5S_number_t __unused__ *numbering,
size_t start, size_t nelmts,
const H5D_transfer_t xfer_mode, void *buf/*out*/)
{
@@ -147,7 +141,6 @@ H5S_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout,
assert (layout);
assert (elmt_size>0);
assert (file_space);
- assert (numbering);
assert (nelmts>0);
assert (buf);
@@ -219,7 +212,6 @@ H5S_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout,
herr_t
H5S_simp_mscat (const void *tconv_buf, size_t elmt_size,
const H5S_t *mem_space,
- const H5S_number_t __unused__ *numbering,
size_t start, size_t nelmts, void *buf/*out*/)
{
hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/
@@ -236,8 +228,7 @@ H5S_simp_mscat (const void *tconv_buf, size_t elmt_size,
/* Check args */
assert (tconv_buf);
assert (elmt_size>0);
- assert (mem_space && H5S_SIMPLE==mem_space->type);
- assert (numbering);
+ assert (mem_space && H5S_SIMPLE==mem_space->extent.type);
assert (nelmts>0);
assert (buf);
@@ -316,7 +307,6 @@ H5S_simp_mscat (const void *tconv_buf, size_t elmt_size,
size_t
H5S_simp_mgath (const void *buf, size_t elmt_size,
const H5S_t *mem_space,
- const H5S_number_t __unused__ *numbering,
size_t start, size_t nelmts, void *tconv_buf/*out*/)
{
hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/
@@ -333,8 +323,7 @@ H5S_simp_mgath (const void *buf, size_t elmt_size,
/* Check args */
assert (buf);
assert (elmt_size>0);
- assert (mem_space && H5S_SIMPLE==mem_space->type);
- assert (numbering);
+ assert (mem_space && H5S_SIMPLE==mem_space->extent.type);
assert (nelmts>0);
assert (tconv_buf);
@@ -415,7 +404,6 @@ herr_t
H5S_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_compress_t *comp, const struct H5O_efl_t *efl,
size_t elmt_size, const H5S_t *file_space,
- const H5S_number_t __unused__ *numbering,
size_t start, size_t nelmts,
const H5D_transfer_t xfer_mode, const void *buf)
{
@@ -434,7 +422,6 @@ H5S_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout,
assert (layout);
assert (elmt_size>0);
assert (file_space);
- assert (numbering);
assert (nelmts>0);
assert (buf);
@@ -521,9 +508,10 @@ H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout,
FUNC_ENTER (H5S_simp_read, FAIL);
#ifndef NDEBUG
- assert (file_space->type==mem_space->type);
- assert (file_space->u.simple.rank==mem_space->u.simple.rank);
- for (i=0; i<file_space->u.simple.rank; i++) {
+ assert (file_space->extent.type==mem_space->extent.type);
+ assert (file_space->extent.u.simple.rank==mem_space->extent.u.simple.rank);
+ for (i=0; i<file_space->extent.u.simple.rank; i++) {
+#ifdef FIXME
if (file_space->hslab_def && mem_space->hslab_def) {
assert (1==file_space->h.stride[i]);
assert (1==mem_space->h.stride[i]);
@@ -538,6 +526,7 @@ H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout,
assert (file_space->u.simple.size[i]==
mem_space->u.simple.size[i]);
}
+#endif
}
#endif
@@ -546,40 +535,74 @@ H5S_simp_read (H5F_t *f, const struct H5O_layout_t *layout,
* Calculate size of hyperslab and offset of hyperslab into file and
* memory.
*/
- if (file_space->hslab_def) {
- for (i=0; i<file_space->u.simple.rank; i++) {
- hslab_size[i] = file_space->h.count[i];
- }
- } else {
- for (i=0; i<file_space->u.simple.rank; i++) {
- hslab_size[i] = file_space->u.simple.size[i];
- }
- }
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_size[i] = mem_space->u.simple.size[i];
- }
- if (file_space->hslab_def) {
- for (i=0; i<file_space->u.simple.rank; i++) {
- file_offset[i] = file_space->h.start[i];
- }
- } else {
- for (i=0; i<file_space->u.simple.rank; i++) {
- file_offset[i] = 0;
- }
- }
- if (mem_space->hslab_def) {
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_offset[i] = mem_space->h.start[i];
- }
- } else {
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_offset[i] = 0;
- }
- }
- hslab_size[file_space->u.simple.rank] = elmt_size;
- mem_size[file_space->u.simple.rank] = elmt_size;
- file_offset[file_space->u.simple.rank] = 0;
- mem_offset[file_space->u.simple.rank] = 0;
+ switch(file_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<file_space->extent.u.simple.rank; i++)
+ hslab_size[i] = file_space->extent.u.simple.size[i];
+ break;
+ } /* end switch */
+
+ switch(mem_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<mem_space->extent.u.simple.rank; i++)
+ mem_size[i] = mem_space->extent.u.simple.size[i];
+ break;
+ } /* end switch */
+
+ switch(file_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+#ifdef LATER
+ for (i=0; i<file_space->u.simple.rank; i++)
+ file_offset[i] = file_space->h.start[i];
+#endif
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<file_space->extent.u.simple.rank; i++)
+ file_offset[i] = 0;
+ break;
+ } /* end switch */
+
+ switch(mem_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+#ifdef LATER
+ for (i=0; i<mem_space->u.simple.rank; i++)
+ mem_offset[i] = mem_space->h.start[i];
+#endif
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<mem_space->extent.u.simple.rank; i++)
+ mem_offset[i] = 0;
+ break;
+ } /* end switch */
+
+ hslab_size[file_space->extent.u.simple.rank] = elmt_size;
+ mem_size[file_space->extent.u.simple.rank] = elmt_size;
+ file_offset[file_space->extent.u.simple.rank] = 0;
+ mem_offset[file_space->extent.u.simple.rank] = 0;
/* Read the hyperslab */
if (H5F_arr_read (f, layout, comp, efl, hslab_size,
@@ -629,8 +652,9 @@ H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout,
FUNC_ENTER (H5S_simp_write, FAIL);
#ifndef NDEBUG
- assert (file_space->type==mem_space->type);
- assert (file_space->u.simple.rank==mem_space->u.simple.rank);
+ assert (file_space->extent.type==mem_space->extent.type);
+ assert (file_space->extent.u.simple.rank==mem_space->extent.u.simple.rank);
+#ifdef LATER
for (i=0; i<file_space->u.simple.rank; i++) {
if (file_space->hslab_def && mem_space->hslab_def) {
assert (1==file_space->h.stride[i]);
@@ -648,46 +672,81 @@ H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout,
}
}
#endif
+#endif
/*
* Calculate size of hyperslab and offset of hyperslab into file and
* memory.
*/
- if (file_space->hslab_def) {
- for (i=0; i<file_space->u.simple.rank; i++) {
- hslab_size[i] = file_space->h.count[i];
- }
- } else {
- for (i=0; i<file_space->u.simple.rank; i++) {
- hslab_size[i] = file_space->u.simple.size[i];
- }
- }
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_size[i] = mem_space->u.simple.size[i];
- }
- if (file_space->hslab_def) {
- for (i=0; i<file_space->u.simple.rank; i++) {
- file_offset[i] = file_space->h.start[i];
- }
- } else {
- for (i=0; i<file_space->u.simple.rank; i++) {
- file_offset[i] = 0;
- }
- }
- if (mem_space->hslab_def) {
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_offset[i] = mem_space->h.start[i];
- }
- } else {
- for (i=0; i<mem_space->u.simple.rank; i++) {
- mem_offset[i] = 0;
- }
- }
- hslab_size[file_space->u.simple.rank] = elmt_size;
- mem_size[file_space->u.simple.rank] = elmt_size;
- file_offset[file_space->u.simple.rank] = 0;
- mem_offset[file_space->u.simple.rank] = 0;
+ switch(file_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<file_space->extent.u.simple.rank; i++)
+ hslab_size[i] = file_space->extent.u.simple.size[i];
+ break;
+ } /* end switch */
+
+ switch(mem_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<mem_space->extent.u.simple.rank; i++)
+ mem_size[i] = mem_space->extent.u.simple.size[i];
+ break;
+ } /* end switch */
+
+ switch(file_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+#ifdef LATER
+ for (i=0; i<file_space->u.simple.rank; i++)
+ file_offset[i] = file_space->h.start[i];
+#endif
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<file_space->extent.u.simple.rank; i++)
+ file_offset[i] = 0;
+ break;
+ } /* end switch */
+
+ switch(mem_space->select.type) {
+ case H5S_SEL_NONE: /* no selection defined */
+ HRETURN_ERROR (H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection not defined");
+
+ case H5S_SEL_POINTS: /* point sequence selection defined */
+ case H5S_SEL_HYPERSLABS: /* hyperslab selection defined */
+#ifdef LATER
+ for (i=0; i<mem_space->u.simple.rank; i++)
+ mem_offset[i] = mem_space->h.start[i];
+#endif
+ HRETURN_ERROR (H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type not supprted currently");
+
+ case H5S_SEL_ALL: /* entire dataspace selection */
+ for (i=0; i<mem_space->extent.u.simple.rank; i++)
+ mem_offset[i] = 0;
+ break;
+ } /* end switch */
+
+ hslab_size[file_space->extent.u.simple.rank] = elmt_size;
+ mem_size[file_space->extent.u.simple.rank] = elmt_size;
+ file_offset[file_space->extent.u.simple.rank] = 0;
+ mem_offset[file_space->extent.u.simple.rank] = 0;
/* Write the hyperslab */
if (H5F_arr_write (f, layout, comp, efl, hslab_size,
@@ -699,6 +758,3 @@ H5S_simp_write (H5F_t *f, const struct H5O_layout_t *layout,
FUNC_LEAVE (SUCCEED);
}
-
-
-
diff --git a/src/H5TB.c b/src/H5TB.c
new file mode 100644
index 0000000..627f755
--- /dev/null
+++ b/src/H5TB.c
@@ -0,0 +1,506 @@
+/****************************************************************************
+* NCSA HDF *
+* Software Development Group *
+* National Center for Supercomputing Applications *
+* University of Illinois at Urbana-Champaign *
+* 605 E. Springfield, Champaign IL 61820 *
+* *
+* For conditions of distribution and use, see the accompanying *
+* hdf/COPYING file. *
+* *
+****************************************************************************/
+
+/*
+ * Created: H5TB.c
+ * Jun 11 1998
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Temporary buffer management functions
+ *
+ * Library Public API Functions:
+ * H5TBget_buf - Get an ID for a temporary buffer
+ * H5TBbuf_ptr - Get a pointer to the temporary buffer's memory
+ * H5TBresize_buf - Resize a temporary buffer
+ * H5TBgarbage_coll- Free all unused temporary buffers
+ * H5TBrelease_buf - Release temporary buffer
+ *
+ * Modifications:
+ *
+ */
+
+#ifdef RCSID
+static char RcsId[] = "@(#)$Revision$";
+#endif
+
+/* $Id$ */
+
+#include <H5private.h> /* Generic Functions */
+#include <H5Iprivate.h> /* ID Functions */
+#include <H5Eprivate.h> /* Error handling */
+#include <H5MMprivate.h> /* Memory Management functions */
+#include <H5TBprivate.h> /* Temporary buffer info */
+
+/* Interface init/term information */
+#define PABLO_MASK H5TB_mask
+#define INTERFACE_INIT H5TB_init_interface
+static intn interface_initialize_g = FALSE;
+static herr_t H5TB_init_interface(void);
+static void H5TB_term_interface(void);
+
+/* Local information for managing buffers */
+#define H5TB_RESERVED_ATOMS 0
+
+typedef struct tag_H5TB_t {
+ hbool_t inuse; /* Flag to indicate whether the buffer is in use or not */
+ hsize_t size; /* Current size of the buffer */
+ struct tag_H5TB_t *next; /* Pointer to next buffer in list */
+ struct tag_H5TB_t *prev; /* Pointer to previous buffer in list */
+ void *buf; /* Pointer to actual temporary buffer */
+} H5TB_t;
+
+static H5TB_t * H5TB_list_head=NULL; /* pointer to beginning of temp. buffer list (list is in order of increasing size) */
+static H5TB_t * H5TB_list_tail=NULL; /* pointer to end of temp. buffer list */
+
+/* Local functions */
+herr_t H5TB_close(H5TB_t *tb);
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5TB_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5TB_init_interface()
+
+RETURNS
+ SUCCEED/FAIL
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5TB_init_interface(void)
+{
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER(H5TB_init_interface, FAIL);
+
+ /* Initialize the atom group for the file IDs */
+ if ((ret_value = H5I_init_group(H5_TEMPBUF, H5I_TEMPBUFID_HASHSIZE,
+ H5TB_RESERVED_ATOMS, NULL)) != FAIL) {
+ ret_value = H5_add_exit(&H5TB_term_interface);
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TB_term_interface
+ PURPOSE
+ Terminate various H5TB objects
+ USAGE
+ void H5TB_term_interface()
+ RETURNS
+ SUCCEED/FAIL
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static void
+H5TB_term_interface(void)
+{
+ /* Destroy the atom group */
+ /* Step through the list and free the buffers */
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5TB_close
+ *
+ * Purpose: Releases all memory associated with a temporary buffer.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, June 11, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5TB_close(H5TB_t *tb)
+{
+ FUNC_ENTER(H5TB_close, FAIL);
+
+ assert(tb);
+
+
+ /* Release the main structure */
+ H5MM_xfree(tb);
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBget_buf
+ PURPOSE
+ Get an ID for a temporary buffer
+ USAGE
+ hid_t H5TBget_buf(size,resize)
+ hsize_t size; IN: Minimum size of buffer requested
+ hbool_t resize; IN: Whether to resize an existing buffer or get a
+ new buffer if one doesn't match the correct size
+ RETURNS
+ Valid buffer ID on success, negative on failure
+ DESCRIPTION
+ Checks for an available temporary buffer of at least the size requested and
+ returns an ID for an appropriate one. If a buffer of the minimum size
+ requested is not available and the resize flag is set, the smallest buffer
+ available is resized to be the correct size and returned, otherwise a new
+ buffer of the correct size is allocated and returned.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t H5TBget_buf(hsize_t size, hbool_t resize)
+{
+ hid_t ret_value = FAIL;
+ H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */
+ *new; /* pointer to a newly created temp. buffer */
+
+ FUNC_ENTER (H5TBget_buf, FAIL);
+
+ while(curr!=NULL) {
+ if(!curr->inuse && size<curr->size)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Check if we found a block or not */
+ if(curr!=NULL) {
+ curr->inuse=TRUE;
+ } else {
+ if(resize) {
+ curr=H5TB_list_head; /* start at beginning again */
+
+ /* Search for first node which isn't in use */
+ while(curr!=NULL) {
+ if(!curr->inuse)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Mark the buffer in use and resize the buffer */
+ if(curr!=NULL) {
+ void * old_ptr=curr->buf;
+
+ if((curr->buf = H5MM_xrealloc(curr->buf, size))==NULL) {
+ curr->buf=old_ptr; /* restore pointer if no memory available */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+ curr->inuse=TRUE;
+ }
+ } /* end if */
+ } /* end else */
+
+ /* No blocks in the list are acceptable */
+ /* (either too small or not able to be resized) */
+ if(curr==NULL) {
+ if((new=H5MM_xcalloc(1,sizeof(H5TB_t)))==NULL)
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer struct");
+ new->inuse=TRUE;
+ new->size=size;
+ if((new->buf=H5MM_xmalloc(size))==NULL) {
+ H5MM_xfree(new); /* free structure */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+
+ /* Check if this is the first node in the list */
+ if(H5TB_list_head==NULL) {
+ H5TB_list_head=H5TB_list_tail=curr=new;
+ } else {
+ /* Find correct place to insert in list */
+ for(curr=H5TB_list_head; curr!=NULL; curr=curr->next) {
+ /* Found node to insert before */
+ if(curr->size > new->size) {
+ H5TB_t *tmp=curr->prev; /* temporary pointer */
+
+ /* Inserting at head of list */
+ if(tmp==NULL) {
+ H5TB_list_head=new;
+ new->next=curr;
+ curr->prev=new;
+ } else {
+ tmp->next=new;
+ new->prev=tmp;
+ curr->prev=new;
+ new->next=curr;
+ } /* end else */
+
+ /* set this so we can fall through to getting the ID */
+ curr=new;
+ } /* end if */
+ } /* end for */
+
+ /* Add to end of list */
+ if(curr==NULL) {
+ curr=H5TB_list_tail;
+ H5TB_list_tail=curr->next=new;
+ new->prev=curr;
+ } /* end if */
+
+ /* set this so we can fall through to getting the ID */
+ curr=new;
+ } /* end else */
+ } /* end if */
+
+ /* Atomize */
+ if ((ret_value=H5I_register (H5_TEMPBUF, curr))<0) {
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register temp. buffer atom");
+ }
+
+done:
+ if (ret_value < 0) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBget_buf() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBbuf_ptr
+ PURPOSE
+ Get the pointer to a temp. buffer memory
+ USAGE
+ void *H5TBbuf_ptr(tbid)
+ hid_t tbid; IN: Temp. buffer ID
+ RETURNS
+ Non-NULL pointer to buffer memory on success, NULL on failure
+ DESCRIPTION
+ Gets the pointer to a temp. buffer's memory.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+void *H5TBbuf_ptr(hid_t tbid)
+{
+ void *ret_value = NULL;
+ H5TB_t *tbuf; /* Pointer to temporary buffer */
+
+ FUNC_ENTER (H5TBbuf_ptr, NULL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a temp. buffer");
+ }
+
+ ret_value=tbuf->buf;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == NULL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBbuf_ptr() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBresize_ptr
+ PURPOSE
+ Resize a temp. buffer to a new size
+ USAGE
+ herr_t H5TBresize_ptr(tbid, size)
+ hid_t tbid; IN: Temp. buffer ID to resize
+ hsize_t size; IN: New size of temp. buffer
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Resizes a temporary buffer to a new size.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBresize_ptr(hid_t tbid, hsize_t size)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *tbuf, /* Pointer to temporary buffer */
+ *curr; /* Pointer to temp. buffer node */
+ void * old_ptr; /* Pointer to the previous buffer */
+
+ FUNC_ENTER (H5TBresize_ptr, FAIL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
+ }
+
+ /* Save old pointer for later */
+ old_ptr=tbuf->buf;
+
+ /* Try to resize buffer to new size */
+ if((tbuf->buf = H5MM_xrealloc(tbuf->buf, size))==NULL) {
+ tbuf->buf=old_ptr; /* restore pointer if no memory available */
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "unable to allocate space for temporary buffer");
+ }
+
+ /* Change the size of the buffer */
+ tbuf->size=size;
+
+ /*
+ * Check if we need to move the buffer in the sorted list
+ */
+
+ /* Check if this is not the last node and it need's to move */
+ if(tbuf->next!=NULL && tbuf->next->size < tbuf->size) {
+ /* Remove this node from the list */
+ if(tbuf->prev==NULL) { /* remove from head of list */
+ H5TB_list_head=tbuf->next;
+ tbuf->next->prev=NULL;
+ } else { /* remove from middle of list */
+ tbuf->prev->next=tbuf->next;
+ tbuf->next->prev=tbuf->prev;
+ } /* end if */
+
+ /* Find correct position in list */
+ curr=H5TB_list_head;
+ while(curr!=NULL) {
+ if(!curr->inuse && size<curr->size)
+ break;
+ curr=curr->next;
+ } /* end while */
+
+ /* Insert into correct position in list */
+ if(curr!=NULL) { /* can't be adding to the beginning of list, so this is in the middle somewhere */
+ curr->prev->next=tbuf;
+ tbuf->prev=curr->prev;
+ curr->prev=tbuf;
+ tbuf->next=curr;
+ } else { /* append to end of list */
+ H5TB_list_tail->next=tbuf;
+ tbuf->prev=H5TB_list_tail;
+ tbuf->next=NULL;
+ H5TB_list_tail=tbuf;
+ } /* end else */
+ } /* end if */
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBresize_ptr() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBgarbage_coll
+ PURPOSE
+ Release all unused temporary buffers
+ USAGE
+ herr_t H5TBgarbase_coll()
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Steps through the list of temporary buffers, removing unused nodes from the
+ list and freeing their memory
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBgarbage_coll(void)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *curr,*next; /* Current temp. buffer node */
+
+ FUNC_ENTER (H5TBgarbage_coll, FAIL);
+
+ /* Step through the list, remove each unused node, repair the list and free the node */
+ curr=H5TB_list_head;
+ while(curr!=NULL) {
+ next=curr->next;
+ if(!curr->inuse) {
+ /* maintain list head & tail */
+ if(H5TB_list_head==curr)
+ H5TB_list_head=curr->next;
+ if(H5TB_list_tail==curr)
+ H5TB_list_tail=curr->prev;
+
+ /* Delete node from list */
+ if(curr->prev!=NULL)
+ curr->prev->next=curr->next;
+ if(curr->next!=NULL)
+ curr->next->prev=curr->prev;
+
+ /* Free memory for node */
+ if(curr->buf!=NULL)
+ H5MM_xfree(curr->buf);
+ H5MM_xfree(curr);
+ } /* end if */
+ curr=next;
+ } /* end while */
+
+ ret_value=SUCCEED;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBgarbage_coll() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TBrelease_buf
+ PURPOSE
+ Release a temp. buffer back to the list of unused ones.
+ USAGE
+ herr_t H5TBrelease_buf(tbid)
+ hid_t tbid; IN: Temp. buffer ID to release
+ RETURNS
+ non-negative on success, negative on failure
+ DESCRIPTION
+ Releases a temporary buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5TBrelease_buf(hid_t tbid)
+{
+ herr_t ret_value = FAIL;
+ H5TB_t *tbuf; /* Pointer to temporary buffer */
+
+ FUNC_ENTER (H5TBresize_ptr, FAIL);
+
+ if (H5_TEMPBUF != H5I_group(tbid) ||
+ NULL == (tbuf = H5I_object(tbid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
+ }
+
+ /* Release the buffer */
+ tbuf->inuse=FALSE;
+
+ ret_value=SUCCEED;
+
+#ifdef LATER
+done:
+#endif
+ if (ret_value == FAIL) {
+ }
+ FUNC_LEAVE(ret_value);
+} /* H5TBresize_ptr() */
+
diff --git a/src/H5TBprivate.h b/src/H5TBprivate.h
new file mode 100644
index 0000000..2d48b1c
--- /dev/null
+++ b/src/H5TBprivate.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ * This file contains private information about the H5TB module
+ */
+#ifndef _H5TBprivate_H
+#define _H5TBprivate_H
+
+/* Functions defined in H5TB.c */
+hid_t H5TBget_buf(hsize_t size, hbool_t resize);
+void *H5TBbuf_ptr(hid_t tbid);
+herr_t H5TBresize_ptr(hid_t tbid, hsize_t size);
+herr_t H5TBgarbage_coll(void);
+herr_t H5TBrelease_buf(hid_t tbid);
+
+#endif
diff --git a/src/H5V.c b/src/H5V.c
index 88570a5..d11569b 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -410,6 +410,16 @@ H5V_hyper_copy(intn n, const hsize_t *_size,
assert(src_size[i] > 0);
}
#endif
+#ifdef QAK
+{
+ intn i;
+
+ printf("%s: n=%d, _dst=%p, _src=%p\n",FUNC,(int)n,_dst,_src);
+ for(i=0; i<n; i++) {
+ printf("%d: size=%d, dst_size=%d, dst_offset=%d, src_size=%d, src_offset=%d\n",i,(int)size[i],(int)dst_size[i],(int)dst_offset[i],(int)src_size[i],(int)src_offset[i]);
+ } /* end for */
+}
+#endif /* QAK */
/* Copy the size vector so we can modify it */
H5V_vector_cpy(n, size, _size);
@@ -610,3 +620,59 @@ H5V_stride_copy2(hsize_t nelmts, hsize_t elmt_size,
FUNC_LEAVE(SUCCEED);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_array_fill
+ *
+ * Purpose: Fills all bytes of an array with the same value using memset().
+ * Increases amount copied by power of two until the halfway point is
+ * crossed, then copies the rest in one swoop.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, June 18, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5V_array_fill(void *_dst, const void *src, size_t size, size_t count)
+{
+ size_t copy_size; /* size of the buffer to copy */
+ size_t copy_items; /* number of items currently copying */
+ size_t items_left; /* number of items left to copy */
+ uint8 *dst=(uint8 *)_dst; /* alias for pointer arithmetic */
+
+ FUNC_ENTER(H5V_array_fill, FAIL);
+ assert (dst);
+ assert (src);
+ assert (size < MAX_SIZET && size > 0);
+ assert (count < MAX_SIZET && count > 0);
+
+ HDmemcpy(dst, src, size); /* copy first item */
+
+ /* Initialize counters, etc. while compensating for first element copied */
+ copy_size = size;
+ copy_items = 1;
+ items_left = count - 1;
+ dst += size;
+
+ /* copy until we've copied at least half of the items */
+ while (items_left >= copy_items)
+ {
+ HDmemcpy(dst, _dst, copy_size); /* copy the current chunk */
+ dst += copy_size; /* move the offset for the next chunk */
+ items_left -= copy_items; /* decrement the number of items left */
+
+ copy_size *= 2; /* increase the size of the chunk to copy */
+ copy_items *= 2; /* increase the count of items we are copying */
+ } /* end while */
+ if (items_left > 0) /* if there are any items left to copy */
+ HDmemcpy(dst, _dst, items_left * size);
+
+ FUNC_LEAVE(SUCCEED);
+} /* H5V_array_fill() */
diff --git a/src/H5Vprivate.h b/src/H5Vprivate.h
index 64f085a..895a240 100644
--- a/src/H5Vprivate.h
+++ b/src/H5Vprivate.h
@@ -62,6 +62,7 @@ herr_t H5V_stride_optimize1(intn *np, hsize_t *elmt_size, hsize_t *size,
hssize_t *stride1);
herr_t H5V_stride_optimize2(intn *np, hsize_t *elmt_size, hsize_t *size,
hssize_t *stride1, hssize_t *stride2);
+herr_t H5V_array_fill(void *_dst, const void *src, size_t size, size_t count);
/*-------------------------------------------------------------------------
diff --git a/src/H5public.h b/src/H5public.h
index 0f2aebf..6f1eb0b 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -27,7 +27,7 @@
/* Version numbers */
#define H5_VERS_MAJOR 1 /* For major interface changes */
#define H5_VERS_MINOR 0 /* For minor interface changes */
-#define H5_VERS_RELEASE 2 /* For interface tweaks & bug-fixes */
+#define H5_VERS_RELEASE 8 /* For interface tweaks & bug-fixes */
#define H5_VERS_PATCH 0 /* For small groups of bug fixes */
#define H5check() H5vers_check(H5_VERS_MAJOR,H5_VERS_MINOR,\
diff --git a/src/Makefile.in b/src/Makefile.in
index eb054b4..604e347 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -16,11 +16,12 @@ PROGS=debug h5ls h5repart
# Source and object files for the library (lexicographically)...
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \
- H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c \
- H5Fstdio.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c \
- H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \
- H5Olayout.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \
- H5S.c H5Ssimp.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5V.c H5Z.c
+ H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c H5Fstdio.c \
+ H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c \
+ H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Olayout.c H5Oname.c \
+ H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5S.c H5Sall.c \
+ H5Shyper.c H5Spoint.c H5Ssimp.c H5Sselect.c H5T.c H5Tbit.c H5Tconv.c \
+ H5Tinit.c H5TB.c H5V.c H5Z.c
LIB_OBJ=$(LIB_SRC:.c=.o)
@@ -41,8 +42,8 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Ppublic.h \
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
H5Pprivate.h H5Dprivate.h H5Dpkg.h H5Eprivate.h H5Fprivate.h H5Gprivate.h \
H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h \
- H5MMprivate.h H5Oprivate.h H5Sprivate.h H5Tprivate.h H5Tpkg.h \
- H5Vprivate.h H5Zprivate.h
+ H5MMprivate.h H5Oprivate.h H5Sprivate.h H5Tprivate.h H5TBprivate.h \
+ H5Tpkg.h H5Vprivate.h H5Zprivate.h
# Number format detection
H5Tinit.c: H5detect