summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-07-24 19:10:00 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-07-24 19:10:00 (GMT)
commit492e5ca2b48782bb4759ee1d0a59b0210f011528 (patch)
treef2c334cd5e2afb9ca40492340efe57d1f3af1ae6 /src
parent05973a4e8610a7f6893d0eaed9c3eee3b008ba60 (diff)
downloadhdf5-492e5ca2b48782bb4759ee1d0a59b0210f011528.zip
hdf5-492e5ca2b48782bb4759ee1d0a59b0210f011528.tar.gz
hdf5-492e5ca2b48782bb4759ee1d0a59b0210f011528.tar.bz2
[svn-r14004] Description:
Fix problem with datatype messages where the version of the format for a datatype message could depend on the "use the latest format" flag from the file after it was initially created. Tested on: FreeBSD/32 6.2 (duty) FreeBSD/64 6.2 (liberty) Linux/32 2.6 (kagiso) Mac OS X/32 10.4.10 (amazon)
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c5
-rw-r--r--src/H5D.c17
-rw-r--r--src/H5Odtype.c101
-rw-r--r--src/H5T.c484
-rw-r--r--src/H5Tarray.c11
-rw-r--r--src/H5Tcommit.c5
-rw-r--r--src/H5Tcompound.c77
-rw-r--r--src/H5Tdbg.c407
-rw-r--r--src/H5Titerate.c155
-rw-r--r--src/H5Tpkg.h79
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--src/H5Tvlen.c21
-rwxr-xr-xsrc/Makefile.am8
-rw-r--r--src/Makefile.in10
14 files changed, 889 insertions, 492 deletions
diff --git a/src/H5A.c b/src/H5A.c
index 5bcbd7f..3ac3d52 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -350,6 +350,11 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
if(H5T_set_loc(attr->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
+ /* Set the latest format for datatype, if requested */
+ if(H5F_USE_LATEST_FORMAT(loc->oloc->file))
+ if(H5T_set_latest_version(attr->dt) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
+
/* Copy the dataspace for the attribute */
attr->ds = H5S_copy(space, FALSE);
diff --git a/src/H5D.c b/src/H5D.c
index 526ee27..6a47908 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1020,6 +1020,7 @@ H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type)
{
htri_t relocatable; /* Flag whether the type is relocatable */
htri_t immutable; /* Flag whether the type is immutable */
+ hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_init_type)
@@ -1037,15 +1038,23 @@ H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type)
if((immutable = H5T_is_immutable(type)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't check datatype?")
+ /* Get the file's 'use the latest version of the format' flag */
+ use_latest_format = H5F_USE_LATEST_FORMAT(file);
+
/* Copy the datatype if it's a custom datatype or if it'll change when it's location is changed */
- if(!immutable || relocatable) {
+ if(!immutable || relocatable || use_latest_format) {
/* Copy datatype for dataset */
- if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL))==NULL)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy datatype")
+ if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL)) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy datatype")
/* Mark any datatypes as being on disk now */
if(H5T_set_loc(dset->shared->type, file, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't set datatype location")
+
+ /* Set the latest format, if requested */
+ if(use_latest_format)
+ if(H5T_set_latest_version(dset->shared->type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
/* Get a datatype ID for the dataset's datatype */
if((dset->shared->type_id = H5I_register(H5I_DATATYPE, dset->shared->type)) < 0)
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 2bfaccf..1e97687 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -89,31 +89,6 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
H5O_dtype_shared_debug /* debug the message */
}};
-/* This is the version to create all datatypes which don't contain
- * array datatypes (atomic types, compound datatypes without array fields,
- * vlen sequences of objects which aren't arrays, etc.) or VAX byte-ordered
- * objects.
- */
-#define H5O_DTYPE_VERSION_1 1
-
-/* This is the version to create all datatypes which contain H5T_ARRAY
- * class objects (array definitely, potentially compound & vlen sequences also),
- * but not VAX byte-ordered objects.
- */
-#define H5O_DTYPE_VERSION_2 2
-
-/* This is the version to create all datatypes which contain VAX byte-ordered
- * objects (floating-point types, currently) (can also also H5T_ARRAY types
- * also).
- */
-/* This version also packs compound & enum field names without padding */
-/* This version also encodes the member offset of compound fields more efficiently */
-#define H5O_DTYPE_VERSION_3 3
-
-/* The latest version of the format. Look through the 'encode helper' routine
- * and 'size' callback for places to change when updating this. */
-#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_3
-
/*-------------------------------------------------------------------------
* Function: H5O_dtype_decode_helper
@@ -146,6 +121,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
version = (flags>>4) & 0x0f;
if(version < H5O_DTYPE_VERSION_1 || version > H5O_DTYPE_VERSION_3)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "bad version number for datatype message")
+ dt->shared->version = version;
dt->shared->type = (H5T_class_t)(flags & 0x0f);
flags >>= 8;
@@ -515,6 +491,10 @@ done:
*
* Purpose: Encodes a datatype.
*
+ * Note: When changing the format of a datatype (or adding a new one),
+ * remember to change the upgrade version callback
+ * (H5T_upgrade_version_cb).
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
@@ -525,14 +505,10 @@ done:
static herr_t
H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
{
- htri_t has_array = FALSE; /* Whether a compound datatype has an array inside it */
- hbool_t has_vax = FALSE; /* Whether VAX floating number exists */
unsigned flags = 0;
char *hdr = (char *)*pp;
unsigned i;
size_t n, z;
- uint8_t version; /* version number */
- hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_encode_helper)
@@ -541,9 +517,6 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
HDassert(pp && *pp);
HDassert(dt);
- /* Get the file's 'use the latest version of the format' flag */
- use_latest_format = H5F_USE_LATEST_FORMAT(f);
-
/* skip the type and class bit-field for now */
*pp += 4;
UINT32ENCODE(*pp, dt->shared->size);
@@ -666,7 +639,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
break;
case H5T_ORDER_VAX: /*turn on 1st and 6th (reserved before adding VAX) bits*/
flags |= 0x41;
- has_vax = TRUE;
+ HDassert(dt->shared->version >= H5O_DTYPE_VERSION_3);
break;
default:
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "byte order is not supported in file format yet")
@@ -733,10 +706,6 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
{
unsigned offset_nbytes; /* Size needed to encode member offsets */
- /* Check for an array datatype somewhere within the compound type */
- if((has_array = H5T_detect_class(dt, H5T_ARRAY)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't detect array class")
-
/* Compute the # of bytes required to store a member offset */
offset_nbytes = (H5V_log2_gen((uint64_t)dt->shared->size) + 7) / 8;
@@ -745,12 +714,16 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
*/
flags = dt->shared->u.compnd.nmembs & 0xffff;
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
+ /* Sanity check */
+ /* (compound datatypes w/array members must be encoded w/version >= 2) */
+ HDassert(dt->shared->u.compnd.memb[i].type->shared->type != H5T_ARRAY || dt->shared->version >= H5O_DTYPE_VERSION_2);
+
/* Name */
HDstrcpy((char*)(*pp), dt->shared->u.compnd.memb[i].name);
/* Version 3 of the datatype message removed the padding to multiple of 8 bytes */
n = HDstrlen(dt->shared->u.compnd.memb[i].name);
- if(use_latest_format)
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
*pp += n + 1;
else {
/* Pad name to multiple of 8 bytes */
@@ -761,7 +734,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
/* Member offset */
/* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
- if(use_latest_format)
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
UINT32ENCODE_VAR(*pp, dt->shared->u.compnd.memb[i].offset, offset_nbytes)
else
UINT32ENCODE(*pp, dt->shared->u.compnd.memb[i].offset)
@@ -770,7 +743,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
* member information, for better backward compatibility
* Write out all zeros for the array information, though...
*/
- if(!has_array && !use_latest_format) {
+ if(dt->shared->version == H5O_DTYPE_VERSION_1) {
unsigned j;
/* Dimensionality */
@@ -810,13 +783,13 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode parent datatype")
/* Names, each a multiple of eight bytes */
- for(i=0; i<dt->shared->u.enumer.nmembs; i++) {
+ for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
/* Name */
HDstrcpy((char*)(*pp), dt->shared->u.enumer.name[i]);
/* Version 3 of the datatype message removed the padding to multiple of 8 bytes */
n = HDstrlen(dt->shared->u.enumer.name[i]);
- if(use_latest_format)
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
*pp += n + 1;
else {
/* Pad to multiple of 8 bytes */
@@ -882,7 +855,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
*(*pp)++ = dt->shared->u.array.ndims;
/* Drop this information for Version 3 of the format */
- if(!use_latest_format) {
+ if(dt->shared->version < H5O_DTYPE_VERSION_3) {
/* Reserved */
*(*pp)++ = '\0';
*(*pp)++ = '\0';
@@ -894,7 +867,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
UINT32ENCODE(*pp, dt->shared->u.array.dim[i]);
/* Drop this information for Version 3 of the format */
- if(!use_latest_format) {
+ if(dt->shared->version < H5O_DTYPE_VERSION_3) {
/* Encode 'fake' array dimension permutations */
for(i = 0; i < (unsigned)dt->shared->u.array.ndims; i++)
UINT32ENCODE(*pp, i);
@@ -910,21 +883,8 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt)
break;
} /* end switch */
- /* Set version #, based on actual features used for datatype */
- /* (unless the "use the latest format" flag is set, which can "upgrade" the
- * format of certain encodings)
- */
- if(use_latest_format)
- version = H5O_DTYPE_VERSION_LATEST;
- else if(has_vax)
- version = H5O_DTYPE_VERSION_3;
- else if(has_array)
- version = H5O_DTYPE_VERSION_2;
- else
- version = H5O_DTYPE_VERSION_1;
-
/* Encode the type's class, version and bit field */
- *hdr++ = ((unsigned)(dt->shared->type) & 0x0f) | (version << 4);
+ *hdr++ = ((unsigned)(dt->shared->type) & 0x0f) | (dt->shared->version << 4);
*hdr++ = (flags >> 0) & 0xff;
*hdr++ = (flags >> 8) & 0xff;
*hdr++ = (flags >> 16) & 0xff;
@@ -1098,7 +1058,6 @@ static size_t
H5O_dtype_size(const H5F_t *f, const void *_mesg)
{
const H5T_t *dt = (const H5T_t *)_mesg;
- hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
unsigned u; /* Local index variable */
size_t ret_value;
@@ -1107,9 +1066,6 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
HDassert(f);
HDassert(dt);
- /* Get the file's 'use the latest version of the format' flag */
- use_latest_format = H5F_USE_LATEST_FORMAT(f);
-
/* Set the common size information */
ret_value = 4 + /* Type, class & flags */
4; /* Size of datatype */
@@ -1134,13 +1090,8 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
case H5T_COMPOUND:
{
- htri_t has_array; /* Whether a compound datatype has an array inside it */
unsigned offset_nbytes; /* Size needed to encode member offsets */
- /* Check for an array datatype somewhere within the compound type */
- has_array = H5T_detect_class(dt, H5T_ARRAY);
- HDassert(has_array >= 0);
-
/* Compute the # of bytes required to store a member offset */
offset_nbytes = (H5V_log2_gen((uint64_t)dt->shared->size) + 7) / 8;
@@ -1151,17 +1102,17 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
/* Get length of field's name */
name_len = HDstrlen(dt->shared->u.compnd.memb[u].name);
- /* Newer versions of the format don't pad out the name */
- if(use_latest_format)
+ /* Versions of the format >= 3 don't pad out the name */
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
ret_value += name_len + 1;
else
ret_value += ((name_len + 8) / 8) * 8;
/* Check for encoding array datatype or using the latest file format */
/* (starting with version 3 of the datatype message, use the minimum # of bytes required) */
- if(use_latest_format)
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
ret_value += offset_nbytes; /*member offset*/
- else if(has_array)
+ if(dt->shared->version >= H5O_DTYPE_VERSION_2)
ret_value += 4; /*member offset*/
else
ret_value += 4 + /*member offset*/
@@ -1183,8 +1134,8 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
/* Get length of field's name */
name_len = HDstrlen(dt->shared->u.enumer.name[u]);
- /* Newer versions of the format don't pad out the name */
- if(use_latest_format)
+ /* Versions of the format >= 3 don't pad out the name */
+ if(dt->shared->version >= H5O_DTYPE_VERSION_3)
ret_value += name_len + 1;
else
ret_value += ((name_len + 8) / 8) * 8;
@@ -1202,10 +1153,10 @@ H5O_dtype_size(const H5F_t *f, const void *_mesg)
case H5T_ARRAY:
ret_value += 1; /* ndims */
- if(!use_latest_format)
+ if(dt->shared->version < H5O_DTYPE_VERSION_3)
ret_value += 3; /* reserved bytes*/
ret_value += 4 * dt->shared->u.array.ndims; /* dimensions */
- if(!use_latest_format)
+ if(dt->shared->version < H5O_DTYPE_VERSION_3)
ret_value += 4 * dt->shared->u.array.ndims; /* dimension permutations */
ret_value += H5O_dtype_size(f, dt->shared->parent);
break;
diff --git a/src/H5T.c b/src/H5T.c
index a08f010..4e6a7a6 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -260,7 +260,6 @@ H5FL_DEFINE(H5T_shared_t);
H5FL_DEFINE(H5T_path_t);
/* Static local functions */
-static herr_t H5T_print_stats(H5T_path_t *path, int *nprint/*in,out*/);
static herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src,
H5T_t *dst, H5T_conv_t func, hid_t dxpl_id);
static herr_t H5T_register(H5T_pers_t pers, const char *name, H5T_t *src,
@@ -287,38 +286,38 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define the code template for bitfields for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_BITFIELD_CORE { \
- dt->shared->type = H5T_BITFIELD; \
+ dt->shared->type = H5T_BITFIELD; \
}
/* Define the code template for times for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_TIME_CORE { \
- dt->shared->type = H5T_TIME; \
+ dt->shared->type = H5T_TIME; \
}
/* Define the code template for types which reset the offset for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_OFFSET_CORE { \
- dt->shared->u.atomic.offset = 0; \
+ dt->shared->u.atomic.offset = 0; \
}
/* Define common code for all numeric types (floating-point & int, signed & unsigned) */
#define H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) { \
- dt->shared->u.atomic.order = ENDIANNESS; \
- dt->shared->u.atomic.offset = 0; \
- dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO; \
- dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.order = ENDIANNESS; \
+ dt->shared->u.atomic.offset = 0; \
+ dt->shared->u.atomic.lsb_pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.msb_pad = H5T_PAD_ZERO; \
}
/* Define the code templates for standard floats for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_FLOAT_COMMON(ENDIANNESS) { \
H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) \
- dt->shared->u.atomic.u.f.sign = 31; \
- dt->shared->u.atomic.u.f.epos = 23; \
- dt->shared->u.atomic.u.f.esize = 8; \
- dt->shared->u.atomic.u.f.ebias = 0x7f; \
- dt->shared->u.atomic.u.f.mpos = 0; \
- dt->shared->u.atomic.u.f.msize = 23; \
- dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
- dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.u.f.sign = 31; \
+ dt->shared->u.atomic.u.f.epos = 23; \
+ dt->shared->u.atomic.u.f.esize = 8; \
+ dt->shared->u.atomic.u.f.ebias = 0x7f; \
+ dt->shared->u.atomic.u.f.mpos = 0; \
+ dt->shared->u.atomic.u.f.msize = 23; \
+ dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
}
#define H5T_INIT_TYPE_FLOATLE_CORE { \
@@ -332,14 +331,14 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define the code templates for standard doubles for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_DOUBLE_COMMON(ENDIANNESS) { \
H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) \
- dt->shared->u.atomic.u.f.sign = 63; \
- dt->shared->u.atomic.u.f.epos = 52; \
- dt->shared->u.atomic.u.f.esize = 11; \
- dt->shared->u.atomic.u.f.ebias = 0x03ff; \
- dt->shared->u.atomic.u.f.mpos = 0; \
- dt->shared->u.atomic.u.f.msize = 52; \
- dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
- dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.u.f.sign = 63; \
+ dt->shared->u.atomic.u.f.epos = 52; \
+ dt->shared->u.atomic.u.f.esize = 11; \
+ dt->shared->u.atomic.u.f.ebias = 0x03ff; \
+ dt->shared->u.atomic.u.f.mpos = 0; \
+ dt->shared->u.atomic.u.f.msize = 52; \
+ dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
}
#define H5T_INIT_TYPE_DOUBLELE_CORE { \
@@ -353,33 +352,35 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define the code templates for VAX float for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_FLOATVAX_CORE { \
H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_VAX) \
- dt->shared->u.atomic.u.f.sign = 31; \
- dt->shared->u.atomic.u.f.epos = 23; \
- dt->shared->u.atomic.u.f.esize = 8; \
- dt->shared->u.atomic.u.f.ebias = 0x81; \
- dt->shared->u.atomic.u.f.mpos = 0; \
- dt->shared->u.atomic.u.f.msize = 23; \
- dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
- dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.u.f.sign = 31; \
+ dt->shared->u.atomic.u.f.epos = 23; \
+ dt->shared->u.atomic.u.f.esize = 8; \
+ dt->shared->u.atomic.u.f.ebias = 0x81; \
+ dt->shared->u.atomic.u.f.mpos = 0; \
+ dt->shared->u.atomic.u.f.msize = 23; \
+ dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->version = H5O_DTYPE_VERSION_3; \
}
/* Define the code templates for VAX double for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_DOUBLEVAX_CORE { \
H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_VAX) \
- dt->shared->u.atomic.u.f.sign = 63; \
- dt->shared->u.atomic.u.f.epos = 52; \
- dt->shared->u.atomic.u.f.esize = 11; \
- dt->shared->u.atomic.u.f.ebias = 0x0401; \
- dt->shared->u.atomic.u.f.mpos = 0; \
- dt->shared->u.atomic.u.f.msize = 52; \
- dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
- dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->u.atomic.u.f.sign = 63; \
+ dt->shared->u.atomic.u.f.epos = 52; \
+ dt->shared->u.atomic.u.f.esize = 11; \
+ dt->shared->u.atomic.u.f.ebias = 0x0401; \
+ dt->shared->u.atomic.u.f.mpos = 0; \
+ dt->shared->u.atomic.u.f.msize = 52; \
+ dt->shared->u.atomic.u.f.norm = H5T_NORM_IMPLIED; \
+ dt->shared->u.atomic.u.f.pad = H5T_PAD_ZERO; \
+ dt->shared->version = H5O_DTYPE_VERSION_3; \
}
/* Define the code templates for standard signed integers for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_SINT_COMMON(ENDIANNESS) { \
H5T_INIT_TYPE_NUM_COMMON(ENDIANNESS) \
- dt->shared->u.atomic.u.i.sign = H5T_SGN_2; \
+ dt->shared->u.atomic.u.i.sign = H5T_SGN_2; \
}
#define H5T_INIT_TYPE_SINTLE_CORE { \
@@ -407,30 +408,30 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define a macro for common code for all newly allocate datatypes */
#define H5T_INIT_TYPE_ALLOC_COMMON(TYPE) { \
dt->sh_loc.type = H5O_SHARE_TYPE_UNSHARED; \
- dt->shared->type = TYPE; \
+ dt->shared->type = TYPE; \
}
/* Define the code templates for opaque for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_OPAQ_CORE { \
H5T_INIT_TYPE_ALLOC_COMMON(H5T_OPAQUE) \
- dt->shared->u.opaque.tag = H5MM_xstrdup(""); \
+ dt->shared->u.opaque.tag = H5MM_xstrdup(""); \
}
/* Define the code templates for strings for the "GUTS" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_STRING_COMMON { \
H5T_INIT_TYPE_ALLOC_COMMON(H5T_STRING) \
H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE) \
- dt->shared->u.atomic.u.s.cset = H5F_DEFAULT_CSET; \
+ dt->shared->u.atomic.u.s.cset = H5F_DEFAULT_CSET; \
}
#define H5T_INIT_TYPE_CSTRING_CORE { \
H5T_INIT_TYPE_STRING_COMMON \
- dt->shared->u.atomic.u.s.pad = H5T_STR_NULLTERM; \
+ dt->shared->u.atomic.u.s.pad = H5T_STR_NULLTERM; \
}
#define H5T_INIT_TYPE_FORSTRING_CORE { \
H5T_INIT_TYPE_STRING_COMMON \
- dt->shared->u.atomic.u.s.pad = H5T_STR_SPACEPAD; \
+ dt->shared->u.atomic.u.s.pad = H5T_STR_SPACEPAD; \
}
/* Define the code templates for references for the "GUTS" in the H5T_INIT_TYPE macro */
@@ -441,20 +442,20 @@ static H5T_t *H5T_decode(const unsigned char *buf);
#define H5T_INIT_TYPE_OBJREF_CORE { \
H5T_INIT_TYPE_REF_COMMON \
- dt->shared->force_conv = TRUE; \
- dt->shared->u.atomic.u.r.rtype = H5R_OBJECT; \
- dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; \
+ dt->shared->force_conv = TRUE; \
+ dt->shared->u.atomic.u.r.rtype = H5R_OBJECT; \
+ dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; \
}
#define H5T_INIT_TYPE_REGREF_CORE { \
H5T_INIT_TYPE_REF_COMMON \
- dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION; \
+ dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION; \
}
/* Define the code templates for the "SIZE_TMPL" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_SET_SIZE(SIZE) { \
- dt->shared->size = SIZE; \
- dt->shared->u.atomic.prec = 8*SIZE; \
+ dt->shared->size = SIZE; \
+ dt->shared->u.atomic.prec = 8 * SIZE; \
}
#define H5T_INIT_TYPE_NOSET_SIZE(SIZE) { \
@@ -463,13 +464,13 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define the code templates for the "CRT_TMPL" in the H5T_INIT_TYPE macro */
#define H5T_INIT_TYPE_COPY_CREATE(BASE) { \
/* Base off of existing datatype */ \
- if(NULL==(dt = H5T_copy(BASE,H5T_COPY_TRANSIENT))) \
+ if(NULL == (dt = H5T_copy(BASE, H5T_COPY_TRANSIENT))) \
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "duplicating base type failed") \
}
#define H5T_INIT_TYPE_ALLOC_CREATE(BASE) { \
/* Allocate new datatype info */ \
- if (NULL==(dt = H5T_alloc())) \
+ if(NULL == (dt = H5T_alloc())) \
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") \
}
@@ -479,14 +480,14 @@ static H5T_t *H5T_decode(const unsigned char *buf);
H5_GLUE3(H5T_INIT_TYPE_,CRT_TMPL,_CREATE)(BASE) \
\
/* Adjust information for all types */ \
- dt->shared->state = H5T_STATE_IMMUTABLE; \
+ dt->shared->state = H5T_STATE_IMMUTABLE; \
H5_GLUE3(H5T_INIT_TYPE_,SIZE_TMPL,_SIZE)(SIZE) \
\
/* Adjust information for this type */ \
H5_GLUE3(H5T_INIT_TYPE_,GUTS,_CORE) \
\
/* Atomize result */ \
- if ((GLOBAL = H5I_register(H5I_DATATYPE, dt)) < 0) \
+ if((GLOBAL = H5I_register(H5I_DATATYPE, dt)) < 0) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \
}
@@ -3277,7 +3278,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
/* Copy shared location information if the new type is named or if it is
* shared in the heap.
*/
- if(old_dt->sh_loc.type == H5O_SHARE_TYPE_SOHM ||
+ if((old_dt->sh_loc.type == H5O_SHARE_TYPE_SOHM || old_dt->sh_loc.type == H5O_SHARE_TYPE_HERE) ||
new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
if(H5O_set_shared(&(new_dt->sh_loc), &(old_dt->sh_loc)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy shared information")
@@ -3357,8 +3358,6 @@ done:
* Programmer: Quincey Koziol
* Monday, August 29, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
H5T_t *
@@ -3369,23 +3368,25 @@ H5T_alloc(void)
FUNC_ENTER_NOAPI(H5T_alloc, NULL)
- /* Allocate & initialize new datatype info */
+ /* Allocate & initialize datatype wrapper info */
if(NULL == (dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
H5O_loc_reset(&(dt->oloc));
H5G_name_reset(&(dt->path));
H5O_msg_reset_share(H5O_DTYPE_ID, dt);
+ /* Allocate & initialize shared datatype structure */
if(NULL == (dt->shared = H5FL_CALLOC(H5T_shared_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ dt->shared->version = H5O_DTYPE_VERSION_1;
/* Assign return value */
ret_value = dt;
done:
if(ret_value == NULL)
- if(dt != NULL) {
- if(dt->shared != NULL)
+ if(dt) {
+ if(dt->shared)
H5FL_FREE(H5T_shared_t, dt->shared);
H5FL_FREE(H5T_t, dt);
} /* end if */
@@ -5071,8 +5072,6 @@ done:
* Programmer: Quincey Koziol
* Thursday, June 24, 2004
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
@@ -5080,323 +5079,124 @@ H5T_is_relocatable(const H5T_t *dt)
{
htri_t ret_value = FALSE;
- FUNC_ENTER_NOAPI(H5T_is_relocatable, FAIL);
+ FUNC_ENTER_NOAPI(H5T_is_relocatable, FAIL)
- assert(dt);
+ /* Sanity check */
+ HDassert(dt);
- if(H5T_detect_class(dt, H5T_VLEN))
- ret_value = TRUE;
- else if(H5T_detect_class(dt, H5T_REFERENCE))
+ /* VL and reference datatypes are relocatable */
+ if(H5T_detect_class(dt, H5T_VLEN) || H5T_detect_class(dt, H5T_REFERENCE))
ret_value = TRUE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_relocatable() */
-
/*-------------------------------------------------------------------------
- * Function: H5T_print_stats
- *
- * Purpose: Print statistics about a conversion path. Statistics are
- * printed only if all the following conditions are true:
+ * Function: H5T_upgrade_version_cb
*
- * 1. The library was compiled with H5T_DEBUG defined.
- * 2. Data type debugging is turned on at run time.
- * 3. The path was called at least one time.
+ * Purpose: H5T_visit callback to Upgrade the version of a datatype
+ * (if there's any benefit to doing so)
*
- * The optional NPRINT argument keeps track of the number of
- * conversions paths for which statistics have been shown. If
- * its value is zero then table headers are printed before the
- * first line of output.
+ * Note: The behavior below is tightly coupled with the "better"
+ * encodings for datatype messages in the datatype message
+ * encoding routine.
*
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Robb Matzke
- * Monday, December 14, 1998
+ * Return: Non-negative on success/Negative on failure
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Thursday, July 19, 2007
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5T_print_stats(H5T_path_t UNUSED * path, int UNUSED * nprint/*in,out*/)
+H5T_upgrade_version_cb(H5T_t *dt, void *op_value)
{
-#ifdef H5T_DEBUG
- hsize_t nbytes;
- char bandwidth[32];
-#endif
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_upgrade_version_cb)
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_print_stats);
+ /* Sanity check */
+ HDassert(dt);
+ HDassert(op_value);
-#ifdef H5T_DEBUG
- if (H5DEBUG(T) && path->stats.ncalls>0) {
- if (nprint && 0==(*nprint)++) {
- HDfprintf (H5DEBUG(T), "H5T: type conversion statistics:\n");
- HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
- "Conversion", "Elmts", "Calls", "User",
- "System", "Elapsed", "Bandwidth");
- HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
- "----------", "-----", "-----", "----",
- "------", "-------", "---------");
- }
- if(path->src && path->dst)
- nbytes = MAX (H5T_get_size (path->src),
- H5T_get_size (path->dst));
- else if(path->src)
- nbytes = H5T_get_size (path->src);
- else if(path->dst)
- nbytes = H5T_get_size (path->dst);
- else
- nbytes = 0;
- nbytes *= path->stats.nelmts;
- H5_bandwidth(bandwidth, (double)nbytes,
- path->stats.timer.etime);
- HDfprintf (H5DEBUG(T), " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n",
- path->name,
- path->stats.nelmts,
- path->stats.ncalls,
- path->stats.timer.utime,
- path->stats.timer.stime,
- path->stats.timer.etime,
- bandwidth);
- }
-#endif
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ /* Special behavior for each type of datatype */
+ switch(dt->shared->type) {
+ case H5T_COMPOUND:
+ case H5T_ARRAY:
+ case H5T_ENUM:
+ /* These types benefit from "upgrading" their version */
+ if(*(unsigned *)op_value > dt->shared->version)
+ dt->shared->version = *(unsigned *)op_value;
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5T_upgrade_version_cb() */
+
+
/*-------------------------------------------------------------------------
- * Function: H5T_debug
+ * Function: H5T_upgrade_version
*
- * Purpose: Prints information about a data type.
+ * Purpose: Upgrade the version of a datatype (if there's any benefit to
+ * doing so) and recursively apply to compound members and/or
+ * parent datatypes.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Wednesday, January 7, 1998
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Thursday, July 19, 2007
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_debug(const H5T_t *dt, FILE *stream)
+H5T_upgrade_version(H5T_t *dt, unsigned new_version)
{
- const char *s1="", *s2="";
- unsigned i;
- size_t k, base_size;
- uint64_t tmp;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5T_debug, FAIL);
-
- /* Check args */
- assert(dt);
- assert(stream);
-
- switch (dt->shared->type) {
- case H5T_INTEGER:
- s1 = "int";
- break;
- case H5T_FLOAT:
- s1 = "float";
- break;
- case H5T_TIME:
- s1 = "time";
- break;
- case H5T_STRING:
- s1 = "str";
- break;
- case H5T_BITFIELD:
- s1 = "bits";
- break;
- case H5T_OPAQUE:
- s1 = "opaque";
- break;
- case H5T_COMPOUND:
- s1 = "struct";
- break;
- case H5T_ENUM:
- s1 = "enum";
- break;
- case H5T_VLEN:
- if(H5T_IS_VL_STRING(dt->shared))
- s1 = "str";
- else
- s1 = "vlen";
- break;
- default:
- s1 = "";
- break;
- }
-
- switch (dt->shared->state) {
- case H5T_STATE_TRANSIENT:
- s2 = "[transient]";
- break;
- case H5T_STATE_RDONLY:
- s2 = "[constant]";
- break;
- case H5T_STATE_IMMUTABLE:
- s2 = "[predefined]";
- break;
- case H5T_STATE_NAMED:
- s2 = "[named,closed]";
- break;
- case H5T_STATE_OPEN:
- s2 = "[named,open]";
- break;
- }
-
- fprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->shared->size));
-
- if (H5T_IS_ATOMIC(dt->shared)) {
- switch (dt->shared->u.atomic.order) {
- case H5T_ORDER_BE:
- s1 = "BE";
- break;
- case H5T_ORDER_LE:
- s1 = "LE";
- break;
- case H5T_ORDER_VAX:
- s1 = "VAX";
- break;
- case H5T_ORDER_NONE:
- s1 = "NONE";
- break;
- default:
- s1 = "order?";
- break;
- }
- fprintf(stream, ", %s", s1);
-
- if (dt->shared->u.atomic.offset) {
- fprintf(stream, ", offset=%lu",
- (unsigned long) (dt->shared->u.atomic.offset));
- }
- if (dt->shared->u.atomic.prec != 8 * dt->shared->size) {
- fprintf(stream, ", prec=%lu",
- (unsigned long) (dt->shared->u.atomic.prec));
- }
- switch (dt->shared->type) {
- case H5T_INTEGER:
- switch (dt->shared->u.atomic.u.i.sign) {
- case H5T_SGN_NONE:
- s1 = "unsigned";
- break;
- case H5T_SGN_2:
- s1 = NULL;
- break;
- default:
- s1 = "sign?";
- break;
- }
- if (s1) fprintf(stream, ", %s", s1);
- break;
-
- case H5T_FLOAT:
- switch (dt->shared->u.atomic.u.f.norm) {
- case H5T_NORM_IMPLIED:
- s1 = "implied";
- break;
- case H5T_NORM_MSBSET:
- s1 = "msbset";
- break;
- case H5T_NORM_NONE:
- s1 = "no-norm";
- break;
- default:
- s1 = "norm?";
- break;
- }
- fprintf(stream, ", sign=%lu+1",
- (unsigned long) (dt->shared->u.atomic.u.f.sign));
- fprintf(stream, ", mant=%lu+%lu (%s)",
- (unsigned long) (dt->shared->u.atomic.u.f.mpos),
- (unsigned long) (dt->shared->u.atomic.u.f.msize), s1);
- fprintf(stream, ", exp=%lu+%lu",
- (unsigned long) (dt->shared->u.atomic.u.f.epos),
- (unsigned long) (dt->shared->u.atomic.u.f.esize));
- tmp = dt->shared->u.atomic.u.f.ebias >> 32;
- if (tmp) {
- size_t hi=(size_t)tmp;
- size_t lo =(size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
- fprintf(stream, " bias=0x%08lx%08lx",
- (unsigned long)hi, (unsigned long)lo);
- } else {
- size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
- fprintf(stream, " bias=0x%08lx", (unsigned long)lo);
- }
- break;
+ herr_t ret_value = SUCCEED; /* Return value */
- default:
- /* No additional info */
- break;
- }
+ FUNC_ENTER_NOAPI(H5T_upgrade_version, FAIL)
- } else if (H5T_COMPOUND==dt->shared->type) {
- /* Compound data type */
- for (i=0; i<dt->shared->u.compnd.nmembs; i++) {
- fprintf(stream, "\n\"%s\" @%lu",
- dt->shared->u.compnd.memb[i].name,
- (unsigned long) (dt->shared->u.compnd.memb[i].offset));
- fprintf(stream, " ");
- H5T_debug(dt->shared->u.compnd.memb[i].type, stream);
- }
- fprintf(stream, "\n");
+ /* Sanity check */
+ HDassert(dt);
- } else if (H5T_VLEN==dt->shared->type) {
- switch(dt->shared->u.vlen.loc) {
- case H5T_LOC_MEMORY:
- fprintf(stream, ", loc=memory");
- break;
+ /* Iterate over entire datatype, upgrading the version of components, if it's useful */
+ if(H5T_visit(dt, (H5T_VISIT_SIMPLE | H5T_VISIT_COMPLEX_LAST), H5T_upgrade_version_cb, &new_version) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "iteration to upgrade datatype encoding version failed")
- case H5T_LOC_DISK:
- fprintf(stream, ", loc=disk");
- break;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_upgrade_version() */
- default:
- fprintf(stream, ", loc=UNKNOWN");
- break;
- } /* end switch */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_set_latest_version
+ *
+ * Purpose: Set the encoding for a datatype to the latest version.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, July 19, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_set_latest_version(H5T_t *dt)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- if(H5T_IS_VL_STRING(dt->shared)) {
- /* Variable length string datatype */
- fprintf(stream, ", variable-length");
- } /* end if */
- else {
- /* Variable length sequence datatype */
- fprintf(stream, " VLEN ");
- H5T_debug(dt->shared->parent, stream);
- fprintf(stream, "\n");
- } /* end else */
-
- } else if (H5T_ENUM==dt->shared->type) {
- /* Enumeration data type */
- fprintf(stream, " ");
- H5T_debug(dt->shared->parent, stream);
- base_size = dt->shared->parent->shared->size;
- for (i=0; i<dt->shared->u.enumer.nmembs; i++) {
- fprintf(stream, "\n\"%s\" = 0x", dt->shared->u.enumer.name[i]);
- for (k=0; k<base_size; k++) {
- fprintf(stream, "%02lx",
- (unsigned long)(dt->shared->u.enumer.value+i*base_size+k));
- }
- }
- fprintf(stream, "\n");
+ FUNC_ENTER_NOAPI(H5T_set_latest_version, FAIL)
- } else if (H5T_OPAQUE==dt->shared->type) {
- fprintf(stream, ", tag=\"%s\"", dt->shared->u.opaque.tag);
+ /* Sanity check */
+ HDassert(dt);
- } else {
- /* Unknown */
- fprintf(stream, "unknown class %d\n", (int)(dt->shared->type));
- }
- fprintf(stream, "}");
+ /* Upgrade the format version for the datatype to the latest */
+ if(H5T_upgrade_version(dt, H5O_DTYPE_VERSION_LATEST) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_set_latest_version() */
diff --git a/src/H5Tarray.c b/src/H5Tarray.c
index 05b8dc4..cef8f66 100644
--- a/src/H5Tarray.c
+++ b/src/H5Tarray.c
@@ -158,12 +158,13 @@ H5T_array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/* ndims */])
/* Set the array's size (number of elements * element datatype's size) */
ret_value->shared->size = ret_value->shared->parent->shared->size * ret_value->shared->u.array.nelem;
- /*
- * Set the "force conversion" flag if the base datatype indicates
- */
+ /* Set the "force conversion" flag if the base datatype indicates */
if(base->shared->force_conv == TRUE)
ret_value->shared->force_conv = TRUE;
+ /* Array datatypes need a later version of the datatype object header message */
+ ret_value->shared->version = MAX(base->shared->version, H5O_DTYPE_VERSION_2);
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_array_create */
@@ -220,7 +221,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5T_get_array_ndims(H5T_t *dt)
+H5T_get_array_ndims(const H5T_t *dt)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_get_array_ndims)
@@ -283,7 +284,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5T_get_array_dims(H5T_t *dt, hsize_t dims[])
+H5T_get_array_dims(const H5T_t *dt, hsize_t dims[])
{
unsigned u; /* Local index variable */
int ret_value; /* return value */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 4c5d802..dba5524 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -314,6 +314,11 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize path")
loc_init = TRUE;
+ /* Set the latest format, if requested */
+ if(H5F_USE_LATEST_FORMAT(file))
+ if(H5T_set_latest_version(type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
+
/* Calculate message size infomation, for creating object header */
dtype_size = H5O_msg_size_f(file, tcpl_id, H5O_DTYPE_ID, type, (size_t)0);
HDassert(dtype_size);
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index fbaacfc..660a76d 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -30,9 +30,6 @@
#include "H5MMprivate.h" /*memory management */
#include "H5Tpkg.h" /*data-type functions */
-/* Local macros */
-#define H5T_COMPND_INC 64 /*typical max numb of members per struct */
-
/* Static local functions */
static herr_t H5T_pack(const H5T_t *dt);
@@ -416,59 +413,56 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5T_insert(const H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
+H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
{
unsigned idx, i;
size_t total_size;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5T_insert, FAIL)
/* check args */
- assert(parent && H5T_COMPOUND == parent->shared->type);
- assert(H5T_STATE_TRANSIENT==parent->shared->state);
- assert(member);
- assert(name && *name);
+ HDassert(parent && H5T_COMPOUND == parent->shared->type);
+ HDassert(H5T_STATE_TRANSIENT == parent->shared->state);
+ HDassert(member);
+ HDassert(name && *name);
/* Does NAME already exist in PARENT? */
- for (i=0; i<parent->shared->u.compnd.nmembs; i++) {
- if (!HDstrcmp(parent->shared->u.compnd.memb[i].name, name))
+ for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
+ if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique")
- }
/* Does the new member overlap any existing member ? */
- total_size=member->shared->size;
- for (i=0; i<parent->shared->u.compnd.nmembs; i++) {
- if ((offset <= parent->shared->u.compnd.memb[i].offset &&
+ total_size = member->shared->size;
+ for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
+ if((offset <= parent->shared->u.compnd.memb[i].offset &&
offset + total_size > parent->shared->u.compnd.memb[i].offset) ||
(parent->shared->u.compnd.memb[i].offset <= offset &&
parent->shared->u.compnd.memb[i].offset +
parent->shared->u.compnd.memb[i].size > offset))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
- }
/* Does the new member overlap the end of the compound type? */
- if(offset+total_size>parent->shared->size)
+ if((offset + total_size) > parent->shared->size)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type")
/* Increase member array if necessary */
- if (parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) {
- unsigned na = parent->shared->u.compnd.nalloc + H5T_COMPND_INC;
- H5T_cmemb_t *x = H5MM_realloc (parent->shared->u.compnd.memb,
- na * sizeof(H5T_cmemb_t));
+ if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) {
+ unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2);
+ H5T_cmemb_t *x = H5MM_realloc(parent->shared->u.compnd.memb, na * sizeof(H5T_cmemb_t));
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
parent->shared->u.compnd.nalloc = na;
parent->shared->u.compnd.memb = x;
- }
+ } /* end if */
/* Add member to end of member array */
idx = parent->shared->u.compnd.nmembs;
parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name);
parent->shared->u.compnd.memb[idx].offset = offset;
parent->shared->u.compnd.memb[idx].size = total_size;
- parent->shared->u.compnd.memb[idx].type = H5T_copy (member, H5T_COPY_ALL);
+ parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL);
parent->shared->u.compnd.sorted = H5T_SORT_NONE;
parent->shared->u.compnd.nmembs++;
@@ -476,35 +470,42 @@ H5T_insert(const H5T_t *parent, const char *name, size_t offset, const H5T_t *me
/* Determine if the compound datatype stayed packed */
if(parent->shared->u.compnd.packed) {
/* Check if the member type is packed */
- if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type)>0) {
- if(idx==0) {
+ if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type) > 0) {
+ if(idx == 0) {
/* If the is the first member, the datatype is not packed
* if the first member isn't at offset 0
*/
- if(parent->shared->u.compnd.memb[idx].offset>0)
- parent->shared->u.compnd.packed=FALSE;
+ if(parent->shared->u.compnd.memb[idx].offset > 0)
+ parent->shared->u.compnd.packed = FALSE;
} /* end if */
else {
/* If the is not the first member, the datatype is not
* packed if the new member isn't adjoining the previous member
*/
- if(parent->shared->u.compnd.memb[idx].offset!=(parent->shared->u.compnd.memb[idx-1].offset+parent->shared->u.compnd.memb[idx-1].size))
- parent->shared->u.compnd.packed=FALSE;
+ if(parent->shared->u.compnd.memb[idx].offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size))
+ parent->shared->u.compnd.packed = FALSE;
} /* end else */
} /* end if */
else
- parent->shared->u.compnd.packed=FALSE;
+ parent->shared->u.compnd.packed = FALSE;
} /* end if */
- /*
- * Set the "force conversion" flag if the field's datatype indicates
- */
- if(member->shared->force_conv==TRUE)
- parent->shared->force_conv=TRUE;
+ /* Set the "force conversion" flag if the field's datatype indicates */
+ if(member->shared->force_conv == TRUE)
+ parent->shared->force_conv = TRUE;
+
+ /* Check for member having a later version than the parent */
+ if(parent->shared->version < member->shared->version)
+ /* Upgrade parent datatype (and all other members also) */
+ /* (can't use a partial datatype and later versions of the format are
+ * more efficient, so might as well upgrade all members also... -QAK)
+ */
+ if(H5T_upgrade_version(parent, member->shared->version) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade member encoding version")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_insert() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Tdbg.c b/src/H5Tdbg.c
new file mode 100644
index 0000000..88e084d
--- /dev/null
+++ b/src/H5Tdbg.c
@@ -0,0 +1,407 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Module Info: This module contains most of the "core" functionality of
+ * the H5T interface, including the API initialization code, etc.
+ * Many routines that are infrequently used, or are specialized for
+ * one particular datatype class are in another module.
+ */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Tdbg.c
+ * Jul 19 2007
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Dump debugging information about a datatype
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5T_PACKAGE /*suppress error about including H5Tpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Tpkg.h" /* Datatypes */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_print_stats
+ *
+ * Purpose: Print statistics about a conversion path. Statistics are
+ * printed only if all the following conditions are true:
+ *
+ * 1. The library was compiled with H5T_DEBUG defined.
+ * 2. Data type debugging is turned on at run time.
+ * 3. The path was called at least one time.
+ *
+ * The optional NPRINT argument keeps track of the number of
+ * conversions paths for which statistics have been shown. If
+ * its value is zero then table headers are printed before the
+ * first line of output.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Robb Matzke
+ * Monday, December 14, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_print_stats(H5T_path_t UNUSED * path, int UNUSED * nprint/*in,out*/)
+{
+#ifdef H5T_DEBUG
+ hsize_t nbytes;
+ char bandwidth[32];
+#endif
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_print_stats)
+
+#ifdef H5T_DEBUG
+ if(H5DEBUG(T) && path->stats.ncalls > 0) {
+ if(nprint && 0 == (*nprint)++) {
+ HDfprintf(H5DEBUG(T), "H5T: type conversion statistics:\n");
+ HDfprintf(H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
+ "Conversion", "Elmts", "Calls", "User",
+ "System", "Elapsed", "Bandwidth");
+ HDfprintf(H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n",
+ "----------", "-----", "-----", "----",
+ "------", "-------", "---------");
+ }
+ if(path->src && path->dst)
+ nbytes = MAX(H5T_get_size(path->src), H5T_get_size(path->dst));
+ else if(path->src)
+ nbytes = H5T_get_size(path->src);
+ else if(path->dst)
+ nbytes = H5T_get_size(path->dst);
+ else
+ nbytes = 0;
+ nbytes *= path->stats.nelmts;
+ H5_bandwidth(bandwidth, (double)nbytes, path->stats.timer.etime);
+ HDfprintf(H5DEBUG(T), " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n",
+ path->name,
+ path->stats.nelmts,
+ path->stats.ncalls,
+ path->stats.timer.utime,
+ path->stats.timer.stime,
+ path->stats.timer.etime,
+ bandwidth);
+ }
+#endif
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5T_print_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_debug
+ *
+ * Purpose: Prints information about a data type.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_debug(const H5T_t *dt, FILE *stream)
+{
+ const char *s1 = "", *s2 = "";
+ unsigned i;
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5T_debug)
+
+ /* Check args */
+ HDassert(dt);
+ HDassert(stream);
+
+ switch(dt->shared->type) {
+ case H5T_INTEGER:
+ s1 = "int";
+ break;
+
+ case H5T_FLOAT:
+ s1 = "float";
+ break;
+
+ case H5T_TIME:
+ s1 = "time";
+ break;
+
+ case H5T_STRING:
+ s1 = "str";
+ break;
+
+ case H5T_BITFIELD:
+ s1 = "bits";
+ break;
+
+ case H5T_OPAQUE:
+ s1 = "opaque";
+ break;
+
+ case H5T_COMPOUND:
+ s1 = "struct";
+ break;
+
+ case H5T_ENUM:
+ s1 = "enum";
+ break;
+
+ case H5T_VLEN:
+ if(H5T_IS_VL_STRING(dt->shared))
+ s1 = "str";
+ else
+ s1 = "vlen";
+ break;
+
+ default:
+ s1 = "";
+ break;
+ } /* end switch */
+
+ switch(dt->shared->state) {
+ case H5T_STATE_TRANSIENT:
+ s2 = "[transient]";
+ break;
+
+ case H5T_STATE_RDONLY:
+ s2 = "[constant]";
+ break;
+
+ case H5T_STATE_IMMUTABLE:
+ s2 = "[predefined]";
+ break;
+
+ case H5T_STATE_NAMED:
+ s2 = "[named,closed]";
+ break;
+
+ case H5T_STATE_OPEN:
+ s2 = "[named,open]";
+ break;
+ } /* end switch */
+
+ fprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->shared->size));
+
+ if(H5T_IS_ATOMIC(dt->shared)) {
+ uint64_t tmp;
+
+ switch(dt->shared->u.atomic.order) {
+ case H5T_ORDER_BE:
+ s1 = "BE";
+ break;
+
+ case H5T_ORDER_LE:
+ s1 = "LE";
+ break;
+
+ case H5T_ORDER_VAX:
+ s1 = "VAX";
+ break;
+
+ case H5T_ORDER_NONE:
+ s1 = "NONE";
+ break;
+
+ default:
+ s1 = "order?";
+ break;
+ } /* end switch */
+
+ fprintf(stream, ", %s", s1);
+
+ if(dt->shared->u.atomic.offset)
+ fprintf(stream, ", offset=%lu",
+ (unsigned long) (dt->shared->u.atomic.offset));
+ if(dt->shared->u.atomic.prec != 8 * dt->shared->size)
+ fprintf(stream, ", prec=%lu",
+ (unsigned long) (dt->shared->u.atomic.prec));
+ switch(dt->shared->type) {
+ case H5T_INTEGER:
+ switch(dt->shared->u.atomic.u.i.sign) {
+ case H5T_SGN_NONE:
+ s1 = "unsigned";
+ break;
+
+ case H5T_SGN_2:
+ s1 = NULL;
+ break;
+
+ default:
+ s1 = "sign?";
+ break;
+
+ } /* end switch */
+ if(s1)
+ fprintf(stream, ", %s", s1);
+ break;
+
+ case H5T_FLOAT:
+ switch(dt->shared->u.atomic.u.f.norm) {
+ case H5T_NORM_IMPLIED:
+ s1 = "implied";
+ break;
+
+ case H5T_NORM_MSBSET:
+ s1 = "msbset";
+ break;
+
+ case H5T_NORM_NONE:
+ s1 = "no-norm";
+ break;
+
+ default:
+ s1 = "norm?";
+ break;
+ } /* end switch */
+
+ fprintf(stream, ", sign=%lu+1",
+ (unsigned long)(dt->shared->u.atomic.u.f.sign));
+ fprintf(stream, ", mant=%lu+%lu (%s)",
+ (unsigned long)(dt->shared->u.atomic.u.f.mpos),
+ (unsigned long)(dt->shared->u.atomic.u.f.msize), s1);
+ fprintf(stream, ", exp=%lu+%lu",
+ (unsigned long)(dt->shared->u.atomic.u.f.epos),
+ (unsigned long)(dt->shared->u.atomic.u.f.esize));
+ tmp = dt->shared->u.atomic.u.f.ebias >> 32;
+ if(tmp) {
+ size_t hi = (size_t)tmp;
+ size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
+ fprintf(stream, " bias=0x%08lx%08lx",
+ (unsigned long)hi, (unsigned long)lo);
+ } else {
+ size_t lo = (size_t)(dt->shared->u.atomic.u.f.ebias & 0xffffffff);
+ fprintf(stream, " bias=0x%08lx", (unsigned long)lo);
+ }
+ break;
+
+ default:
+ /* No additional info */
+ break;
+ } /* end switch */
+ } else if(H5T_COMPOUND == dt->shared->type) {
+ /* Compound data type */
+ for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
+ fprintf(stream, "\n\"%s\" @%lu",
+ dt->shared->u.compnd.memb[i].name,
+ (unsigned long)(dt->shared->u.compnd.memb[i].offset));
+ fprintf(stream, " ");
+ H5T_debug(dt->shared->u.compnd.memb[i].type, stream);
+ } /* end for */
+ fprintf(stream, "\n");
+ } else if(H5T_VLEN == dt->shared->type) {
+ switch(dt->shared->u.vlen.loc) {
+ case H5T_LOC_MEMORY:
+ fprintf(stream, ", loc=memory");
+ break;
+
+ case H5T_LOC_DISK:
+ fprintf(stream, ", loc=disk");
+ break;
+
+ default:
+ fprintf(stream, ", loc=UNKNOWN");
+ break;
+ } /* end switch */
+
+ if(H5T_IS_VL_STRING(dt->shared))
+ /* Variable length string datatype */
+ fprintf(stream, ", variable-length");
+ else {
+ /* Variable length sequence datatype */
+ fprintf(stream, " VLEN ");
+ H5T_debug(dt->shared->parent, stream);
+ fprintf(stream, "\n");
+ } /* end else */
+ } else if(H5T_ENUM == dt->shared->type) {
+ size_t base_size;
+
+ /* Enumeration data type */
+ fprintf(stream, " ");
+ H5T_debug(dt->shared->parent, stream);
+ base_size = dt->shared->parent->shared->size;
+ for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
+ size_t k;
+
+ fprintf(stream, "\n\"%s\" = 0x", dt->shared->u.enumer.name[i]);
+ for(k = 0; k < base_size; k++)
+ fprintf(stream, "%02lx",
+ (unsigned long)(dt->shared->u.enumer.value + (i * base_size) + k));
+ } /* end for */
+ fprintf(stream, "\n");
+ } else if(H5T_OPAQUE == dt->shared->type) {
+ fprintf(stream, ", tag=\"%s\"", dt->shared->u.opaque.tag);
+ } else {
+ /* Unknown */
+ fprintf(stream, "unknown class %d\n", (int)(dt->shared->type));
+ }
+ fprintf(stream, "}");
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5T_debug() */
+
diff --git a/src/H5Titerate.c b/src/H5Titerate.c
new file mode 100644
index 0000000..15a91e3
--- /dev/null
+++ b/src/H5Titerate.c
@@ -0,0 +1,155 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Module Info: This module contains most of the "core" functionality of
+ * the H5T interface, including the API initialization code, etc.
+ * Many routines that are infrequently used, or are specialized for
+ * one particular datatype class are in another module.
+ */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Tdbg.c
+ * Jul 19 2007
+ * Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Dump debugging information about a datatype
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5T_PACKAGE /*suppress error about including H5Tpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Tpkg.h" /* Datatypes */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_visit
+ *
+ * Purpose: Visit a datatype and all it's members and/or parents, making
+ * a callback for each.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, July 19, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_visit(H5T_t *dt, unsigned visit_flags, H5T_operator_t op, void *op_value)
+{
+ hbool_t is_complex; /* Flag indicating current datatype is "complex" */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5T_visit, FAIL)
+
+ /* Sanity check */
+ HDassert(dt);
+ HDassert(op);
+
+ /* Check for complex datatype */
+ is_complex = H5T_IS_COMPLEX(dt->shared->type);
+
+ /* If the callback is to be made on the datatype first, do that */
+ if(is_complex && (visit_flags & H5T_VISIT_COMPLEX_FIRST))
+ if(op(dt, op_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "operator callback failed")
+
+ /* Make callback for each member/child, if requested */
+ switch(dt->shared->type) {
+ case H5T_COMPOUND:
+ {
+ unsigned u; /* Local index variable */
+
+ /* Visit each member of the compound datatype */
+ for(u = 0; u < dt->shared->u.compnd.nmembs; u++)
+ if(H5T_visit(dt->shared->u.compnd.memb[u].type, visit_flags, op, op_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "can't visit member datatype")
+ } /* end case */
+ break;
+
+ case H5T_ARRAY:
+ case H5T_VLEN:
+ case H5T_ENUM:
+ /* Visit parent type */
+ if(H5T_visit(dt->shared->parent, visit_flags, op, op_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "can't visit parent datatype")
+ break;
+
+ default:
+ /* Visit "simple" datatypes here */
+ if(visit_flags & H5T_VISIT_SIMPLE)
+ if(op(dt, op_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "operator callback failed")
+ break;
+ } /* end switch */
+
+ /* If the callback is to be made on the datatype last, do that */
+ if(is_complex && (visit_flags & H5T_VISIT_COMPLEX_LAST))
+ if(op(dt, op_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "operator callback failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_iterate() */
+
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 6b68bf1..4704288 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -68,6 +68,45 @@
#define H5T_IS_ATOMIC(dt) (!(H5T_IS_COMPLEX((dt)->type) || (dt)->type==H5T_OPAQUE))
+/*
+ * Datatype encoding versions
+ */
+
+/* This is the version to create all datatypes which don't contain
+ * array datatypes (atomic types, compound datatypes without array fields,
+ * vlen sequences of objects which aren't arrays, etc.) or VAX byte-ordered
+ * objects.
+ */
+#define H5O_DTYPE_VERSION_1 1
+
+/* This is the version to create all datatypes which contain H5T_ARRAY
+ * class objects (array definitely, potentially compound & vlen sequences also),
+ * but not VAX byte-ordered objects.
+ */
+#define H5O_DTYPE_VERSION_2 2
+
+/* This is the version to create all datatypes which contain VAX byte-ordered
+ * objects (floating-point types, currently).
+ */
+/* This version also packs compound & enum field names without padding */
+/* This version also encodes the member offset of compound fields more efficiently */
+/* This version also encodes array types more efficiently */
+#define H5O_DTYPE_VERSION_3 3
+
+/* The latest version of the format. Look through the 'encode helper' routine
+ * and 'size' callback for places to change when updating this. */
+#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_3
+
+
+/* Flags for visiting datatype */
+#define H5T_VISIT_COMPLEX_FIRST 0x01 /* Visit complex datatype before visiting member/parent datatypes */
+#define H5T_VISIT_COMPLEX_LAST 0x02 /* Visit complex datatype after visiting member/parent datatypes */
+ /* (setting both flags will mean visiting complex type twice) */
+#define H5T_VISIT_SIMPLE 0x04 /* Visit simple datatypes (at all) */
+ /* (setting H5T_VISIT_SIMPLE and _not_ setting either H5T_VISIT_COMPLEX_FIRST or H5T_VISIT_COMPLEX_LAST will mean visiting _only_ "simple" "leafs" in the "tree" */
+ /* (_not_ setting H5T_VISIT_SIMPLE and setting either H5T_VISIT_COMPLEX_FIRST or H5T_VISIT_COMPLEX_LAST will mean visiting all nodes _except_ "simple" "leafs" in the "tree" */
+
+
/* Define an internal macro for converting between floating number(float and double) and floating number.
* All Cray compilers don't support denormalized floating values generating exception(?). */
#if H5_CONVERT_DENORMAL_FLOAT
@@ -314,6 +353,7 @@ typedef struct H5T_shared_t {
H5T_state_t state; /*current state of the type */
H5T_class_t type; /*which class of type is this? */
size_t size; /*total size of an instance of this type */
+ unsigned version; /* Version of object header message to encode this object with */
hbool_t force_conv;/* Set if this type always needs to be converted and H5T_conv_noop cannot be called */
struct H5T_t *parent;/*parent type for derived datatypes */
union {
@@ -362,6 +402,9 @@ typedef struct {
hid_t tcpl_id; /* Named datatype creation property list */
} H5T_obj_create_t;
+/* Typedef for datatype iteration operations */
+typedef herr_t (*H5T_operator_t)(H5T_t *dt, void *op_data/*in,out*/);
+
/*
* Alignment information for native types. A value of N indicates that the
* data must be aligned on an address ADDR such that 0 == ADDR mod N. When
@@ -458,20 +501,11 @@ H5_DLL herr_t H5T_commit_named(const H5G_loc_t *loc, const char *name,
H5T_t *dt, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id);
H5_DLL H5T_t *H5T_alloc(void);
H5_DLL herr_t H5T_free(H5T_t *dt);
-H5_DLL H5T_sign_t H5T_get_sign(H5T_t const *dt);
+H5_DLL herr_t H5T_visit(H5T_t *dt, unsigned visit_flags, H5T_operator_t op,
+ void *op_value);
H5_DLL H5T_t *H5T_get_super(H5T_t *dt);
-H5_DLL char *H5T_get_member_name(H5T_t const *dt, unsigned membno);
-H5_DLL herr_t H5T_get_member_value(const H5T_t *dt, unsigned membno, void *value);
-H5_DLL int H5T_get_nmembers(const H5T_t *dt);
-H5_DLL herr_t H5T_insert(const H5T_t *parent, const char *name, size_t offset,
- const H5T_t *member);
-H5_DLL H5T_t *H5T_enum_create(const H5T_t *parent);
-H5_DLL herr_t H5T_enum_insert(const H5T_t *dt, const char *name, const void *value);
-H5_DLL int H5T_get_array_ndims(H5T_t *dt);
-H5_DLL int H5T_get_array_dims(H5T_t *dt, hsize_t dims[]);
-H5_DLL herr_t H5T_sort_value(const H5T_t *dt, int *map);
-H5_DLL herr_t H5T_sort_name(const H5T_t *dt, int *map);
H5_DLL herr_t H5T_set_size(H5T_t *dt, size_t size);
+H5_DLL herr_t H5T_upgrade_version(H5T_t *dt, unsigned new_version);
/* Conversion functions */
H5_DLL herr_t H5T_conv_noop(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
@@ -1326,6 +1360,9 @@ H5_DLL htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size);
H5_DLL htri_t H5T_bit_dec(uint8_t *buf, size_t start, size_t size);
H5_DLL void H5T_bit_neg(uint8_t *buf, size_t start, size_t size);
+/* Fixed-point functions */
+H5_DLL H5T_sign_t H5T_get_sign(H5T_t const *dt);
+
/* VL functions */
H5_DLL H5T_t * H5T_vlen_create(const H5T_t *base);
H5_DLL htri_t H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc);
@@ -1333,13 +1370,31 @@ H5_DLL htri_t H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc);
/* Array functions */
H5_DLL H5T_t * H5T_array_create(H5T_t *base, unsigned ndims,
const hsize_t dim[/* ndims */]);
+H5_DLL int H5T_get_array_ndims(const H5T_t *dt);
+H5_DLL int H5T_get_array_dims(const H5T_t *dt, hsize_t dims[]);
/* Compound functions */
+H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset,
+ const H5T_t *member);
H5_DLL H5T_t *H5T_get_member_type(const H5T_t *dt, unsigned membno);
H5_DLL size_t H5T_get_member_offset(const H5T_t *dt, unsigned membno);
H5_DLL size_t H5T_get_member_size(const H5T_t *dt, unsigned membno);
H5_DLL htri_t H5T_is_packed(const H5T_t *dt);
H5_DLL H5T_subset_t H5T_conv_struct_subset(const H5T_cdata_t *cdata);
+/* Enumerated type functions */
+H5_DLL H5T_t *H5T_enum_create(const H5T_t *parent);
+H5_DLL herr_t H5T_enum_insert(const H5T_t *dt, const char *name, const void *value);
+H5_DLL herr_t H5T_get_member_value(const H5T_t *dt, unsigned membno, void *value);
+
+/* Field functions (for both compound & enumerated types) */
+H5_DLL char *H5T_get_member_name(H5T_t const *dt, unsigned membno);
+H5_DLL int H5T_get_nmembers(const H5T_t *dt);
+H5_DLL herr_t H5T_sort_value(const H5T_t *dt, int *map);
+H5_DLL herr_t H5T_sort_name(const H5T_t *dt, int *map);
+
+/* Debugging functions */
+H5_DLL herr_t H5T_print_stats(H5T_path_t *path, int *nprint/*in,out*/);
+
#endif /* _H5Tpkg_H */
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 842eced..deeb8ce 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -114,6 +114,7 @@ H5_DLL herr_t H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_
H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
H5_DLL htri_t H5T_is_sensible(const H5T_t *dt);
H5_DLL uint32_t H5T_hash(H5F_t * file, const H5T_t *dt);
+H5_DLL herr_t H5T_set_latest_version(H5T_t *dt);
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index 1d71498..bbc698f 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -115,20 +115,20 @@ H5Tvlen_create(hid_t base_id)
H5TRACE1("i", "i", base_id);
/* Check args */
- if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE)))
+ if(NULL == (base = H5I_object_verify(base_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
/* Create up VL datatype */
- if ((dt=H5T_vlen_create(base))==NULL)
+ if((dt = H5T_vlen_create(base)) == NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location")
/* Atomize the type */
- if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dt)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tvlen_create() */
/*-------------------------------------------------------------------------
@@ -157,7 +157,7 @@ H5T_vlen_create(const H5T_t *base)
FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_create)
/* Check args */
- assert(base);
+ HDassert(base);
/* Build new type */
if(NULL == (dt = H5T_alloc()))
@@ -171,19 +171,22 @@ H5T_vlen_create(const H5T_t *base)
dt->shared->force_conv = TRUE;
dt->shared->parent = H5T_copy(base, H5T_COPY_ALL);
+ /* Inherit encoding version from base type */
+ dt->shared->version = base->shared->version;
+
/* This is a sequence, not a string */
dt->shared->u.vlen.type = H5T_VLEN_SEQUENCE;
/* Set up VL information */
- if (H5T_set_loc(dt, NULL, H5T_LOC_MEMORY)<0)
+ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
/* Set return value */
- ret_value=dt;
+ ret_value = dt;
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5T_vlen_create() */
/*-------------------------------------------------------------------------
@@ -284,7 +287,7 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
break;
default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location")
} /* end switch */ /*lint !e788 All appropriate cases are covered */
} /* end if */
diff --git a/src/Makefile.am b/src/Makefile.am
index bef62b6..b52afbc 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -78,10 +78,12 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5R.c H5RC.c \
H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
H5Sselect.c H5Stest.c H5SL.c H5SM.c H5SMbtree2.c \
- H5SMcache.c H5SMtest.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
- H5Tcompound.c H5Tconv.c H5Tcset.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
+ H5SMcache.c H5SMtest.c H5ST.c \
+ H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c H5Tcompound.c H5Tconv.c \
+ H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
H5Tfixed.c \
- H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
+ H5Tfloat.c H5Tinit.c H5Titerate.c H5Tnative.c H5Toffset.c H5Toh.c \
+ H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 1f82a69..ce657cf 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -111,9 +111,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5S.lo H5Sall.lo H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo \
H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo \
H5SMcache.lo H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo \
- H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdeprec.lo \
+ H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo \
H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \
- H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \
+ H5Titerate.lo H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \
H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo \
H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo \
H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
@@ -434,9 +434,9 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
H5Sselect.c H5Stest.c H5SL.c H5SM.c H5SMbtree2.c \
H5SMcache.c H5SMtest.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
- H5Tcompound.c H5Tconv.c H5Tcset.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
+ H5Tcompound.c H5Tconv.c H5Tcset.c H5Tdbg.c H5Tdeprec.c H5Tenum.c H5Tfields.c \
H5Tfixed.c \
- H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
+ H5Tfloat.c H5Tinit.c H5Titerate.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
@@ -745,12 +745,14 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tcompound.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tconv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tcset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tdeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tenum.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tfields.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tfixed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tfloat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tinit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Titerate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tnative.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Toffset.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Toh.Plo@am__quote@