summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSongyu Lu <songyulu@hdfgroup.org>2019-04-09 23:11:06 (GMT)
committerSongyu Lu <songyulu@hdfgroup.org>2019-04-09 23:11:06 (GMT)
commitc0b13e078e5ee1d15fcf97c64e90c1d07ae285aa (patch)
treec60d511aca2b3450603572084ec1e0cfaeb48170 /src
parent04d07d967a12f6aeeb4fa5bee99526ab328b509a (diff)
parent52276f3713eec584044bc72d4724507848cfeba0 (diff)
downloadhdf5-c0b13e078e5ee1d15fcf97c64e90c1d07ae285aa.zip
hdf5-c0b13e078e5ee1d15fcf97c64e90c1d07ae285aa.tar.gz
hdf5-c0b13e078e5ee1d15fcf97c64e90c1d07ae285aa.tar.bz2
Merge branch 'develop' of https://bitbucket.hdfgroup.org/scm/~songyulu/hdf5_ray into HDFFV-10658-performance-drop-from-1-8
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/H5Dmpio.c3
-rw-r--r--src/H5Dvirtual.c4
-rw-r--r--src/H5P.c19
-rw-r--r--src/H5Pdeprec.c48
-rw-r--r--src/H5Ppublic.h3
-rw-r--r--src/H5Rint.c3
-rw-r--r--src/H5S.c22
-rw-r--r--src/H5Sall.c2
-rw-r--r--src/H5Sdeprec.c121
-rw-r--r--src/H5Shyper.c880
-rw-r--r--src/H5Snone.c2
-rw-r--r--src/H5Spkg.h31
-rw-r--r--src/H5Spoint.c334
-rw-r--r--src/H5Spublic.h12
-rw-r--r--src/H5vers.txt2
-rw-r--r--src/Makefile.am2
17 files changed, 1216 insertions, 273 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5f7bd48..9730436 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -533,6 +533,7 @@ set (H5S_SOURCES
${HDF5_SRC_DIR}/H5S.c
${HDF5_SRC_DIR}/H5Sall.c
${HDF5_SRC_DIR}/H5Sdbg.c
+ ${HDF5_SRC_DIR}/H5Sdeprec.c
${HDF5_SRC_DIR}/H5Shyper.c
${HDF5_SRC_DIR}/H5Smpio.c
${HDF5_SRC_DIR}/H5Snone.c
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index d23cb63..7019362 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -2742,6 +2742,9 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty
if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size")
+ /* Set to latest format for encoding dataspace */
+ H5CX_set_libver_bounds(NULL);
+
if (*local_chunk_array_num_entries)
if (NULL == (send_requests = (MPI_Request *) H5MM_malloc(*local_chunk_array_num_entries * sizeof(MPI_Request))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate send requests buffer")
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index 6c0cfba..d38df1b 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -430,6 +430,10 @@ H5D__virtual_store_layout(H5F_t *f, H5O_layout_t *layout)
/* Create block if # of used entries > 0 */
if(layout->storage.u.virt.list_nused > 0) {
+
+ /* Set the low/high bounds according to 'f' for the API context */
+ H5CX_set_libver_bounds(f);
+
/* Allocate array for caching results of strlen */
if(NULL == (str_size = (size_t *)H5MM_malloc(2 * layout->storage.u.virt.list_nused * sizeof(size_t))))
HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate string length array")
diff --git a/src/H5P.c b/src/H5P.c
index 72d7ae8..09ff7f0 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -817,14 +817,17 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5Pencode
+ H5Pencode2
PURPOSE
- Routine to convert the property values in a property list into a binary buffer
+ Routine to convert the property values in a property list into a binary buffer.
+ The encoding of property values will be done according to the file format
+ setting in fapl_id.
USAGE
- herr_t H5Pencode(plist_id, buf, nalloc)
+ herr_t H5Pencode(plist_id, buf, nalloc, fapl_id)
hid_t plist_id; IN: Identifier to property list to encode
void *buf: OUT: buffer to gold the encoded plist
size_t *nalloc; IN/OUT: size of buffer needed to encode plist
+ hid_t fapl_id; IN: File access property list ID
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
@@ -837,25 +840,29 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Pencode(hid_t plist_id, void *buf, size_t *nalloc)
+H5Pencode2(hid_t plist_id, void *buf, size_t *nalloc, hid_t fapl_id)
{
H5P_genplist_t *plist; /* Property list to query */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_API(FAIL)
- H5TRACE3("e", "i*x*z", plist_id, buf, nalloc);
+ H5TRACE4("e", "i*x*zi", plist_id, buf, nalloc, fapl_id);
/* Check arguments. */
if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+
/* Call the internal encode routine */
if((ret_value = H5P__encode(plist, TRUE, buf, nalloc)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to encode property list");
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Pencode() */
+} /* H5Pencode2() */
/*--------------------------------------------------------------------------
diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c
index 4a63b36..f6c2a3c 100644
--- a/src/H5Pdeprec.c
+++ b/src/H5Pdeprec.c
@@ -486,6 +486,54 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_version() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Pencode1
+ PURPOSE
+ Routine to convert the property values in a property list into a binary buffer
+ USAGE
+ herr_t H5Pencode1(plist_id, buf, nalloc)
+ hid_t plist_id; IN: Identifier to property list to encode
+ void *buf: OUT: buffer to gold the encoded plist
+ size_t *nalloc; IN/OUT: size of buffer needed to encode plist
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Encodes a property list into a binary buffer. If the buffer is NULL, then
+ the call will set the size needed to encode the plist in nalloc. Otherwise
+ the routine will encode the plist in buf.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc)
+{
+ H5P_genplist_t *plist; /* Property list to query */
+ hid_t temp_fapl_id = H5P_DEFAULT;
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x*z", plist_id, buf, nalloc);
+
+ /* Check arguments. */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&temp_fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+
+ /* Call the internal encode routine */
+ if((ret_value = H5P__encode(plist, TRUE, buf, nalloc)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to encode property list");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pencode1() */
+
/*-------------------------------------------------------------------------
* Function: H5Pset_file_space
*
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 078fe74..90e6618 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -236,7 +236,7 @@ H5_DLL herr_t H5Pinsert2(hid_t plist_id, const char *name, size_t size,
H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close);
H5_DLL herr_t H5Pset(hid_t plist_id, const char *name, const void *value);
H5_DLL htri_t H5Pexist(hid_t plist_id, const char *name);
-H5_DLL herr_t H5Pencode(hid_t plist_id, void *buf, size_t *nalloc);
+H5_DLL herr_t H5Pencode2(hid_t plist_id, void *buf, size_t *nalloc, hid_t fapl_id);
H5_DLL hid_t H5Pdecode(const void *buf);
H5_DLL herr_t H5Pget_size(hid_t id, const char *name, size_t *size);
H5_DLL herr_t H5Pget_nprops(hid_t id, size_t *nprops);
@@ -536,6 +536,7 @@ H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size,
void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
H5P_prp_close_func_t prp_close);
+H5_DLL herr_t H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc);
H5_DLL H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter,
unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
unsigned cd_values[]/*out*/, size_t namelen, char name[]);
diff --git a/src/H5Rint.c b/src/H5Rint.c
index a4f76ce..9098a03 100644
--- a/src/H5Rint.c
+++ b/src/H5Rint.c
@@ -215,6 +215,9 @@ H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H
obj_loc.path = &path;
H5G_loc_reset(&obj_loc);
+ /* Set the FAPL for the API context */
+ H5CX_set_libver_bounds(loc->oloc->file);
+
/* Find the object */
if(H5G_loc_find(loc, name, &obj_loc) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found")
diff --git a/src/H5S.c b/src/H5S.c
index 301060f..3926b5f 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -23,6 +23,7 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5CXprivate.h" /* API Contexts */
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
@@ -1487,13 +1488,15 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Sencode
+ * Function: H5Sencode2
*
* Purpose: Given a dataspace ID, converts the object description
* (including selection) into binary in a buffer.
+ * The selection will be encoded according to the file
+ * format setting in fapl.
*
* Return: Success: non-negative
- * Failure: negative
+ * Failure: negative
*
* Programmer: Raymond Lu
* slu@ncsa.uiuc.edu
@@ -1502,24 +1505,29 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Sencode(hid_t obj_id, void *buf, size_t *nalloc)
+H5Sencode2(hid_t obj_id, void *buf, size_t *nalloc, hid_t fapl_id)
{
H5S_t *dspace;
herr_t ret_value=SUCCEED;
FUNC_ENTER_API(FAIL)
- H5TRACE3("e", "i*x*z", obj_id, buf, nalloc);
+ H5TRACE4("e", "i*x*zi", obj_id, buf, nalloc, fapl_id);
/* Check argument and retrieve object */
if(NULL == (dspace = (H5S_t *)H5I_object_verify(obj_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+
if(H5S_encode(dspace, (unsigned char **)&buf, nalloc) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Sencode() */
+} /* H5Sencode2() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 9823d36..7aa9644 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -629,7 +629,7 @@ H5S__all_serialize(const H5S_t *space, uint8_t **p)
/* Store the preamble information */
UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(pp, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(pp, (uint32_t)H5S_ALL_VERSION_1); /* Store the version number */
UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
UINT32ENCODE(pp, (uint32_t)0); /* Store the additional information length */
diff --git a/src/H5Sdeprec.c b/src/H5Sdeprec.c
new file mode 100644
index 0000000..e4ec1b0
--- /dev/null
+++ b/src/H5Sdeprec.c
@@ -0,0 +1,121 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Sdeprec.c
+ *
+ * Purpose: Deprecated functions from the H5S interface. These
+ * functions are here for compatibility purposes and may be
+ * removed in the future. Applications should switch to the
+ * newer APIs.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5Smodule.h" /* This source code file is part of the H5S module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5CXprivate.h" /* API Contexts */
+#include "H5Spkg.h" /* Dataspaces */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+/*-------------------------------------------------------------------------
+ * Function: H5Sencode1
+ *
+ * Purpose: Given a dataspace ID, converts the object description
+ * (including selection) into binary in a buffer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * slu@ncsa.uiuc.edu
+ * July 14, 2004
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Sencode1(hid_t obj_id, void *buf, size_t *nalloc)
+{
+ H5S_t *dspace;
+ hid_t temp_fapl_id = H5P_DEFAULT;
+ herr_t ret_value=SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x*z", obj_id, buf, nalloc);
+
+ /* Check argument and retrieve object */
+ if (NULL == (dspace = (H5S_t *)H5I_object_verify(obj_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&temp_fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+
+ /* Use (earliest, latest) i.e. not latest format */
+ if(H5S_encode(dspace, (unsigned char **)&buf, nalloc)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Sencode1() */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 6d42ec1..a6494d9 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -28,13 +28,14 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
+#include "H5private.h" /* Generic Functions */
+#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* ID Functions */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5Spkg.h" /* Dataspace functions */
-#include "H5VMprivate.h" /* Vector functions */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Spkg.h" /* Dataspace functions */
+#include "H5VMprivate.h" /* Vector functions */
/****************/
@@ -157,6 +158,13 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S__hyper_iter_init,
}};
+/* Format version bounds for dataspace hyperslab selection */
+const unsigned H5O_sds_hyper_ver_bounds[] = {
+ H5S_HYPER_VERSION_1, /* H5F_LIBVER_EARLIEST */
+ H5S_HYPER_VERSION_1, /* H5F_LIBVER_V18 */
+ H5S_HYPER_VERSION_2, /* H5F_LIBVER_V110 */
+ H5S_HYPER_VERSION_3 /* H5F_LIBVER_LATEST */
+};
/*******************/
/* Local Variables */
@@ -3204,8 +3212,9 @@ H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans)
PURPOSE
Get the number of hyperslab blocks in current hyperslab selection
USAGE
- hsize_t H5S__get_select_hyper_nblocks(space)
+ hsize_t H5S__get_select_hyper_nblocks(space, app_ref)
H5S_t *space; IN: Dataspace ptr of selection to query
+ hbool_t app_ref; IN: Whether this is an appl. ref. call
RETURNS
The number of hyperslab blocks in selection on success, negative on failure
DESCRIPTION
@@ -3216,7 +3225,7 @@ H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans)
REVISION LOG
--------------------------------------------------------------------------*/
static hsize_t
-H5S__get_select_hyper_nblocks(const H5S_t *space)
+H5S__get_select_hyper_nblocks(const H5S_t *space, hbool_t app_ref)
{
hsize_t ret_value = 0; /* Return value */
@@ -3231,7 +3240,8 @@ H5S__get_select_hyper_nblocks(const H5S_t *space)
/* Check each dimension */
for(ret_value = 1, u = 0; u < space->extent.rank; u++)
- ret_value *= space->select.sel_info.hslab->app_diminfo[u].count;
+ ret_value *= (app_ref ? space->select.sel_info.hslab->app_diminfo[u].count :
+ space->select.sel_info.hslab->opt_diminfo[u].count);
} /* end if */
else
ret_value = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
@@ -3274,7 +3284,7 @@ H5Sget_select_hyper_nblocks(hid_t spaceid)
if(space->select.sel_info.hslab->unlim_dim >= 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get number of blocks for unlimited selection")
- ret_value = (hssize_t)H5S__get_select_hyper_nblocks(space);
+ ret_value = (hssize_t)H5S__get_select_hyper_nblocks(space, TRUE);
done:
FUNC_LEAVE_API(ret_value)
@@ -3283,6 +3293,210 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S__hyper_get_enc_size_real
+ PURPOSE
+ Determine the size to encode the hyperslab selection info
+ USAGE
+ hssize_t H5S__hyper_get_enc_size_real(max_size, enc_size)
+ hsize_t max_size: IN: The maximum size of the hyperslab selection info
+ unint8_t *enc_size: OUT:The encoding size
+ RETURNS
+ The size to encode hyperslab selection info
+ DESCRIPTION
+ Determine the size by comparing "max_size" with (2^32 - 1) and (2^16 - 1).
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static uint8_t
+H5S__hyper_get_enc_size_real(hsize_t max_size)
+{
+ uint8_t ret_value = H5S_SELECT_INFO_ENC_SIZE_2;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ if(max_size > H5S_UINT32_MAX)
+ ret_value = H5S_SELECT_INFO_ENC_SIZE_8;
+ else if(max_size > H5S_UINT16_MAX)
+ ret_value = H5S_SELECT_INFO_ENC_SIZE_4;
+ else
+ ret_value = H5S_SELECT_INFO_ENC_SIZE_2;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S__hyper_get_enc_size_real() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__hyper_get_version_enc_size
+ PURPOSE
+ Determine the version and encoded size to use for encoding hyperslab selection info
+ USAGE
+ hssize_t H5S__hyper_get_version_enc_size(space, block_count, version, enc_size)
+ const H5S_t *space: IN: The dataspace
+ hsize_t block_count: IN: The number of blocks in the selection
+ uint32_t *version: OUT: The version to use for encoding
+ uint8_t *enc_size: OUT: The encoded size to use
+
+ RETURNS
+ The version and the size to encode hyperslab selection info
+ DESCRIPTION
+ Determine the version to use for encoding hyperslab selection info based
+ on the following:
+ (1) the file format setting in fapl
+ (2) whether the number of blocks or selection high bounds exceeds H5S_UINT32_MAX or not
+
+ Determine the encoded size based on version:
+ For version 3, the encoded size is determined according to:
+ (a) regular hyperslab
+ (1) The maximum needed to store start/stride/count/block
+ (2) Special handling for count/block: need to provide room for H5S_UNLIMITED
+ (b) irregular hyperslab
+ The maximum size needed to store:
+ (1) the number of blocks
+ (2) the selection high bounds
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__hyper_get_version_enc_size(const H5S_t *space, hsize_t block_count, uint32_t *version, uint8_t *enc_size)
+{
+ hsize_t bounds_start[H5S_MAX_RANK]; /* Starting coordinate of bounding box */
+ hsize_t bounds_end[H5S_MAX_RANK]; /* Opposite coordinate of bounding box */
+ hbool_t count_up_version = FALSE; /* Whether number of blocks exceed H5S_UINT32_MAX */
+ hbool_t bound_up_version = FALSE; /* Whether high bounds exceed H5S_UINT32_MAX */
+ H5F_libver_t low_bound; /* The 'low' bound of library format versions */
+ H5F_libver_t high_bound; /* The 'high' bound of library format versions */
+ htri_t is_regular; /* A regular hyperslab or not */
+ uint32_t tmp_version; /* Local temporay version */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Get bounding box for the selection */
+ HDmemset(bounds_end, 0, sizeof(bounds_end));
+
+ if(space->select.sel_info.hslab->unlim_dim < 0) { /* ! H5S_UNLIMITED */
+ /* Get bounding box for the selection */
+ if(H5S__hyper_bounds(space, bounds_start, bounds_end) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds")
+ }
+
+ /* Determine whether the number of blocks or the high bounds in the selection exceed (2^32 - 1) */
+ if(block_count > H5S_UINT32_MAX)
+ count_up_version = TRUE;
+ else {
+ for(u = 0; u < space->extent.rank; u++)
+ if(bounds_end[u] > H5S_UINT32_MAX) {
+ bound_up_version = TRUE;
+ break;
+ }
+ }
+
+ /* Get the file's low_bound and high_bound */
+ if(H5CX_get_libver_bounds(&low_bound, &high_bound) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get low/high bounds from API context")
+
+ /* Determine regular hyperslab */
+ is_regular = H5S__hyper_is_regular(space);
+
+ if(low_bound >= H5F_LIBVER_V112 || space->select.sel_info.hslab->unlim_dim >= 0)
+ tmp_version = MAX(H5S_HYPER_VERSION_2, H5O_sds_hyper_ver_bounds[low_bound]);
+
+ else {
+ if(count_up_version || bound_up_version)
+ tmp_version = is_regular ? H5S_HYPER_VERSION_2 : H5S_HYPER_VERSION_3;
+ else
+ tmp_version = (is_regular && block_count >= 4) ? H5O_sds_hyper_ver_bounds[low_bound] : H5S_HYPER_VERSION_1;
+
+ }
+
+ /* Version bounds check */
+ if(tmp_version > H5O_sds_hyper_ver_bounds[high_bound]) {
+ /* Fail for irregular hyperslab if exceeds 32 bits */
+ if(count_up_version)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "The number of blocks in hyperslab selection exceeds 2^32")
+ else if(bound_up_version)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "The end of bounding box in hyperslab selection exceeds 2^32")
+ else
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "Dataspace hyperslab selection version out of bounds")
+ }
+
+ /* Set the message version */
+ *version = tmp_version;
+
+ /* Determine the encoded size based on version */
+ switch(tmp_version) {
+ case H5S_HYPER_VERSION_1:
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_4;
+ break;
+
+ case H5S_HYPER_VERSION_2:
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_8;
+ break;
+
+ case H5S_HYPER_VERSION_3:
+ if(is_regular) {
+ uint8_t enc1, enc2;
+ hsize_t max1 = 0;
+ hsize_t max2 = 0;
+
+ /* Find max for count[] and block[] */
+ for(u = 0; u < space->extent.rank; u++) {
+ if(space->select.sel_info.hslab->opt_diminfo[u].count != H5S_UNLIMITED &&
+ space->select.sel_info.hslab->opt_diminfo[u].count > max1)
+ max1 = space->select.sel_info.hslab->opt_diminfo[u].count;
+ if(space->select.sel_info.hslab->opt_diminfo[u].block != H5S_UNLIMITED &&
+ space->select.sel_info.hslab->opt_diminfo[u].block > max1)
+ max1 = space->select.sel_info.hslab->opt_diminfo[u].block;
+ }
+
+ /* +1 to provide room for H5S_UNLIMITED */
+ enc1 = H5S__hyper_get_enc_size_real(++max1);
+
+ /* Find max for start[] and stride[] */
+ for(u = 0; u < space->extent.rank; u++) {
+ if(space->select.sel_info.hslab->opt_diminfo[u].start > max2)
+ max2 = space->select.sel_info.hslab->opt_diminfo[u].start;
+ if(space->select.sel_info.hslab->opt_diminfo[u].stride > max2)
+ max2 = space->select.sel_info.hslab->opt_diminfo[u].stride;
+ }
+
+ /* Determine the encoding size */
+ enc2 = H5S__hyper_get_enc_size_real(max2);
+
+ *enc_size = MAX(enc1, enc2);
+ } else {
+ hsize_t max_size = block_count;
+ HDassert(space->select.sel_info.hslab->unlim_dim < 0);
+
+ /* Find max for block_count and bounds_end[] */
+ for(u = 0; u < space->extent.rank; u++)
+ if(bounds_end[u] > max_size)
+ max_size = bounds_end[u];
+
+ /* Determine the encoding size */
+ *enc_size = H5S__hyper_get_enc_size_real(max_size);
+ }
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown hyperslab selection version")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S__hyper_get_version_enc_size() */
+
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S__hyper_serial_size
PURPOSE
Determine the number of bytes needed to store the serialized hyperslab
@@ -3303,49 +3517,73 @@ done:
static hssize_t
H5S__hyper_serial_size(const H5S_t *space)
{
- hsize_t block_count; /* block counter for regular hyperslabs */
- unsigned u; /* Counter */
- hssize_t ret_value = -1; /* return value */
+ hsize_t block_count = 0; /* block counter for regular hyperslabs */
+ uint32_t version; /* Version number */
+ uint8_t enc_size; /* Encoded size of hyerslab selection info */
+ hssize_t ret_value = -1; /* return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_STATIC
HDassert(space);
- /* Check for version (right now, an unlimited dimension is the only thing
- * that would bump the version) */
- if(space->select.sel_info.hslab->unlim_dim >= 0)
+ if(space->select.sel_info.hslab->unlim_dim < 0) /* ! H5S_UNLIMITED */
+ block_count = H5S__get_select_hyper_nblocks(space, FALSE);
+
+ /* Determine the version and the encoded size */
+ if(H5S__hyper_get_version_enc_size(space, block_count, &version, &enc_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't determine hyper version & enc_size")
+
+ if(version == H5S_HYPER_VERSION_3) {
+ /* Version 3: regular */
+ /* Size required is always:
+ * <type (4 bytes)> + <version (4 bytes)> + <flags (1 byte)> +
+ * <size of offset info (1 byte)> + <rank (4 bytes)> +
+ * (4 (start/stride/count/block) * <enc_size> * <rank>) =
+ * 14 + (4 * enc_size * rank) bytes
+ */
+ if(H5S__hyper_is_regular(space))
+ ret_value = (hssize_t)14 +
+ ((hssize_t)4 * (hssize_t)enc_size * (hssize_t)space->extent.rank);
+ else {
+ /* Version 3: irregular */
+ /* Size required is always:
+ * <type (4 bytes)> + <version (4 bytes)> + <flags (1 byte)> +
+ * <size of offset info (1 byte)> + <rank (4 bytes)> +
+ * < # of blocks (depend on enc_size) > +
+ * (2 (starting/ending offset) * <rank> * <enc_size> * <# of blocks) =
+ * = 14 bytes + enc_size (block_count) + (2 * enc_size * rank * block_count) bytes
+ */
+ ret_value = 14 + enc_size;
+ H5_CHECK_OVERFLOW(((unsigned)2 * enc_size * space->extent.rank * block_count), hsize_t, hssize_t);
+ ret_value += (hssize_t)((unsigned)2 * enc_size * space->extent.rank * block_count);
+ }
+ } else if(version == H5S_HYPER_VERSION_2) {
/* Version 2 */
/* Size required is always:
* <type (4 bytes)> + <version (4 bytes)> + <flags (1 byte)> +
* <length (4 bytes)> + <rank (4 bytes)> +
- * (4 (start/stride/count/block) * <rank> * <value (8 bytes)>) =
- * 17 + (4 * rank * 8) bytes
+ * (4 (start/stride/count/block) * <enc_size (8 bytes)> * <rank>) =
+ * 17 + (4 * 8 * rank) bytes
*/
- ret_value = (hssize_t)17 + ((hssize_t)4 * (hssize_t)space->extent.rank
- * (hssize_t)8);
- else {
+ HDassert(enc_size == 8);
+ ret_value = (hssize_t)17 + ((hssize_t)4 * (hssize_t)8 * (hssize_t)space->extent.rank);
+ } else {
+ HDassert(version == H5S_HYPER_VERSION_1);
+ HDassert(enc_size == 4);
/* Version 1 */
/* Basic number of bytes required to serialize hyperslab selection:
* <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
- * <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)>
- * = 24 bytes
+ * <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)> +
+ * (2 (starting/ending offset) * <enc_size (4 bytes)> * <rank> * <# of blocks) =
+ * = 24 bytes + (2 * 4 * rank * block_count)
*/
ret_value = 24;
-
- /* Check for a "regular" hyperslab selection */
- if(space->select.sel_info.hslab->diminfo_valid) {
- /* Check each dimension */
- for(block_count = 1, u = 0; u < space->extent.rank; u++)
- block_count *= space->select.sel_info.hslab->opt_diminfo[u].count;
- } /* end if */
- else
- /* Spin through hyperslab spans, adding 8 * rank bytes for each block */
- block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
-
H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t);
- ret_value += (hssize_t)(8 * block_count * space->extent.rank);
+ ret_value += (hssize_t)(8 * space->extent.rank * block_count);
} /* end else */
+done:
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S__hyper_serial_size() */
@@ -3356,12 +3594,13 @@ H5S__hyper_serial_size(const H5S_t *space)
PURPOSE
Serialize the current selection into a user-provided buffer.
USAGE
- void H5S__hyper_serialize_helper(spans, start, end, rank, buf)
+ void H5S__hyper_serialize_helper(spans, start, end, rank, enc_size, buf)
H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to serialize
hssize_t start[]; IN/OUT: Accumulated start points
hssize_t end[]; IN/OUT: Accumulated end points
hsize_t rank; IN: Current rank looking at
- uint8 *buf; OUT: Buffer to put serialized selection into
+ uint8_t enc_size IN: Encoded size of hyperslab selection info
+ uint8_t *buf; OUT: Buffer to put serialized selection into
RETURNS
None
DESCRIPTION
@@ -3374,7 +3613,7 @@ H5S__hyper_serial_size(const H5S_t *space)
--------------------------------------------------------------------------*/
static void
H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans,
- hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p)
+ hsize_t *start, hsize_t *end, hsize_t rank, uint8_t enc_size, uint8_t **p)
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
uint8_t *pp = (*p); /* Local pointer for decoding */
@@ -3398,26 +3637,65 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans,
end[rank] = curr->high;
/* Recurse down to the next dimension */
- H5S__hyper_serialize_helper(curr->down, start, end, rank + 1, &pp);
+ H5S__hyper_serialize_helper(curr->down, start, end, rank + 1, enc_size, &pp);
} /* end if */
else {
hsize_t u; /* Index variable */
/* Encode all the previous dimensions starting & ending points */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ /* Encode previous starting points */
+ for(u=0; u<rank; u++)
+ UINT16ENCODE(pp, (uint16_t)start[u]);
+
+ /* Encode starting point for this span */
+ UINT16ENCODE(pp, (uint16_t)curr->low);
+
+ /* Encode previous ending points */
+ for(u=0; u<rank; u++)
+ UINT16ENCODE(pp, (uint16_t)end[u]);
+
+ /* Encode starting point for this span */
+ UINT16ENCODE(pp, (uint16_t)curr->high);
+ break;
- /* Encode previous starting points */
- for(u = 0; u < rank; u++)
- UINT32ENCODE(pp, (uint32_t)start[u]);
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ /* Encode previous starting points */
+ for(u=0; u<rank; u++)
+ UINT32ENCODE(pp, (uint32_t)start[u]);
- /* Encode starting point for this span */
- UINT32ENCODE(pp, (uint32_t)curr->low);
+ /* Encode starting point for this span */
+ UINT32ENCODE(pp, (uint32_t)curr->low);
- /* Encode previous ending points */
- for(u = 0; u < rank; u++)
- UINT32ENCODE(pp, (uint32_t)end[u]);
+ /* Encode previous ending points */
+ for(u=0; u<rank; u++)
+ UINT32ENCODE(pp, (uint32_t)end[u]);
+
+ /* Encode starting point for this span */
+ UINT32ENCODE(pp, (uint32_t)curr->high);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ /* Encode previous starting points */
+ for(u=0; u<rank; u++)
+ UINT64ENCODE(pp, (uint64_t)start[u]);
+
+ /* Encode starting point for this span */
+ UINT64ENCODE(pp, (uint64_t)curr->low);
+
+ /* Encode previous ending points */
+ for(u=0; u<rank; u++)
+ UINT64ENCODE(pp, (uint64_t)end[u]);
+
+ /* Encode starting point for this span */
+ UINT64ENCODE(pp, (uint64_t)curr->high);
+ break;
+
+ default:
+ HDassert(0 && "Unknown enc size?!?");
- /* Encode starting point for this span */
- UINT32ENCODE(pp, (uint32_t)curr->high);
+ } /* end switch */
} /* end else */
/* Advance to next node */
@@ -3455,14 +3733,26 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans,
static herr_t
H5S__hyper_serialize(const H5S_t *space, uint8_t **p)
{
- uint8_t *pp; /* Local pointer for encoding */
- uint8_t *lenp; /* Pointer to length location for later storage */
- uint32_t len = 0; /* Number of bytes used */
+ const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */
+ hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */
+ hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */
+ hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */
+ uint8_t *pp; /* Local pointer for decoding */
+ uint8_t *lenp = NULL; /* pointer to length location for later storage */
+ uint32_t len = 0; /* number of bytes used */
uint32_t version; /* Version number */
uint8_t flags = 0; /* Flags for message */
- hsize_t block_count; /* Block counter for regular hyperslabs */
+ hsize_t block_count = 0; /* block counter for regular hyperslabs */
+ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ unsigned ndims; /* Rank of the dataspace */
+ unsigned i, u; /* Local counting variable */
+ hbool_t complete = FALSE; /* Whether we are done with the iteration */
+ hbool_t is_regular; /* Whether selection is regular */
+ uint8_t enc_size;
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(space);
@@ -3470,163 +3760,243 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p)
pp = (*p);
HDassert(pp);
- /* Calculate version */
- if(space->select.sel_info.hslab->unlim_dim >= 0) {
- version = 2;
- flags |= H5S_SELECT_FLAG_UNLIM;
- } /* end if */
- else
- version = 1;
+ /* Set some convienence values */
+ ndims = space->extent.rank;
+ diminfo = space->select.sel_info.hslab->opt_diminfo;
+
+ if(space->select.sel_info.hslab->unlim_dim < 0) /* ! H5S_UNLIMITED */
+ block_count = H5S__get_select_hyper_nblocks(space, FALSE);
+
+ /* Determine the version and the encoded size */
+ if(H5S__hyper_get_version_enc_size(space, block_count, &version, &enc_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't determine hyper version & enc_size")
+
+ is_regular = H5S__hyper_is_regular(space);
+ if(is_regular &&
+ (version == H5S_HYPER_VERSION_2 || version == H5S_HYPER_VERSION_3))
+ flags |= H5S_HYPER_REGULAR;
/* Store the preamble information */
UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
UINT32ENCODE(pp, version); /* Store the version number */
- if(version >= 2)
- *(pp)++ = flags; /* Store the flags */
- else
- UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
- lenp = pp; /* keep the pointer to the length location for later */
- pp += 4; /* skip over space for length */
+
+ if(version >= 3) {
+ *(pp)++ = flags; /* Store the flags */
+ *(pp)++ = enc_size; /* Store size of offset info */
+
+ } else {
+ if(version == 2)
+ *(pp)++ = flags; /* Store the flags */
+ else
+ UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
+ lenp = pp; /* keep the pointer to the length location for later */
+ pp += 4; /* skip over space for length */
+
+ len += 4; /* ndims */
+ }
/* Encode number of dimensions */
- UINT32ENCODE(pp, (uint32_t)space->extent.rank);
- len += 4;
+ UINT32ENCODE(pp, (uint32_t)ndims);
- /* If there is an unlimited dimension, only encode opt_unlim_diminfo */
- if(flags & H5S_SELECT_FLAG_UNLIM) {
- unsigned i;
+ if(is_regular) {
- HDassert(H5S_UNLIMITED == HSIZE_UNDEF);
+ if(version >= H5S_HYPER_VERSION_2) {
+
+ HDassert(H5S_UNLIMITED == HSIZE_UNDEF);
- /* Iterate over dimensions */
- for(i = 0; i < space->extent.rank; i++) {
+ /* Iterate over dimensions */
/* Encode start/stride/block/count */
- UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].start);
- UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].stride);
- UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].count);
- UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].block);
- } /* end for */
- len += (4 * space->extent.rank * 8);
- } /* end if */
- /* Check for a "regular" hyperslab selection */
- else if(space->select.sel_info.hslab->diminfo_valid) {
- const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
- hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */
- hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */
- unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */
- unsigned ndims; /* Rank of the dataspace */
- unsigned u; /* Local counting variable */
- hbool_t done; /* Whether we are done with the iteration */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ HDassert(version == H5S_HYPER_VERSION_3);
+ for(i = 0; i < space->extent.rank; i++) {
+ UINT16ENCODE(pp, diminfo[i].start);
+ UINT16ENCODE(pp, diminfo[i].stride);
+ if(diminfo[i].count == H5S_UNLIMITED) {
+ UINT16ENCODE(pp, H5S_UINT16_MAX);
+ } else {
+ UINT16ENCODE(pp, diminfo[i].count);
+ }
+
+ if(diminfo[i].block == H5S_UNLIMITED) {
+ UINT16ENCODE(pp, H5S_UINT16_MAX);
+ } else {
+ UINT16ENCODE(pp, diminfo[i].block);
+ }
+ } /* end for */
+ break;
- /* Set some convenience values */
- ndims = space->extent.rank;
- fast_dim = ndims - 1;
- diminfo = space->select.sel_info.hslab->opt_diminfo;
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ HDassert(version == H5S_HYPER_VERSION_3);
+ for(i = 0; i < space->extent.rank; i++) {
+ UINT32ENCODE(pp, diminfo[i].start);
+ UINT32ENCODE(pp, diminfo[i].stride);
+ if(diminfo[i].count == H5S_UNLIMITED) {
+ UINT32ENCODE(pp, H5S_UINT32_MAX);
+ } else {
+ UINT32ENCODE(pp, diminfo[i].count);
+ }
+ if(diminfo[i].block == H5S_UNLIMITED) {
+ UINT32ENCODE(pp, H5S_UINT32_MAX);
+ } else {
+ UINT32ENCODE(pp, diminfo[i].block);
+ }
+ } /* end for */
+ break;
- /* Check each dimension */
- for(block_count = 1, u = 0; u < ndims; u++)
- block_count *= diminfo[u].count;
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ HDassert(version == H5S_HYPER_VERSION_2 || version == H5S_HYPER_VERSION_3);
+ for(i = 0; i < space->extent.rank; i++) {
+ UINT64ENCODE(pp, diminfo[i].start);
+ UINT64ENCODE(pp, diminfo[i].stride);
+ if(diminfo[i].count == H5S_UNLIMITED) {
+ UINT64ENCODE(pp, H5S_UINT64_MAX);
+ } else {
+ UINT64ENCODE(pp, diminfo[i].count);
+ }
+ if(diminfo[i].block == H5S_UNLIMITED) {
+ UINT64ENCODE(pp, H5S_UINT64_MAX);
+ } else {
+ UINT64ENCODE(pp, diminfo[i].block);
+ }
+ } /* end for */
+ if(version == H5S_HYPER_VERSION_2)
+ len += (4 * space->extent.rank * 8);
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown offset info size for hyperslab")
+ break;
+ } /* end switch */
- /* Encode number of hyperslabs */
- H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
- UINT32ENCODE(pp, (uint32_t)block_count);
- len += 4;
+ } else {
- /* Now serialize the information for the regular hyperslab */
+ HDassert(version == H5S_HYPER_VERSION_1);
+
+ /* Set some convienence values */
+ fast_dim = ndims - 1;
- /* Build the tables of count sizes as well as the initial offset */
- for(u = 0; u < ndims; u++) {
- tmp_count[u] = diminfo[u].count;
- offset[u] = diminfo[u].start;
- } /* end for */
+ /* Encode number of hyperslabs */
+ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
+ UINT32ENCODE(pp, (uint32_t)block_count);
+ len += 4;
- /* We're not done with the iteration */
- done = FALSE;
+ /* Now serialize the information for the regular hyperslab */
- /* Go iterate over the hyperslabs */
- while(done == FALSE) {
- /* Iterate over the blocks in the fastest dimension */
- while(tmp_count[fast_dim] > 0) {
- /* Add 8 bytes times the rank for each hyperslab selected */
- len += 8 * ndims;
+ /* Build the tables of count sizes as well as the initial offset */
+ for(u = 0; u < ndims; u++) {
+ tmp_count[u] = diminfo[u].count;
+ offset[u] = diminfo[u].start;
+ } /* end for */
- /* Encode hyperslab starting location */
- for(u = 0; u < ndims; u++)
- UINT32ENCODE(pp, (uint32_t)offset[u]);
+ /* Go iterate over the hyperslabs */
+ while(complete == FALSE) {
+ /* Iterate over the blocks in the fastest dimension */
+ while(tmp_count[fast_dim] > 0) {
+ /* Add 8 bytes times the rank for each hyperslab selected */
+ len += 8 * ndims;
- /* Encode hyperslab ending location */
- for(u = 0; u < ndims; u++)
- UINT32ENCODE(pp, (uint32_t)(offset[u] + (diminfo[u].block - 1)));
+ /* Encode hyperslab starting location */
+ for(u = 0; u < ndims; u++)
+ UINT32ENCODE(pp, (uint32_t)offset[u]);
- /* Move the offset to the next sequence to start */
- offset[fast_dim]+=diminfo[fast_dim].stride;
+ /* Encode hyperslab ending location */
+ for(u = 0; u < ndims; u++)
+ UINT32ENCODE(pp, (uint32_t)(offset[u] + (diminfo[u].block - 1)));
- /* Decrement the block count */
- tmp_count[fast_dim]--;
- } /* end while */
+ /* Move the offset to the next sequence to start */
+ offset[fast_dim]+=diminfo[fast_dim].stride;
+
+ /* Decrement the block count */
+ tmp_count[fast_dim]--;
+ } /* end while */
- /* Work on other dimensions if necessary */
- if(fast_dim > 0) {
- int temp_dim; /* Temporary rank holder */
+ /* Work on other dimensions if necessary */
+ if(fast_dim > 0) {
+ int temp_dim; /* Temporary rank holder */
- /* Reset the block counts */
- tmp_count[fast_dim] = diminfo[fast_dim].count;
+ /* Reset the block counts */
+ tmp_count[fast_dim] = diminfo[fast_dim].count;
- /* Bubble up the decrement to the slower changing dimensions */
- temp_dim = (int)fast_dim - 1;
- while(temp_dim >= 0 && done == FALSE) {
- /* Decrement the block count */
- tmp_count[temp_dim]--;
+ /* Bubble up the decrement to the slower changing dimensions */
+ temp_dim = (int)fast_dim - 1;
+ while(temp_dim >= 0 && complete == FALSE) {
+ /* Decrement the block count */
+ tmp_count[temp_dim]--;
- /* Check if we have more blocks left */
- if(tmp_count[temp_dim] > 0)
- break;
+ /* Check if we have more blocks left */
+ if(tmp_count[temp_dim] > 0)
+ break;
- /* Check for getting out of iterator */
- if(temp_dim == 0)
- done = TRUE;
+ /* Check for getting out of iterator */
+ if(temp_dim == 0)
+ complete = TRUE;
- /* Reset the block count in this dimension */
- tmp_count[temp_dim] = diminfo[temp_dim].count;
+ /* Reset the block count in this dimension */
+ tmp_count[temp_dim] = diminfo[temp_dim].count;
- /* Wrapped a dimension, go up to next dimension */
- temp_dim--;
- } /* end while */
- } /* end if */
- else
- break; /* Break out now, for 1-D selections */
+ /* Wrapped a dimension, go up to next dimension */
+ temp_dim--;
+ } /* end while */
+ } /* end if */
+ else
+ break; /* Break out now, for 1-D selections */
- /* Re-compute offset array */
- for(u = 0; u < ndims; u++)
- offset[u] = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]);
- } /* end while */
- } /* end if */
- else {
- hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */
- hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */
+ /* Re-compute offset array */
+ for(u = 0; u < ndims; u++)
+ offset[u] = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]);
+ } /* end while */
+
+ } /* end else */
+
+ } else { /* irregular */
/* Encode number of hyperslabs */
- block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
- H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
- UINT32ENCODE(pp, (uint32_t)block_count);
- len += 4;
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ HDassert(version == H5S_HYPER_VERSION_3);
+ H5_CHECK_OVERFLOW(block_count, hsize_t, uint16_t);
+ UINT16ENCODE(pp, (uint16_t)block_count);
+ break;
- /* Add 8 bytes times the rank for each hyperslab selected */
- H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t);
- len += (uint32_t)(8 * space->extent.rank * block_count);
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ HDassert(version == H5S_HYPER_VERSION_1 || version == H5S_HYPER_VERSION_3);
+ H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
+ UINT32ENCODE(pp, (uint32_t)block_count);
+ break;
- /* Encode each hyperslab in selection */
- H5S__hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &pp);
- } /* end else */
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ HDassert(version == H5S_HYPER_VERSION_3);
+ UINT64ENCODE(pp, block_count);
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown offset info size for hyperslab")
+ break;
+ } /* end switch */
+
+ if(version == H5S_HYPER_VERSION_1) {
+ len+=4; /* block_count */
+
+ /* Add 8 bytes times the rank for each hyperslab selected */
+ H5_CHECK_OVERFLOW((8 * ndims * block_count), hsize_t, size_t);
+ len += (uint32_t)(8 * ndims * block_count);
+ }
+
+ H5S__hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, enc_size, &pp);
+
+ }
/* Encode length */
- UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
+ if(version <= H5S_HYPER_VERSION_2)
+ UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
/* Update encoding pointer */
*p = pp;
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S__hyper_serialize() */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S__hyper_serialize() */
+
/*--------------------------------------------------------------------------
@@ -3657,14 +4027,15 @@ H5S__hyper_deserialize(H5S_t **space, const uint8_t **p)
H5S_t *tmp_space = NULL; /* Pointer to actual dataspace to use,
either *space or a newly allocated one */
hsize_t dims[H5S_MAX_RANK]; /* Dimenion sizes */
- hsize_t start[H5S_MAX_RANK]; /* Hyperslab start information */
- hsize_t block[H5S_MAX_RANK]; /* Hyperslab block information */
+ hsize_t start[H5S_MAX_RANK]; /* hyperslab start information */
+ hsize_t block[H5S_MAX_RANK]; /* hyperslab block information */
uint32_t version; /* Version number */
uint8_t flags = 0; /* Flags */
- unsigned rank; /* Rank of points */
+ uint8_t enc_size = 0; /* Encoded size of selection info */
+ unsigned rank; /* rank of points */
const uint8_t *pp; /* Local pointer for decoding */
- unsigned u; /* Local counting variable */
- herr_t ret_value = FAIL; /* Return value */
+ unsigned u; /* Local counting variable */
+ herr_t ret_value=FAIL; /* return value */
FUNC_ENTER_STATIC
@@ -3688,15 +4059,31 @@ H5S__hyper_deserialize(H5S_t **space, const uint8_t **p)
/* Decode version */
UINT32DECODE(pp, version);
- if(version >= (uint32_t)2) {
+ if(version >= (uint32_t)H5S_HYPER_VERSION_2) {
/* Decode flags */
flags = *(pp)++;
- /* Skip over the remainder of the header */
- pp += 4;
- } else
+ if(version >= (uint32_t)H5S_HYPER_VERSION_3)
+ /* decode size of offset info */
+ enc_size = *(pp)++;
+ else {
+ /* Skip over the remainder of the header */
+ pp += 4;
+ enc_size = H5S_SELECT_INFO_ENC_SIZE_8;
+ }
+
+ /* Check for unknown flags */
+ if(flags & ~H5S_SELECT_FLAG_BITS)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "unknown flag for selection")
+ } else {
/* Skip over the remainder of the header */
pp += 8;
+ enc_size = H5S_SELECT_INFO_ENC_SIZE_4;
+ }
+
+ /* Check encoded */
+ if(enc_size & ~H5S_SELECT_INFO_ENC_SIZE_BITS)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "unknown size of point/offset info for selection")
/* Decode the rank of the point selection */
UINT32DECODE(pp,rank);
@@ -3712,24 +4099,66 @@ H5S__hyper_deserialize(H5S_t **space, const uint8_t **p)
if(rank != tmp_space->extent.rank)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of serialized selection does not match dataspace")
- /* If there is an unlimited dimension, only encode opt_unlim_diminfo */
- if(flags & H5S_SELECT_FLAG_UNLIM) {
+ if(flags & H5S_HYPER_REGULAR) {
hsize_t stride[H5S_MAX_RANK]; /* Hyperslab stride information */
- hsize_t count[H5S_MAX_RANK]; /* Hyperslab count information */
+ hsize_t count[H5S_MAX_RANK]; /* Hyperslab count information */
/* Sanity checks */
HDassert(H5S_UNLIMITED == HSIZE_UNDEF);
HDassert(version >= 2);
- /* Iterate over dimensions */
- for(u = 0; u < rank; u++) {
- /* Decode start/stride/block/count */
- UINT64DECODE(pp, start[u]);
- UINT64DECODE(pp, stride[u]);
- UINT64DECODE(pp, count[u]);
- UINT64DECODE(pp, block[u]);
- } /* end for */
+ /* Decode start/stride/block/count */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ for(u = 0; u < tmp_space->extent.rank; u++) {
+ UINT16DECODE(pp, start[u]);
+ UINT16DECODE(pp, stride[u]);
+
+ UINT16DECODE(pp, count[u]);
+ if((uint16_t)count[u] == H5S_UINT16_MAX)
+ count[u] = H5S_UNLIMITED;
+
+ UINT16DECODE(pp, block[u]);
+ if((uint16_t)block[u] == H5S_UINT16_MAX)
+ block[u] = H5S_UNLIMITED;
+ } /* end for */
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ for(u = 0; u < tmp_space->extent.rank; u++) {
+ UINT32DECODE(pp, start[u]);
+ UINT32DECODE(pp, stride[u]);
+
+ UINT32DECODE(pp, count[u]);
+ if((uint32_t)count[u] == H5S_UINT32_MAX)
+ count[u] = H5S_UNLIMITED;
+
+ UINT32DECODE(pp, block[u]);
+ if((uint32_t)block[u] == H5S_UINT32_MAX)
+ block[u] = H5S_UNLIMITED;
+ } /* end for */
+ break;
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ for(u = 0; u < tmp_space->extent.rank; u++) {
+ UINT64DECODE(pp, start[u]);
+ UINT64DECODE(pp, stride[u]);
+
+ UINT64DECODE(pp, count[u]);
+ if((uint64_t)count[u] == H5S_UINT64_MAX)
+ count[u] = H5S_UNLIMITED;
+
+ UINT64DECODE(pp, block[u]);
+ if((uint64_t)block[u] == H5S_UINT64_MAX)
+ block[u] = H5S_UNLIMITED;
+ } /* end for */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown offset info size for hyperslab")
+ break;
+ } /* end switch */
+
/* Select the hyperslab to the current selection */
if((ret_value = H5S_select_hyperslab(tmp_space, H5S_SELECT_SET, start, stride, count, block)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't change selection")
@@ -3737,28 +4166,65 @@ H5S__hyper_deserialize(H5S_t **space, const uint8_t **p)
else {
const hsize_t *stride; /* Hyperslab stride information */
const hsize_t *count; /* Hyperslab count information */
- hsize_t end[H5S_MAX_RANK]; /* Hyperslab end information */
- hsize_t *tstart; /* Temporary hyperslab pointers */
- hsize_t *tend; /* Temporary hyperslab pointers */
- hsize_t *tblock; /* Temporary hyperslab pointers */
- size_t block_count; /* Number of blocks in selection */
- unsigned v; /* Local counting variable */
+ hsize_t end[H5S_MAX_RANK]; /* Hyperslab end information */
+ hsize_t *tstart; /* Temporary hyperslab pointers */
+ hsize_t *tend; /* Temporary hyperslab pointers */
+ hsize_t *tblock; /* Temporary hyperslab pointers */
+ size_t num_elem; /* Number of elements in selection */
+ unsigned v; /* Local counting variable */
+
+ /* decode the number of blocks */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ UINT16DECODE(pp, num_elem);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ UINT32DECODE(pp, num_elem);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ UINT64DECODE(pp, num_elem);
+ break;
- /* Decode the number of blocks */
- UINT32DECODE(pp, block_count);
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown offset info size for hyperslab")
+ break;
+ }
/* Set the count & stride for all blocks */
stride = count = H5S_hyper_ones_g;
/* Retrieve the coordinates from the buffer */
- for(u = 0; u < block_count; u++) {
- /* Decode the starting points */
- for(tstart = start, v = 0; v < rank; v++, tstart++)
- UINT32DECODE(pp, *tstart);
-
- /* Decode the ending points */
- for(tend = end, v = 0; v < rank; v++, tend++)
- UINT32DECODE(pp, *tend);
+ for(u = 0; u < num_elem; u++) {
+
+ /* Decode the starting and ending points */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ for(tstart = start, v = 0; v < rank; v++, tstart++)
+ UINT16DECODE(pp, *tstart);
+ for(tend = end, v = 0; v < rank; v++, tend++)
+ UINT16DECODE(pp, *tend);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ for(tstart = start,v = 0; v < rank; v++, tstart++)
+ UINT32DECODE(pp, *tstart);
+ for(tend = end, v = 0; v < rank; v++, tend++)
+ UINT32DECODE(pp, *tend);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ for(tstart = start, v = 0; v < rank; v++, tstart++)
+ UINT64DECODE(pp, *tstart);
+ for(tend = end, v = 0; v < rank; v++, tend++)
+ UINT64DECODE(pp, *tend);
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown offset info size for hyperslab")
+ break;
+ }
/* Change the ending points into blocks */
for(tblock = block, tstart = start, tend = end, v = 0; v < rank; v++, tstart++, tend++, tblock++)
diff --git a/src/H5Snone.c b/src/H5Snone.c
index cae9a67..6219bb1 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -583,7 +583,7 @@ H5S__none_serialize(const H5S_t *space, uint8_t **p)
/* Store the preamble information */
UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(pp, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(pp, (uint32_t)H5S_NONE_VERSION_1); /* Store the version number */
UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
UINT32ENCODE(pp, (uint32_t)0); /* Store the additional information length */
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 2918648..56b1f30 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -37,8 +37,35 @@
#define H5S_VALID_PERM 0x02
/* Flags for serialization of selections */
-#define H5S_SELECT_FLAG_UNLIM 0x01
-#define H5S_SELECT_FLAG_BITS (H5S_SELECT_FLAG_UNLIM)
+#define H5S_HYPER_REGULAR 0x01
+#define H5S_SELECT_FLAG_BITS (H5S_HYPER_REGULAR)
+
+/* Versions for H5S_SEL_HYPER selection info */
+#define H5S_HYPER_VERSION_1 1
+#define H5S_HYPER_VERSION_2 2
+#define H5S_HYPER_VERSION_3 3
+
+/* Versions for H5S_SEL_POINTS selection info */
+#define H5S_POINT_VERSION_1 1
+#define H5S_POINT_VERSION_2 2
+
+/* Versions for H5S_SEL_NONE selection info */
+#define H5S_NONE_VERSION_1 1
+
+/* Versions for H5S_SEL_ALL selection info */
+#define H5S_ALL_VERSION_1 1
+
+/* Encoded size of selection info for H5S_SEL_POINTS/H5S_SEL_HYPER */
+#define H5S_SELECT_INFO_ENC_SIZE_2 0x02 /* 2 bytes: 16 bits */
+#define H5S_SELECT_INFO_ENC_SIZE_4 0x04 /* 4 bytes: 32 bits */
+#define H5S_SELECT_INFO_ENC_SIZE_8 0x08 /* 8 bytes: 64 bits */
+#define H5S_SELECT_INFO_ENC_SIZE_BITS ( H5S_SELECT_INFO_ENC_SIZE_2 | \
+ H5S_SELECT_INFO_ENC_SIZE_4 | \
+ H5S_SELECT_INFO_ENC_SIZE_8 )
+
+#define H5S_UINT16_MAX 0x0000FFFF /* 2^16 - 1 = 65,535 */
+#define H5S_UINT32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4,294,967,295 */
+#define H5S_UINT64_MAX ((hsize_t)(-1L)) /* 2^64 - 1 = 18,446,744,073,709,551,615 */
/* Length of stack-allocated sequences for "project intersect" routines */
#define H5S_PROJECT_INTERSECT_NSEQS 256
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index ac9c983..0bdabb4 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -28,13 +28,14 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
+#include "H5private.h" /* Generic Functions */
+#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
-#include "H5Iprivate.h" /* ID Functions */
-#include "H5MMprivate.h" /* Memory management */
-#include "H5Spkg.h" /* Dataspace functions */
-#include "H5VMprivate.h" /* Vector functions */
+#include "H5Iprivate.h" /* ID Functions */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Spkg.h" /* Dataspace functions */
+#include "H5VMprivate.h" /* Vector functions */
/****************/
@@ -72,6 +73,8 @@ static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space,
hsize_t *offset);
static herr_t H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
+static herr_t
+ H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *enc_size);
/* Selection iteration callbacks */
static herr_t H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
@@ -118,6 +121,13 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S__point_iter_init,
}};
+/* Format version bounds for dataspace hyperslab selection */
+const unsigned H5O_sds_point_ver_bounds[] = {
+ H5S_POINT_VERSION_1, /* H5F_LIBVER_EARLIEST */
+ H5S_POINT_VERSION_1, /* H5F_LIBVER_V18 */
+ H5S_POINT_VERSION_1, /* H5F_LIBVER_V110 */
+ H5S_POINT_VERSION_2 /* H5F_LIBVER_LATEST */
+};
/*******************/
/* Local Variables */
@@ -919,6 +929,124 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Sget_select_elem_npoints() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__point_get_version_enc_size
+ PURPOSE
+ Determine the version and the size (2, 4 or 8 bytes) to encode point selection info
+ USAGE
+ hssize_t H5S__point_set_enc_size(space, version, enc_size)
+ const H5S_t *space: IN: Dataspace ID of selection to query
+ uint32_t *version: OUT: The version to use for encoding
+ uint8_t *enc_size: OUT: The size to use for encoding
+ RETURNS
+ The version and the size to encode point selection info
+ DESCRIPTION
+ Determine the version to use for encoding points selection info based
+ on the following:
+ (1) the low/high bounds setting in fapl
+ (2) whether the number of points or selection high bounds exceeds H5S_UINT32_MAX or not
+
+ Determine the encoded size based on version:
+ --For version 2, the encoded size of point selection info is determined
+ by the maximum size for:
+ (a) storing the number of points
+ (b) storing the selection high bounds
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *enc_size)
+{
+ hbool_t count_up_version = FALSE; /* Whether number of points exceed H5S_UINT32_MAX */
+ hbool_t bound_up_version = FALSE; /* Whether high bounds exceed H5S_UINT32_MAX */
+ H5F_libver_t low_bound; /* The 'low' bound of library format versions */
+ H5F_libver_t high_bound; /* The 'high' bound of library format versions */
+ uint32_t tmp_version; /* Local temporary version */
+ hsize_t bounds_start[H5S_MAX_RANK]; /* Starting coordinate of bounding box */
+ hsize_t bounds_end[H5S_MAX_RANK]; /* Opposite coordinate of bounding box */
+ hsize_t max_size = 0; /* Maximum selection size */
+ unsigned u; /* Local index veriable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Get bounding box for the selection */
+ HDmemset(bounds_end, 0, sizeof(bounds_end));
+ if(H5S__point_bounds(space, bounds_start, bounds_end) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds")
+
+ /* Determine whether number of points or high bounds exceeds (2^32 - 1) */
+ if(space->select.num_elem > H5S_UINT32_MAX)
+ count_up_version = TRUE;
+ else {
+ for(u = 0; u < space->extent.rank; u++)
+ if(bounds_end[u] > H5S_UINT32_MAX) {
+ bound_up_version = TRUE;
+ break;
+ }
+ }
+
+ /* If exceed (2^32 -1) */
+ if(count_up_version || bound_up_version)
+ tmp_version = H5S_POINT_VERSION_2;
+ else
+ tmp_version = H5S_POINT_VERSION_1;
+
+ /* Get the file's low/high bounds */
+ if(H5CX_get_libver_bounds(&low_bound, &high_bound) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get low/high bounds from API context")
+
+ /* Upgrade to the version indicated by the file's low bound if higher */
+ tmp_version = MAX(tmp_version, H5O_sds_point_ver_bounds[low_bound]);
+
+ /* Version bounds check */
+ if(tmp_version > H5O_sds_point_ver_bounds[high_bound]) {
+ if(count_up_version)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "The number of points in point selection exceeds 2^32")
+ else if(bound_up_version)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "The end of bounding box in point selection exceeds 2^32")
+ else
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "Dataspace point selection version out of bounds")
+ }
+
+ /* Set the version to return */
+ *version = tmp_version;
+
+ /* Get the encoded size use based on version */
+ switch(tmp_version) {
+ case H5S_POINT_VERSION_1:
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_4;
+ break;
+
+ case H5S_POINT_VERSION_2:
+ /* Find max for num_elem and bounds_end[] */
+ max_size = space->select.num_elem;
+ for(u = 0; u < space->extent.rank; u++)
+ if(bounds_end[u] > max_size)
+ max_size = bounds_end[u];
+
+ /* Determine the encoding size */
+ if(max_size > H5S_UINT32_MAX)
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_8;
+ else if(max_size > H5S_UINT16_MAX)
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_4;
+ else
+ *enc_size = H5S_SELECT_INFO_ENC_SIZE_2;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown point info size")
+ break;
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S__point_get_version_enc_size() */
+
/*--------------------------------------------------------------------------
NAME
@@ -942,22 +1070,39 @@ done:
static hssize_t
H5S__point_serial_size(const H5S_t *space)
{
+ uint32_t version; /* Version number */
+ uint8_t enc_size; /* Encoded size of point selection info */
hssize_t ret_value = -1; /* Return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_STATIC
HDassert(space);
- /* Basic number of bytes required to serialize point selection:
- * <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
- * <length (4 bytes)> + <rank (4 bytes)> + <# of points (4 bytes)> = 24 bytes
- */
- ret_value = 24;
+ /* Determine the version and encoded size for point selection */
+ if(H5S__point_get_version_enc_size(space, &version, &enc_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't determine hyper version")
+
+ /* Basic number of bytes required to serialize point selection: */
+ if(version >= H5S_POINT_VERSION_2)
+ /*
+ * <type (4 bytes)> + <version (4 bytes)> +
+ * <size of point info (1 byte)> + rank (4 bytes)>
+ */
+ ret_value=13;
+ else
+ /*
+ * <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
+ * <length (4 bytes)> + <rank (4 bytes)>
+ */
+ ret_value = 20;
+
+ /* <num points (depend on enc_size)> */
+ ret_value += enc_size;
/* Count points in selection */
- /* (Add 4 bytes times the rank for each element selected) */
- ret_value += (4 * space->extent.rank) * (hssize_t)H5S_GET_SELECT_NPOINTS(space);
+ ret_value += (hssize_t) (enc_size * space->extent.rank * space->select.num_elem);
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S__point_serial_size() */
@@ -987,12 +1132,15 @@ static herr_t
H5S__point_serialize(const H5S_t *space, uint8_t **p)
{
H5S_pnt_node_t *curr; /* Point information nodes */
- uint8_t *pp; /* Local pointer for encoding */
- uint8_t *lenp; /* Pointer to length location for later storage */
- uint32_t len = 0; /* Number of bytes used */
- unsigned u; /* Local counting variable */
+ uint8_t *pp; /* Local pointer for decoding */
+ uint8_t *lenp = NULL; /* pointer to length location for later storage */
+ uint32_t len=0; /* number of bytes used */
+ unsigned u; /* local counting variable */
+ uint32_t version; /* Version number */
+ uint8_t enc_size; /* Encoded size of point selection info */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC_NOERR
+ FUNC_ENTER_STATIC
/* Check args */
HDassert(space);
@@ -1000,42 +1148,96 @@ H5S__point_serialize(const H5S_t *space, uint8_t **p)
pp = (*p);
HDassert(pp);
+ /* Determine the version and encoded size for point selection info */
+ if(H5S__point_get_version_enc_size(space, &version, &enc_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't determine hyper version")
+
/* Store the preamble information */
UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(pp, (uint32_t)1); /* Store the version number */
- UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
- lenp = pp; /* Keep the pointer to the length location for later */
- pp += 4; /* Skip over space for length */
+
+ UINT32ENCODE(pp, version); /* Store the version number */
+ if(version >= 2) {
+ *(pp)++ = enc_size; /* Store size of point info */
+ } else {
+ HDassert(version == H5S_POINT_VERSION_1);
+ UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */
+ lenp = pp; /* Keep the pointer to the length location for later */
+ pp += 4; /* Skip over space for length */
+ len += 8; /* Add in advance # of bytes for num of dimensions and num elements */
+ }
/* Encode number of dimensions */
UINT32ENCODE(pp, (uint32_t)space->extent.rank);
- len += 4;
- /* Encode number of elements */
- UINT32ENCODE(pp, (uint32_t)space->select.num_elem);
- len += 4;
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ HDassert(version == H5S_POINT_VERSION_2);
+
+ /* Encode number of elements */
+ UINT16ENCODE(pp, (uint16_t)space->select.num_elem);
+
+ /* Encode each point in selection */
+ curr=space->select.sel_info.pnt_lst->head;
+ while(curr!=NULL) {
+ /* Encode each point */
+ for(u=0; u<space->extent.rank; u++)
+ UINT16ENCODE(pp, (uint16_t)curr->pnt[u]);
+ curr=curr->next;
+ } /* end while */
+ break;
- /* Encode each point in selection */
- curr = space->select.sel_info.pnt_lst->head;
- while(curr != NULL) {
- /* Add 4 bytes times the rank for each element selected */
- len += 4 * space->extent.rank;
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ HDassert(version == H5S_POINT_VERSION_1 || version == H5S_POINT_VERSION_2);
- /* Encode each point */
- for(u = 0; u < space->extent.rank; u++)
- UINT32ENCODE(pp, (uint32_t)curr->pnt[u]);
+ /* Encode number of elements */
+ UINT32ENCODE(pp, (uint32_t)space->select.num_elem);
- curr = curr->next;
- } /* end while */
+ /* Encode each point in selection */
+ curr=space->select.sel_info.pnt_lst->head;
+ while(curr!=NULL) {
+ /* Encode each point */
+ for(u=0; u<space->extent.rank; u++)
+ UINT32ENCODE(pp, (uint32_t)curr->pnt[u]);
+ curr=curr->next;
+ } /* end while */
+
+ /* Add 4 bytes times the rank for each element selected */
+ if(version == H5S_POINT_VERSION_1)
+ len += (uint32_t)space->select.num_elem * 4 * space->extent.rank;
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ HDassert(version == H5S_POINT_VERSION_2);
+
+ /* Encode number of elements */
+ UINT64ENCODE(pp, space->select.num_elem);
+
+ /* Encode each point in selection */
+ curr=space->select.sel_info.pnt_lst->head;
+ while(curr!=NULL) {
+ /* Encode each point */
+ for(u=0; u<space->extent.rank; u++)
+ UINT64ENCODE(pp, curr->pnt[u]);
+ curr=curr->next;
+ } /* end while */
+ break;
- /* Encode length */
- UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown point info size")
+ break;
+
+ } /* end switch */
+
+ if(version == H5S_POINT_VERSION_1)
+ UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
/* Update encoding pointer */
*p = pp;
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S__point_serialize() */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S__point_serialize() */
+
/*--------------------------------------------------------------------------
@@ -1067,9 +1269,10 @@ H5S__point_deserialize(H5S_t **space, const uint8_t **p)
either *space or a newly allocated one */
hsize_t dims[H5S_MAX_RANK]; /* Dimension sizes */
uint32_t version; /* Version number */
+ uint8_t enc_size = 0; /* Encoded size of selection info */
hsize_t *coord = NULL, *tcoord; /* Pointer to array of elements */
const uint8_t *pp; /* Local pointer for decoding */
- size_t num_elem = 0; /* Number of elements in selection */
+ uint64_t num_elem = 0; /* Number of elements in selection */
unsigned rank; /* Rank of points */
unsigned i, j; /* local counting variables */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1096,8 +1299,18 @@ H5S__point_deserialize(H5S_t **space, const uint8_t **p)
/* Decode version */
UINT32DECODE(pp, version);
- /* Skip over the remainder of the header */
- pp += 8;
+ if(version >= (uint32_t)H5S_POINT_VERSION_2)
+ /* Decode size of point info */
+ enc_size = *(pp)++;
+ else {
+ /* Skip over the remainder of the header */
+ pp += 8;
+ enc_size = H5S_SELECT_INFO_ENC_SIZE_4;
+ }
+
+ /* Check encoded size */
+ if(enc_size & ~H5S_SELECT_INFO_ENC_SIZE_BITS)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "unknown size of point/offset info for selection")
/* Decode the rank of the point selection */
UINT32DECODE(pp,rank);
@@ -1113,8 +1326,22 @@ H5S__point_deserialize(H5S_t **space, const uint8_t **p)
if(rank != tmp_space->extent.rank)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of serialized selection does not match dataspace")
- /* Deserialize points to select */
- UINT32DECODE(pp, num_elem); /* decode the number of points */
+ /* decode the number of points */
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ UINT16DECODE(pp, num_elem);
+ break;
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ UINT32DECODE(pp, num_elem);
+ break;
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ UINT64DECODE(pp, num_elem);
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown point info size")
+ break;
+ } /* end switch */
+
/* Allocate space for the coordinates */
if(NULL == (coord = (hsize_t *)H5MM_malloc(num_elem * rank * sizeof(hsize_t))))
@@ -1123,7 +1350,22 @@ H5S__point_deserialize(H5S_t **space, const uint8_t **p)
/* Retrieve the coordinates from the buffer */
for(tcoord = coord, i = 0; i < num_elem; i++)
for(j = 0; j < (unsigned)rank; j++, tcoord++)
- UINT32DECODE(pp, *tcoord);
+ switch(enc_size) {
+ case H5S_SELECT_INFO_ENC_SIZE_2:
+ UINT16DECODE(pp, *tcoord);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_4:
+ UINT32DECODE(pp, *tcoord);
+ break;
+
+ case H5S_SELECT_INFO_ENC_SIZE_8:
+ UINT64DECODE(pp, *tcoord);
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unknown point info size")
+ break;
+ } /* end switch */
/* Select points */
if(H5S_select_elements(tmp_space, H5S_SELECT_SET, num_elem, (const hsize_t *)coord) < 0)
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 561875a..c01beca 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -97,7 +97,7 @@ H5_DLL herr_t H5Sset_extent_simple(hid_t space_id, int rank,
const hsize_t dims[], const hsize_t max[]);
H5_DLL hid_t H5Scopy(hid_t space_id);
H5_DLL herr_t H5Sclose(hid_t space_id);
-H5_DLL herr_t H5Sencode(hid_t obj_id, void *buf, size_t *nalloc);
+H5_DLL herr_t H5Sencode2(hid_t obj_id, void *buf, size_t *nalloc, hid_t fapl);
H5_DLL hid_t H5Sdecode(const void *buf);
H5_DLL hssize_t H5Sget_simple_extent_npoints(hid_t space_id);
H5_DLL int H5Sget_simple_extent_ndims(hid_t space_id);
@@ -134,6 +134,16 @@ H5_DLL hssize_t H5Sget_select_hyper_nblocks(hid_t spaceid);
H5_DLL herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
hsize_t numblocks, hsize_t buf[/*numblocks*/]);
+/* Symbols defined for compatibility with previous versions of the HDF5 API.
+ *
+ * Use of these symbols is deprecated.
+ */
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+/* Function prototypes */
+H5_DLL herr_t H5Sencode1(hid_t obj_id, void *buf, size_t *nalloc);
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5vers.txt b/src/H5vers.txt
index 914c30e..22117c3 100644
--- a/src/H5vers.txt
+++ b/src/H5vers.txt
@@ -61,12 +61,14 @@ FUNCTION: H5Oget_info_by_name; ; v18, v112
FUNCTION: H5Oget_info_by_idx; ; v18, v112
FUNCTION: H5Ovisit; ; v18, v112
FUNCTION: H5Ovisit_by_name; ; v18, v112
+FUNCTION: H5Pencode; ; v110, v112
FUNCTION: H5Pget_filter; ; v10, v18
FUNCTION: H5Pget_filter_by_id; ; v16, v18
FUNCTION: H5Pinsert; ; v14, v18
FUNCTION: H5Pregister; ; v14, v18
FUNCTION: H5Rdereference; ; v10, v110
FUNCTION: H5Rget_obj_type; ; v16, v18
+FUNCTION: H5Sencode; ; v18, v112
FUNCTION: H5Tarray_create; ; v14, v18
FUNCTION: H5Tcommit; ; v10, v18
FUNCTION: H5Tget_array_dims; ; v14, v18
diff --git a/src/Makefile.am b/src/Makefile.am
index 5532655..378e390 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -102,7 +102,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5R.c H5Rint.c H5Rdeprec.c \
H5UC.c \
H5RS.c \
- H5S.c H5Sall.c H5Sdbg.c H5Shyper.c H5Snone.c H5Spoint.c \
+ H5S.c H5Sall.c H5Sdbg.c H5Sdeprec.c H5Shyper.c H5Snone.c H5Spoint.c \
H5Sselect.c H5Stest.c \
H5SL.c \
H5SM.c H5SMbtree2.c H5SMcache.c H5SMmessage.c H5SMtest.c \