summaryrefslogtreecommitdiffstats
path: root/src/H5Odtype.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2000-11-09 21:45:27 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2000-11-09 21:45:27 (GMT)
commite32c78d023348c70255c3835a4f904862414fb0d (patch)
treebec2363f2d5cd8811522f80114e70efa72d2c196 /src/H5Odtype.c
parent796b4daf83110a1e61f754eeb0ab7be625b0e98a (diff)
downloadhdf5-e32c78d023348c70255c3835a4f904862414fb0d.zip
hdf5-e32c78d023348c70255c3835a4f904862414fb0d.tar.gz
hdf5-e32c78d023348c70255c3835a4f904862414fb0d.tar.bz2
[svn-r2843] Purpose:
New Feature Description: Added array datatype to library. See documentation at: http://hdf.ncsa.uiuc.edu/HDF5/planning/DP/ArrayType.html for complete details on the impact to the library. Solution: Changes to the base library include removing the ability of compound datatype fields to be an array (they can use an array type for the field, to duplicate the functionality) and adding in the new array datatype everywhere appropriate. (I hope :-) Platforms tested: FreeBSD 4.1.1 (hawkwind)
Diffstat (limited to 'src/H5Odtype.c')
-rw-r--r--src/H5Odtype.c315
1 files changed, 213 insertions, 102 deletions
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index b4ff181..0a505ae 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -58,7 +58,14 @@ const H5O_class_t H5O_DTYPE[1] = {{
H5O_dtype_debug, /* debug the message */
}};
-#define H5O_DTYPE_VERSION 1
+/* This is the correct 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.) */
+#define H5O_DTYPE_VERSION_COMPAT 1
+
+/* This is the correct version to create all datatypes which contain H5T_ARRAY
+ * class objects (array definitely, potentially compound & vlen sequences also) */
+#define H5O_DTYPE_VERSION_UPDATED 2
/* Interface initialization */
static intn interface_initialize_g = 0;
@@ -86,7 +93,7 @@ H5FL_EXTERN(H5T_t);
static herr_t
H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
{
- uintn flags, perm_word, version;
+ uintn flags, version;
intn i, j;
size_t z;
@@ -99,8 +106,8 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* decode */
UINT32DECODE(*pp, flags);
version = (flags>>4) & 0x0f;
- if (version!=H5O_DTYPE_VERSION) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL,
+ if (version!=H5O_DTYPE_VERSION_COMPAT && version!=H5O_DTYPE_VERSION_UPDATED) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL,
"bad version number for data type message");
}
dt->type = (H5T_class_t)(flags & 0x0f);
@@ -194,53 +201,94 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
"memory allocation failed");
}
for (i = 0; i < dt->u.compnd.nmembs; i++) {
+ intn ndims; /* Number of dimensions of the array field */
+ hsize_t dim[H5O_LAYOUT_NDIMS]; /* Dimensions of the array */
+ int perm[H5O_LAYOUT_NDIMS]; /* Dimension permutations */
+ uintn perm_word; /* Dimension permutation information */
+ H5T_t *array_dt; /* Temporary pointer to the array datatype */
+ H5T_t *temp_type; /* Temporary pointer to the field's datatype */
+
+ /* Decode the field name */
dt->u.compnd.memb[i].name = H5MM_xstrdup((const char *)*pp);
/*multiple of 8 w/ null terminator */
*pp += ((HDstrlen((const char *)*pp) + 8) / 8) * 8;
+
+ /* Decode the field offset */
UINT32DECODE(*pp, dt->u.compnd.memb[i].offset);
- dt->u.compnd.memb[i].ndims = *(*pp)++;
- assert(dt->u.compnd.memb[i].ndims <= 4);
- *pp += 3; /*reserved bytes */
-
- /* Dimension permutation */
- UINT32DECODE(*pp, perm_word);
- dt->u.compnd.memb[i].perm[0] = (perm_word >> 0) & 0xff;
- dt->u.compnd.memb[i].perm[1] = (perm_word >> 8) & 0xff;
- dt->u.compnd.memb[i].perm[2] = (perm_word >> 16) & 0xff;
- dt->u.compnd.memb[i].perm[3] = (perm_word >> 24) & 0xff;
- dt->u.compnd.memb[i].type = H5FL_ALLOC (H5T_t,1);
- if (NULL==dt->u.compnd.memb[i].type) {
+
+ /* Older versions of the library allowed a field to have
+ * intrinsic 'arrayness'. Newer versions of the library
+ * use the separate array datatypes. */
+ if(version==H5O_DTYPE_VERSION_COMPAT) {
+ /* Decode the number of dimensions */
+ ndims = *(*pp)++;
+ assert(ndims <= 4);
+ *pp += 3; /*reserved bytes */
+
+ /* Decode dimension permutation (unused currently) */
+ UINT32DECODE(*pp, perm_word);
+
+ /* Skip reserved bytes */
+ *pp += 4;
+
+ /* Decode array dimension sizes */
+ for (j=0; j<4; j++)
+ UINT32DECODE(*pp, dim[j]);
+ } /* end if */
+
+ /* Allocate space for the field's datatype */
+ temp_type = H5FL_ALLOC (H5T_t,1);
+ if (NULL==temp_type) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
+ temp_type->ent.header = HADDR_UNDEF;
- /* Reserved */
- *pp += 4;
-
- /* Dimension sizes */
- for (j=0; j<4; j++)
- UINT32DECODE(*pp, dt->u.compnd.memb[i].dim[j]);
-
- dt->u.compnd.memb[i].type->ent.header = HADDR_UNDEF;
- if (H5O_dtype_decode_helper(f, pp, dt->u.compnd.memb[i].type)<0) {
+ /* Decode the field's datatype information */
+ if (H5O_dtype_decode_helper(f, pp, temp_type)<0) {
for (j=0; j<=i; j++)
H5MM_xfree(dt->u.compnd.memb[j].name);
H5MM_xfree(dt->u.compnd.memb);
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL,
- "unable to decode member type");
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type");
}
+ /* Go create the array datatype now, for older versions of the datatype message */
+ if(version==H5O_DTYPE_VERSION_COMPAT) {
+ /* Check if this member is an array field */
+ if(ndims>0) {
+ /* Set up the permutation vector for the array create */
+ for (j=0; j<ndims; j++)
+ perm[j]=(perm_word>>(j*8))&0xff;
+
+ /* Create the array datatype for the field */
+ if ((array_dt=H5T_array_create(temp_type,ndims,dim,perm))==NULL) {
+ for (j=0; j<=i; j++)
+ H5MM_xfree(dt->u.compnd.memb[j].name);
+ H5MM_xfree(dt->u.compnd.memb);
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create array datatype");
+ }
+
+ /* Make the array type the type that is set for the field */
+ temp_type=array_dt;
+ } /* end if */
+ } /* end if */
+
/*
* Set the "force conversion" flag if VL datatype fields exist in this
* type or any component types
*/
- if(dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->force_conv==TRUE)
+ if(temp_type->type==H5T_VLEN || temp_type->force_conv==TRUE)
dt->force_conv=TRUE;
-
- /* Total member size */
- dt->u.compnd.memb[i].size = dt->u.compnd.memb[i].type->size;
- for (j=0; j<dt->u.compnd.memb[i].ndims; j++)
- dt->u.compnd.memb[i].size *= dt->u.compnd.memb[i].dim[j];
+
+ /* Set the "has array" flag if array datatype fields exist in this type */
+ if(temp_type->type==H5T_ARRAY)
+ dt->u.compnd.has_array=TRUE;
+
+ /* Member size */
+ dt->u.compnd.memb[i].size = temp_type->size;
+
+ /* Set the field datatype (finally :-) */
+ dt->u.compnd.memb[i].type=temp_type;
}
break;
@@ -327,11 +375,43 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
UINT16DECODE(*pp, dt->u.atomic.prec);
break;
+ case H5T_ARRAY: /* Array datatypes... */
+ /* Decode the number of dimensions */
+ dt->u.array.ndims = *(*pp)++;
+
+ /* Double-check the number of dimensions */
+ assert(dt->u.array.ndims <= H5S_MAX_RANK);
+
+ /* Skip reserved bytes */
+ *pp += 3;
+
+ /* Decode array dimension sizes & compute number of elements */
+ for (j=0, dt->u.array.nelem=1; j<dt->u.array.ndims; j++) {
+ UINT32DECODE(*pp, dt->u.array.dim[j]);
+ dt->u.array.nelem *= dt->u.array.dim[j];
+ } /* end for */
+
+ /* Skip dimension permutations (unused currently) */
+ *pp += 4*dt->u.array.ndims;
+
+ /* Decode base type of array */
+ if (NULL==(dt->parent = H5FL_ALLOC(H5T_t,1)))
+ HRETURN_ERROR (H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ dt->parent->ent.header = HADDR_UNDEF;
+ if (H5O_dtype_decode_helper(f, pp, dt->parent)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type");
+
+ /*
+ * Set the "force conversion" flag if a VL base datatype is used or
+ * or if any components of the base datatype are VL types.
+ */
+ if(dt->parent->type==H5T_VLEN || dt->parent->force_conv==TRUE)
+ dt->force_conv=TRUE;
+ break;
+
default:
- if (flags) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
- "class flags are non-zero");
- }
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unknown datatype class found");
break;
}
@@ -358,7 +438,6 @@ static herr_t
H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
{
uintn flags = 0;
- uintn perm_word;
char *hdr = (char *)*pp;
intn i, j;
size_t n, z, aligned;
@@ -369,7 +448,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
assert(pp && *pp);
assert(dt);
- /* skip the type and class bit field for now */
+ /* skip the type and class bit-field for now */
*pp += 4;
UINT32ENCODE(*pp, dt->size);
@@ -574,31 +653,29 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
/* Member offset */
UINT32ENCODE(*pp, dt->u.compnd.memb[i].offset);
- /* Dimensionality */
- *(*pp)++ = dt->u.compnd.memb[i].ndims;
- assert(dt->u.compnd.memb[i].ndims <= 4);
-
- /* Reserved */
- *(*pp)++ = '\0';
- *(*pp)++ = '\0';
- *(*pp)++ = '\0';
+ /* If we don't have any array fields, write out the old style
+ * member information, for better backward compatibility
+ * Write out all zeros for the array information, though...
+ */
+ if(!dt->u.compnd.has_array) {
+ /* Dimensionality */
+ *(*pp)++ = 0;
- /* Dimension permutation */
- for (j = 0, perm_word = 0; j < dt->u.compnd.memb[i].ndims; j++) {
- perm_word |= dt->u.compnd.memb[i].perm[j] << (8 * j);
- }
- UINT32ENCODE(*pp, perm_word);
+ /* Reserved */
+ *(*pp)++ = '\0';
+ *(*pp)++ = '\0';
+ *(*pp)++ = '\0';
- /* Reserved */
- UINT32ENCODE(*pp, 0);
+ /* Dimension permutation */
+ UINT32ENCODE(*pp, 0);
- /* Dimensions */
- for (j=0; j<dt->u.compnd.memb[i].ndims; j++) {
- UINT32ENCODE(*pp, dt->u.compnd.memb[i].dim[j]);
- }
- for (/*void*/; j<4; j++) {
+ /* Reserved */
UINT32ENCODE(*pp, 0);
- }
+
+ /* Dimensions */
+ for (j=0; j<4; j++)
+ UINT32ENCODE(*pp, 0);
+ } /* end if */
/* Subtype */
if (H5O_dtype_encode_helper(pp, dt->u.compnd.memb[i].type)<0) {
@@ -675,12 +752,37 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
UINT16ENCODE(*pp, dt->u.atomic.prec);
break;
+ case H5T_ARRAY: /* Array datatypes... */
+ /* Double-check the number of dimensions */
+ assert(dt->u.array.ndims <= H5S_MAX_RANK);
+
+ /* Encode the number of dimensions */
+ *(*pp)++ = dt->u.array.ndims;
+
+ /* Reserved */
+ *(*pp)++ = '\0';
+ *(*pp)++ = '\0';
+ *(*pp)++ = '\0';
+
+ /* Encode array dimensions */
+ for (j=0; j<dt->u.array.ndims; j++)
+ UINT32ENCODE(*pp, dt->u.array.dim[j]);
+
+ /* Encode array dimension permutations */
+ for (j=0; j<dt->u.array.ndims; j++)
+ UINT32ENCODE(*pp, dt->u.array.perm[j]);
+
+ /* Encode base type of array's information */
+ if (H5O_dtype_encode_helper(pp, dt->parent)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type");
+ break;
+
default:
/*nothing */
break;
}
- *hdr++ = ((uintn)(dt->type) & 0x0f) | (H5O_DTYPE_VERSION<<4);
+ *hdr++ = ((uintn)(dt->type) & 0x0f) | (((dt->type==H5T_COMPOUND && dt->u.compnd.has_array) ? H5O_DTYPE_VERSION_UPDATED : H5O_DTYPE_VERSION_COMPAT )<<4);
*hdr++ = (flags >> 0) & 0xff;
*hdr++ = (flags >> 8) & 0xff;
*hdr++ = (flags >> 16) & 0xff;
@@ -837,54 +939,61 @@ H5O_dtype_size(H5F_t *f, const void *mesg)
assert(mesg);
switch (dt->type) {
- case H5T_INTEGER:
- ret_value += 4;
- break;
+ case H5T_INTEGER:
+ ret_value += 4;
+ break;
- case H5T_BITFIELD:
- ret_value += 4;
- break;
+ case H5T_BITFIELD:
+ ret_value += 4;
+ break;
- case H5T_OPAQUE:
- ret_value += (HDstrlen(dt->u.opaque.tag)+7) & 0xf8;
- break;
+ case H5T_OPAQUE:
+ ret_value += (HDstrlen(dt->u.opaque.tag)+7) & 0xf8;
+ break;
- case H5T_FLOAT:
- ret_value += 12;
- break;
+ case H5T_FLOAT:
+ ret_value += 12;
+ break;
- case H5T_COMPOUND:
- for (i=0; i<dt->u.compnd.nmembs; i++) {
- ret_value += ((HDstrlen(dt->u.compnd.memb[i].name) + 8) / 8) * 8;
- ret_value += 4 + /*member offset*/
- 1 + /*dimensionality*/
- 3 + /*reserved*/
- 4 + /*permutation*/
- 4 + /*reserved*/
- 16; /*dimensions*/
- ret_value += H5O_dtype_size(f, dt->u.compnd.memb[i].type);
- }
- break;
+ case H5T_COMPOUND:
+ for (i=0; i<dt->u.compnd.nmembs; i++) {
+ ret_value += ((HDstrlen(dt->u.compnd.memb[i].name) + 8) / 8) * 8;
+ ret_value += 4 + /*member offset*/
+ 1 + /*dimensionality*/
+ 3 + /*reserved*/
+ 4 + /*permutation*/
+ 4 + /*reserved*/
+ 16; /*dimensions*/
+ ret_value += H5O_dtype_size(f, dt->u.compnd.memb[i].type);
+ }
+ break;
- case H5T_ENUM:
- ret_value += H5O_dtype_size(f, dt->parent);
- for (i=0; i<dt->u.enumer.nmembs; i++) {
- ret_value += ((HDstrlen(dt->u.enumer.name[i])+8)/8)*8;
- }
- ret_value += dt->u.enumer.nmembs * dt->parent->size;
- break;
+ case H5T_ENUM:
+ ret_value += H5O_dtype_size(f, dt->parent);
+ for (i=0; i<dt->u.enumer.nmembs; i++) {
+ ret_value += ((HDstrlen(dt->u.enumer.name[i])+8)/8)*8;
+ }
+ ret_value += dt->u.enumer.nmembs * dt->parent->size;
+ break;
+
+ case H5T_VLEN:
+ ret_value += H5O_dtype_size(f, dt->parent);
+ break;
- case H5T_VLEN:
- ret_value += H5O_dtype_size(f, dt->parent);
- break;
+ case H5T_TIME:
+ ret_value += 2;
+ break;
- case H5T_TIME:
- ret_value += 2;
- break;
+ case H5T_ARRAY:
+ ret_value += 4; /* ndims & reserved bytes*/
+ ret_value += 4*dt->u.array.ndims; /* dimensions */
+ ret_value += 4*dt->u.array.ndims; /* dimension permutations */
+ ret_value += H5O_dtype_size(f, dt->parent);
+ break;
- default:
- /*no properties */
- break;
+ default:
+ /*no properties */
+ break;
}
FUNC_LEAVE(ret_value);
@@ -1048,7 +1157,7 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE *stream,
const H5T_t *dt = (const H5T_t*)mesg;
const char *s;
char buf[256];
- intn i, j;
+ intn i;
size_t k;
@@ -1111,6 +1220,7 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE *stream,
fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0, fwidth-3),
"Byte offset:",
(unsigned long) (dt->u.compnd.memb[i].offset));
+#ifdef OLD_WAY
fprintf(stream, "%*s%-*s %d%s\n", indent+3, "", MAX(0, fwidth-3),
"Dimensionality:",
dt->u.compnd.memb[i].ndims,
@@ -1131,6 +1241,7 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE *stream,
}
fprintf(stream, "}\n");
}
+#endif /* OLD_WAY */
H5O_dtype_debug(f, dt->u.compnd.memb[i].type, stream,
indent+3, MAX(0, fwidth - 3));
}