diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2000-11-09 21:45:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2000-11-09 21:45:27 (GMT) |
commit | e32c78d023348c70255c3835a4f904862414fb0d (patch) | |
tree | bec2363f2d5cd8811522f80114e70efa72d2c196 /src | |
parent | 796b4daf83110a1e61f754eeb0ab7be625b0e98a (diff) | |
download | hdf5-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')
-rw-r--r-- | src/H5Odtype.c | 315 | ||||
-rw-r--r-- | src/H5RA.c | 11 | ||||
-rw-r--r-- | src/H5T.c | 1493 | ||||
-rw-r--r-- | src/H5Tconv.c | 353 | ||||
-rw-r--r-- | src/H5Tpkg.h | 33 | ||||
-rw-r--r-- | src/H5Tprivate.h | 5 | ||||
-rw-r--r-- | src/H5Tpublic.h | 11 | ||||
-rw-r--r-- | src/H5Tvlen.c | 90 |
8 files changed, 1347 insertions, 964 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)); } @@ -86,13 +86,10 @@ H5RA_init_interface(void) /* The meta dataset type */ if (NULL==(type=H5T_create(H5T_COMPOUND, sizeof(H5RA_meta_t))) || - H5T_struct_insert(type, "nelmts", HOFFSET(H5RA_meta_t, nelmts), - 0, NULL, NULL, H5I_object(H5T_NATIVE_HSIZE_g))<0 || - H5T_struct_insert(type, "offset", HOFFSET(H5RA_meta_t, offset), - 0, NULL, NULL, H5I_object(H5T_NATIVE_HSSIZE_g))<0 || - H5T_struct_insert(type, "nover", HOFFSET(H5RA_meta_t, nover), - 0, NULL, NULL, H5I_object(H5T_NATIVE_HSIZE_g))) { - HRETURN_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL, + H5T_insert(type, "nelmts", HOFFSET(H5RA_meta_t, nelmts), H5I_object(H5T_NATIVE_HSIZE_g))<0 || + H5T_insert(type, "offset", HOFFSET(H5RA_meta_t, offset), H5I_object(H5T_NATIVE_HSSIZE_g))<0 || + H5T_insert(type, "nover", HOFFSET(H5RA_meta_t, nover), H5I_object(H5T_NATIVE_HSIZE_g))) { + HRETURN_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL, "unable to define ragged array meta type"); } H5RA_meta_type_g = type; @@ -245,7 +245,8 @@ H5T_init_interface(void) { H5T_t *dt = NULL; hid_t fixedpt=-1, floatpt=-1, string=-1, compound=-1, enum_type=-1; - hid_t vlen_type=-1, bitfield=-1; + hid_t vlen_type=-1, bitfield=-1, array_type=-1; + hsize_t dim[1]={1}; /* Dimension info for array datatype */ herr_t status; herr_t ret_value=FAIL; @@ -947,6 +948,7 @@ H5T_init_interface(void) compound = H5Tcreate(H5T_COMPOUND, 1); enum_type = H5Tcreate(H5T_ENUM, 1); vlen_type = H5Tvlen_create(H5T_NATIVE_INT); + array_type = H5Tarray_create(H5T_NATIVE_INT,1,dim,NULL); status = 0; status |= H5Tregister(H5T_PERS_SOFT, "i_i", @@ -979,6 +981,9 @@ H5T_init_interface(void) status |= H5Tregister(H5T_PERS_SOFT, "vlen", vlen_type, vlen_type, H5T_conv_vlen); + status |= H5Tregister(H5T_PERS_SOFT, "array", + array_type, array_type, + H5T_conv_array); status |= H5Tregister(H5T_PERS_HARD, "u32le_f64le", H5T_STD_U32LE_g, H5T_IEEE_F64LE_g, @@ -1963,9 +1968,9 @@ H5Tset_size(hid_t type_id, size_t size) HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); } - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for this datatype"); } /* Do the work */ @@ -2012,7 +2017,7 @@ H5Tget_order(hid_t type_id) "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY ==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); } @@ -2065,7 +2070,7 @@ H5Tset_order(hid_t type_id, H5T_order_t order) "operation not allowed after members are defined"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); } @@ -2114,7 +2119,7 @@ H5Tget_precision(hid_t type_id) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type"); } @@ -2240,7 +2245,7 @@ H5Tget_offset(hid_t type_id) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); } @@ -2359,7 +2364,7 @@ H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); } @@ -2413,7 +2418,7 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb) "operation not allowed after members are defined"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); } @@ -3308,56 +3313,6 @@ H5Tget_member_offset(hid_t type_id, int membno) /*------------------------------------------------------------------------- - * Function: H5Tget_member_dims - * - * Purpose: Returns the dimensionality of the member. The dimensions and - * permuation vector are returned through arguments DIMS and - * PERM, both arrays of at least four elements. Either (or even - * both) may be null pointers. - * - * Return: Success: A value between zero and four, inclusive. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, January 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5Tget_member_dims(hid_t type_id, int membno, - size_t dims[]/*out*/, int perm[]/*out*/) -{ - H5T_t *dt = NULL; - intn ndims, i; - - FUNC_ENTER(H5Tget_member_dims, FAIL); - H5TRACE4("Is","iIsxx",type_id,membno,dims,perm); - - /* Check args */ - if (H5I_DATATYPE != H5I_get_type(type_id) || - NULL == (dt = H5I_object(type_id)) || - H5T_COMPOUND != dt->type) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - } - if (membno < 0 || membno >= dt->u.compnd.nmembs) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); - } - - /* Value */ - ndims = dt->u.compnd.memb[membno].ndims; - for (i = 0; i < ndims; i++) { - if (dims) dims[i] = dt->u.compnd.memb[membno].dim[i]; - if (perm) perm[i] = dt->u.compnd.memb[membno].perm[i]; - } - - FUNC_LEAVE(ndims); -} - - -/*------------------------------------------------------------------------- * Function: H5Tget_member_type * * Purpose: Returns the data type of the specified member. The caller @@ -3467,79 +3422,8 @@ H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id) } /* Insert */ - if (H5T_struct_insert(parent, name, offset, 0, NULL, NULL, member) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, - "unable to insert member"); - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Tinsert_array - * - * Purpose: Adds another member to the compound data type PARENT_ID. The - * new member has a NAME which must be unique within the - * compound data type. The OFFSET argument defines the start of - * the member in an instance of the compound data type and - * MEMBER_ID is the type of the new member. The member is an - * array with NDIMS dimensionality and the size of the array is - * DIMS. The total member size should be relatively small. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Tuesday, July 7, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tinsert_array(hid_t parent_id, const char *name, size_t offset, - int ndims, const size_t dim[/*ndims*/], const int *perm, - hid_t member_id) -{ - H5T_t *parent = NULL; /*the compound parent data type */ - H5T_t *member = NULL; /*the atomic member type */ - intn i; - - FUNC_ENTER(H5Tinsert_array, FAIL); - H5TRACE7("e","iszIs*[a3]z*Isi",parent_id,name,offset,ndims,dim,perm, - member_id); - - /* Check args */ - if (H5I_DATATYPE != H5I_get_type(parent_id) || - NULL == (parent = H5I_object(parent_id)) || - H5T_COMPOUND != parent->type) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - } - if (H5T_STATE_TRANSIENT!=parent->state) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only"); - } - if (!name || !*name) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name"); - } - if (ndims<0 || ndims>4) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimensionality"); - } - if (ndims>0 && !dim) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); - } - for (i=0; i<ndims; i++) { - if (dim[i]<1) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimension"); - } - } - if (H5I_DATATYPE != H5I_get_type(member_id) || - NULL == (member = H5I_object(member_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - } - - /* Insert */ - if (H5T_struct_insert(parent, name, offset, ndims, dim, perm, member)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, + if (H5T_insert(parent, name, offset, member) < 0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member"); } @@ -4583,58 +4467,62 @@ H5T_create(H5T_class_t type, size_t size) assert(size > 0); switch (type) { - case H5T_INTEGER: - case H5T_FLOAT: - case H5T_TIME: - case H5T_STRING: - case H5T_BITFIELD: - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, - "type class is not appropriate - use H5Tcopy()"); + case H5T_INTEGER: + case H5T_FLOAT: + case H5T_TIME: + case H5T_STRING: + case H5T_BITFIELD: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, + "type class is not appropriate - use H5Tcopy()"); - case H5T_OPAQUE: - case H5T_COMPOUND: - if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - dt->type = type; - break; + case H5T_OPAQUE: + case H5T_COMPOUND: + if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + dt->type = type; + break; - case H5T_ENUM: - if (sizeof(char)==size) { - subtype = H5T_NATIVE_SCHAR_g; - } else if (sizeof(short)==size) { - subtype = H5T_NATIVE_SHORT_g; - } else if (sizeof(int)==size) { - subtype = H5T_NATIVE_INT_g; - } else if (sizeof(long)==size) { - subtype = H5T_NATIVE_LONG_g; - } else if (sizeof(long_long)==size) { - subtype = H5T_NATIVE_LLONG_g; - } else { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, - "no applicable native integer type"); - } - if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - dt->type = type; - if (NULL==(dt->parent=H5T_copy(H5I_object(subtype), - H5T_COPY_ALL))) { - H5FL_FREE(H5T_t,dt); - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, - "unable to copy base data type"); - } - break; + case H5T_ENUM: + if (sizeof(char)==size) { + subtype = H5T_NATIVE_SCHAR_g; + } else if (sizeof(short)==size) { + subtype = H5T_NATIVE_SHORT_g; + } else if (sizeof(int)==size) { + subtype = H5T_NATIVE_INT_g; + } else if (sizeof(long)==size) { + subtype = H5T_NATIVE_LONG_g; + } else if (sizeof(long_long)==size) { + subtype = H5T_NATIVE_LLONG_g; + } else { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "no applicable native integer type"); + } + if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + dt->type = type; + if (NULL==(dt->parent=H5T_copy(H5I_object(subtype), + H5T_COPY_ALL))) { + H5FL_FREE(H5T_t,dt); + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to copy base data type"); + } + break; - case H5T_VLEN: /* Variable length datatype */ - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, - "base type required - use H5Tvlen_create()"); + case H5T_VLEN: /* Variable length datatype */ + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, + "base type required - use H5Tvlen_create()"); - default: - HRETURN_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL, - "unknown data type class"); + case H5T_ARRAY: /* Array datatype */ + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, + "base type required - use H5Tarray_create()"); + + default: + HRETURN_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL, + "unknown data type class"); } dt->ent.header = HADDR_UNDEF; @@ -4808,147 +4696,167 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) /* check args */ assert(old_dt); - /* copy */ + /* Allocate space */ if (NULL==(new_dt = H5FL_ALLOC(H5T_t,0))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } + + /* Copy actual information */ *new_dt = *old_dt; - /* copy parent */ - if (new_dt->parent) { + /* Copy parent information */ + if (new_dt->parent) new_dt->parent = H5T_copy(new_dt->parent, method); - } + /* Check what sort of copy we are making */ switch (method) { - case H5T_COPY_TRANSIENT: - /* - * Return an unlocked transient type. - */ - new_dt->state = H5T_STATE_TRANSIENT; - HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent)); - new_dt->ent.header = HADDR_UNDEF; - break; - - case H5T_COPY_ALL: - /* - * Return a transient type (locked or unlocked) or an unopened named - * type. Immutable transient types are degraded to read-only. - */ - if (H5T_STATE_OPEN==new_dt->state) { - new_dt->state = H5T_STATE_NAMED; - } else if (H5T_STATE_IMMUTABLE==new_dt->state) { - new_dt->state = H5T_STATE_RDONLY; - } - break; + case H5T_COPY_TRANSIENT: + /* + * Return an unlocked transient type. + */ + new_dt->state = H5T_STATE_TRANSIENT; + HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent)); + new_dt->ent.header = HADDR_UNDEF; + break; + + case H5T_COPY_ALL: + /* + * Return a transient type (locked or unlocked) or an unopened named + * type. Immutable transient types are degraded to read-only. + */ + if (H5T_STATE_OPEN==new_dt->state) { + new_dt->state = H5T_STATE_NAMED; + } else if (H5T_STATE_IMMUTABLE==new_dt->state) { + new_dt->state = H5T_STATE_RDONLY; + } + break; - case H5T_COPY_REOPEN: - /* - * Return a transient type (locked or unlocked) or an opened named - * type. - */ - if (H5F_addr_defined(new_dt->ent.header)) { - if (H5O_open (&(new_dt->ent))<0) { - H5FL_FREE (H5T_t,new_dt); - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, - "unable to reopen named data type"); - } - new_dt->state = H5T_STATE_OPEN; - } - break; - } + case H5T_COPY_REOPEN: + /* + * Return a transient type (locked or unlocked) or an opened named + * type. + */ + if (H5F_addr_defined(new_dt->ent.header)) { + if (H5O_open (&(new_dt->ent))<0) { + H5FL_FREE (H5T_t,new_dt); + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, + "unable to reopen named data type"); + } + new_dt->state = H5T_STATE_OPEN; + } + break; + } /* end switch */ - if (H5T_COMPOUND == new_dt->type) { - intn accum_change=0; /* Amount of change in the offset of the fields */ + switch(new_dt->type) { + case H5T_COMPOUND: + { + intn accum_change=0; /* Amount of change in the offset of the fields */ + + /* + * Copy all member fields to new type, then overwrite the + * name and type fields of each new member with copied values. + * That is, H5T_copy() is a deep copy. + */ + new_dt->u.compnd.memb = H5MM_malloc(new_dt->u.compnd.nalloc * + sizeof(H5T_cmemb_t)); + if (NULL==new_dt->u.compnd.memb) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } - /* - * Copy all member fields to new type, then overwrite the - * name and type fields of each new member with copied values. - * That is, H5T_copy() is a deep copy. - */ - new_dt->u.compnd.memb = H5MM_malloc(new_dt->u.compnd.nalloc * - sizeof(H5T_cmemb_t)); - if (NULL==new_dt->u.compnd.memb) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } + HDmemcpy(new_dt->u.compnd.memb, old_dt->u.compnd.memb, + new_dt->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + + for (i=0; i<new_dt->u.compnd.nmembs; i++) { + intn j; + intn old_match; + + s = new_dt->u.compnd.memb[i].name; + new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s); + tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method); + new_dt->u.compnd.memb[i].type = tmp; + + /* Apply the accumulated size change to the offset of the field */ + new_dt->u.compnd.memb[i].offset += accum_change; + + if(old_dt->u.compnd.sorted != H5T_SORT_VALUE) { + for (old_match=-1, j=0; j<old_dt->u.compnd.nmembs; j++) { + if(!HDstrcmp(new_dt->u.compnd.memb[i].name,old_dt->u.compnd.memb[j].name)) { + old_match=j; + break; + } /* end if */ + } /* end for */ + + /* check if we couldn't find a match */ + if(old_match<0) + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted"); + } /* end if */ + else { + old_match=i; + } /* end else */ + + /* If the field changed size, add that change to the accumulated size change */ + if(new_dt->u.compnd.memb[i].type->size != old_dt->u.compnd.memb[old_match].type->size) { + /* Adjust the size of the member */ + new_dt->u.compnd.memb[i].size = (old_dt->u.compnd.memb[old_match].size*tmp->size)/old_dt->u.compnd.memb[old_match].type->size; + + accum_change += (new_dt->u.compnd.memb[i].type->size - old_dt->u.compnd.memb[old_match].type->size); + } /* end if */ + } /* end for */ + + /* Apply the accumulated size change to the size of the compound struct */ + new_dt->size += accum_change; - HDmemcpy(new_dt->u.compnd.memb, old_dt->u.compnd.memb, - new_dt->u.compnd.nmembs * sizeof(H5T_cmemb_t)); - - for (i=0; i<new_dt->u.compnd.nmembs; i++) { - intn j; - intn old_match; - - s = new_dt->u.compnd.memb[i].name; - new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s); - tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method); - new_dt->u.compnd.memb[i].type = tmp; - - /* Apply the accumulated size change to the offset of the field */ - new_dt->u.compnd.memb[i].offset += accum_change; - - if(old_dt->u.compnd.sorted != H5T_SORT_VALUE) { - for (old_match=-1, j=0; j<old_dt->u.compnd.nmembs; j++) { - if(!HDstrcmp(new_dt->u.compnd.memb[i].name,old_dt->u.compnd.memb[j].name)) { - old_match=j; - break; - } /* end if */ - } /* end for */ - - /* check if we couldn't find a match */ - if(old_match<0) - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted"); - } /* end if */ - else { - old_match=i; - } /* end else */ - - /* If the field changed size, add that change to the accumulated size change */ - if(new_dt->u.compnd.memb[i].type->size != old_dt->u.compnd.memb[old_match].type->size) { - /* Adjust the size of the member */ - new_dt->u.compnd.memb[i].size = (old_dt->u.compnd.memb[old_match].size*tmp->size)/old_dt->u.compnd.memb[old_match].type->size; - - accum_change += (new_dt->u.compnd.memb[i].type->size - old_dt->u.compnd.memb[old_match].type->size); - } /* end if */ - } /* end for */ - - /* Apply the accumulated size change to the size of the compound struct */ - new_dt->size += accum_change; - - } else if (H5T_ENUM == new_dt->type) { - /* - * Copy all member fields to new type, then overwrite the name fields - * of each new member with copied values. That is, H5T_copy() is a - * deep copy. - */ - new_dt->u.enumer.name = H5MM_malloc(new_dt->u.enumer.nalloc * - sizeof(char*)); - new_dt->u.enumer.value = H5MM_malloc(new_dt->u.enumer.nalloc * - new_dt->size); - if (NULL==new_dt->u.enumer.value) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - HDmemcpy(new_dt->u.enumer.value, old_dt->u.enumer.value, - new_dt->u.enumer.nmembs * new_dt->size); - for (i=0; i<new_dt->u.enumer.nmembs; i++) { - s = old_dt->u.enumer.name[i]; - new_dt->u.enumer.name[i] = H5MM_xstrdup(s); - } - } else if (H5T_VLEN == new_dt->type) { - if(method==H5T_COPY_TRANSIENT || method==H5T_COPY_REOPEN) { - /* H5T_copy converts any VL type into a memory VL type */ - if (H5T_vlen_mark(new_dt, NULL, H5T_VLEN_MEMORY)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); } - } - } else if (H5T_OPAQUE == new_dt->type) { - /* - * Copy the tag name. - */ - new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag); - } + break; + + case H5T_ENUM: + /* + * Copy all member fields to new type, then overwrite the name fields + * of each new member with copied values. That is, H5T_copy() is a + * deep copy. + */ + new_dt->u.enumer.name = H5MM_malloc(new_dt->u.enumer.nalloc * + sizeof(char*)); + new_dt->u.enumer.value = H5MM_malloc(new_dt->u.enumer.nalloc * + new_dt->size); + if (NULL==new_dt->u.enumer.value) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + HDmemcpy(new_dt->u.enumer.value, old_dt->u.enumer.value, + new_dt->u.enumer.nmembs * new_dt->size); + for (i=0; i<new_dt->u.enumer.nmembs; i++) { + s = old_dt->u.enumer.name[i]; + new_dt->u.enumer.name[i] = H5MM_xstrdup(s); + } + break; + + case H5T_VLEN: + if(method==H5T_COPY_TRANSIENT || method==H5T_COPY_REOPEN) { + /* H5T_copy converts any VL type into a memory VL type */ + if (H5T_vlen_mark(new_dt, NULL, H5T_VLEN_MEMORY)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); + } + } + break; + + case H5T_OPAQUE: + /* + * Copy the tag name. + */ + new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag); + break; + + case H5T_ARRAY: + /* Re-compute the array's size, in case it's base type changed size */ + new_dt->size=new_dt->u.array.nelem*new_dt->parent->size; + break; + + default: + break; + } /* end switch */ FUNC_LEAVE(new_dt); } @@ -5183,7 +5091,7 @@ H5T_is_atomic(const H5T_t *dt) FUNC_ENTER(H5T_is_atomic, FAIL); assert(dt); - if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type && H5T_OPAQUE!=dt->type) { + if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type && H5T_OPAQUE!=dt->type && H5T_ARRAY!=dt->type) { ret_value = TRUE; } else { ret_value = FALSE; @@ -5260,8 +5168,9 @@ H5T_set_size(H5T_t *dt, size_t size) switch (dt->type) { case H5T_COMPOUND: + case H5T_ARRAY: HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to set size of a compound data type"); + "unable to set size of specified data type"); case H5T_INTEGER: case H5T_TIME: @@ -5412,7 +5321,7 @@ H5T_set_precision(H5T_t *dt, size_t prec) } dt->size = dt->parent->size; } else { - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); @@ -5527,7 +5436,7 @@ H5T_set_offset(H5T_t *dt, size_t offset) } dt->size = dt->parent->size; } else { - if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type"); } else if (H5T_ENUM==dt->type) { @@ -5545,7 +5454,7 @@ H5T_set_offset(H5T_t *dt, size_t offset) /*------------------------------------------------------------------------- - * Function: H5T_struct_insert + * Function: H5T_insert * * Purpose: Adds a new MEMBER to the compound data type PARENT. The new * member will have a NAME that is unique within PARENT and an @@ -5558,18 +5467,17 @@ H5T_set_offset(H5T_t *dt, size_t offset) * Monday, December 8, 1997 * * Modifications: + * Took out arrayness parameters - QAK, 10/6/00 * *------------------------------------------------------------------------- */ herr_t -H5T_struct_insert(H5T_t *parent, const char *name, size_t offset, intn ndims, - const size_t *dim, const intn *perm, const H5T_t *member) +H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) { intn idx, i; size_t total_size; - hbool_t *perm_check=NULL; - FUNC_ENTER(H5T_struct_insert, FAIL); + FUNC_ENTER(H5T_insert, FAIL); /* check args */ assert(parent && H5T_COMPOUND == parent->type); @@ -5586,7 +5494,7 @@ H5T_struct_insert(H5T_t *parent, const char *name, size_t offset, intn ndims, } /* Does the new member overlap any existing member ? */ - for (total_size=member->size, i=0; i<ndims; i++) total_size *= dim[i]; + total_size=member->size; for (i=0; i<parent->u.compnd.nmembs; i++) { if ((offset <= parent->u.compnd.memb[i].offset && offset + total_size > parent->u.compnd.memb[i].offset) || @@ -5598,39 +5506,18 @@ H5T_struct_insert(H5T_t *parent, const char *name, size_t offset, intn ndims, } } - /* Are permutations correct? */ - if (ndims>0 && perm) { - if (NULL==(perm_check=H5MM_calloc(ndims*sizeof(hbool_t)))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - for (i=0; i<ndims; i++) { - if (perm[i]<0 || perm[i]>=ndims) { - H5MM_xfree(perm_check); - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "invalid permutation vector (out of range)"); - } - if (perm_check[perm[i]]) { - H5MM_xfree(perm_check); - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "invalid permutation vector (duplicate value)"); - } - perm_check[perm[i]] = TRUE; - } - perm_check = H5MM_xfree(perm_check); - } - /* Increase member array if necessary */ if (parent->u.compnd.nmembs >= parent->u.compnd.nalloc) { - size_t na = parent->u.compnd.nalloc + H5T_COMPND_INC; - H5T_cmemb_t *x = H5MM_realloc (parent->u.compnd.memb, - na * sizeof(H5T_cmemb_t)); - if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - parent->u.compnd.nalloc = (intn)na; - parent->u.compnd.memb = x; + size_t na = parent->u.compnd.nalloc + H5T_COMPND_INC; + H5T_cmemb_t *x = H5MM_realloc (parent->u.compnd.memb, + na * sizeof(H5T_cmemb_t)); + + if (!x) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } + parent->u.compnd.nalloc = (intn)na; + parent->u.compnd.memb = x; } /* Add member to end of member array */ @@ -5638,12 +5525,7 @@ H5T_struct_insert(H5T_t *parent, const char *name, size_t offset, intn ndims, parent->u.compnd.memb[idx].name = H5MM_xstrdup(name); parent->u.compnd.memb[idx].offset = offset; parent->u.compnd.memb[idx].size = total_size; - parent->u.compnd.memb[idx].ndims = ndims; parent->u.compnd.memb[idx].type = H5T_copy (member, H5T_COPY_ALL); - for (i=0; i<ndims; i++) { - parent->u.compnd.memb[idx].dim[i] = dim[i]; - parent->u.compnd.memb[idx].perm[i] = perm ? perm[i] : i; - } parent->u.compnd.sorted = H5T_SORT_NONE; parent->u.compnd.nmembs++; @@ -5655,6 +5537,10 @@ H5T_struct_insert(H5T_t *parent, const char *name, size_t offset, intn ndims, if(member->type==H5T_VLEN || member->force_conv==TRUE) parent->force_conv=TRUE; + /* Set the flag for this compound type, if the field is an array */ + if(member->type==H5T_ARRAY) + parent->u.compnd.has_array=TRUE; + FUNC_LEAVE(SUCCEED); } @@ -6183,316 +6069,337 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) if (tmp>0) HGOTO_DONE(1); } - if (H5T_COMPOUND == dt1->type) { - /* - * Compound data types... - */ - if (dt1->u.compnd.nmembs < dt2->u.compnd.nmembs) HGOTO_DONE(-1); - if (dt1->u.compnd.nmembs > dt2->u.compnd.nmembs) HGOTO_DONE(1); - - /* Build an index for each type so the names are sorted */ - if (NULL==(idx1 = H5MM_malloc(dt1->u.compnd.nmembs * sizeof(intn))) || - NULL==(idx2 = H5MM_malloc(dt1->u.compnd.nmembs * sizeof(intn)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, - "memory allocation failed"); - } - for (i=0; i<dt1->u.compnd.nmembs; i++) idx1[i] = idx2[i] = i; - for (i=dt1->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { - for (j=0, swapped=FALSE; j<i; j++) { - if (HDstrcmp(dt1->u.compnd.memb[idx1[j]].name, - dt1->u.compnd.memb[idx1[j+1]].name) > 0) { - tmp = idx1[j]; - idx1[j] = idx1[j+1]; - idx1[j+1] = tmp; - swapped = TRUE; - } - } - } - for (i=dt2->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { - for (j=0, swapped=FALSE; j<i; j++) { - if (HDstrcmp(dt2->u.compnd.memb[idx2[j]].name, - dt2->u.compnd.memb[idx2[j+1]].name) > 0) { - tmp = idx2[j]; - idx2[j] = idx2[j+1]; - idx2[j+1] = tmp; - swapped = TRUE; - } - } - } + switch(dt1->type) { + case H5T_COMPOUND: + /* + * Compound data types... + */ + if (dt1->u.compnd.nmembs < dt2->u.compnd.nmembs) + HGOTO_DONE(-1); + if (dt1->u.compnd.nmembs > dt2->u.compnd.nmembs) + HGOTO_DONE(1); + + /* Build an index for each type so the names are sorted */ + if (NULL==(idx1 = H5MM_malloc(dt1->u.compnd.nmembs * sizeof(intn))) || + NULL==(idx2 = H5MM_malloc(dt1->u.compnd.nmembs * sizeof(intn)))) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, + "memory allocation failed"); + } + for (i=0; i<dt1->u.compnd.nmembs; i++) + idx1[i] = idx2[i] = i; + for (i=dt1->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt1->u.compnd.memb[idx1[j]].name, + dt1->u.compnd.memb[idx1[j+1]].name) > 0) { + tmp = idx1[j]; + idx1[j] = idx1[j+1]; + idx1[j+1] = tmp; + swapped = TRUE; + } + } + } + for (i=dt2->u.compnd.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt2->u.compnd.memb[idx2[j]].name, + dt2->u.compnd.memb[idx2[j+1]].name) > 0) { + tmp = idx2[j]; + idx2[j] = idx2[j+1]; + idx2[j+1] = tmp; + swapped = TRUE; + } + } + } #ifdef H5T_DEBUG - /* I don't quite trust the code above yet :-) --RPM */ - for (i=0; i<dt1->u.compnd.nmembs-1; i++) { - assert(HDstrcmp(dt1->u.compnd.memb[idx1[i]].name, - dt1->u.compnd.memb[idx1[i + 1]].name)); - assert(HDstrcmp(dt2->u.compnd.memb[idx2[i]].name, - dt2->u.compnd.memb[idx2[i + 1]].name)); - } + /* I don't quite trust the code above yet :-) --RPM */ + for (i=0; i<dt1->u.compnd.nmembs-1; i++) { + assert(HDstrcmp(dt1->u.compnd.memb[idx1[i]].name, + dt1->u.compnd.memb[idx1[i + 1]].name)); + assert(HDstrcmp(dt2->u.compnd.memb[idx2[i]].name, + dt2->u.compnd.memb[idx2[i + 1]].name)); + } #endif - /* Compare the members */ - for (i=0; i<dt1->u.compnd.nmembs; i++) { - tmp = HDstrcmp(dt1->u.compnd.memb[idx1[i]].name, - dt2->u.compnd.memb[idx2[i]].name); - if (tmp < 0) HGOTO_DONE(-1); - if (tmp > 0) HGOTO_DONE(1); - - if (dt1->u.compnd.memb[idx1[i]].offset < - dt2->u.compnd.memb[idx2[i]].offset) HGOTO_DONE(-1); - if (dt1->u.compnd.memb[idx1[i]].offset > - dt2->u.compnd.memb[idx2[i]].offset) HGOTO_DONE(1); - - if (dt1->u.compnd.memb[idx1[i]].size < - dt2->u.compnd.memb[idx2[i]].size) HGOTO_DONE(-1); - if (dt1->u.compnd.memb[idx1[i]].size > - dt2->u.compnd.memb[idx2[i]].size) HGOTO_DONE(1); - - if (dt1->u.compnd.memb[idx1[i]].ndims < - dt2->u.compnd.memb[idx2[i]].ndims) HGOTO_DONE(-1); - if (dt1->u.compnd.memb[idx1[i]].ndims > - dt2->u.compnd.memb[idx2[i]].ndims) HGOTO_DONE(1); - - for (j=0; j<dt1->u.compnd.memb[idx1[i]].ndims; j++) { - if (dt1->u.compnd.memb[idx1[i]].dim[j] < - dt2->u.compnd.memb[idx2[i]].dim[j]) HGOTO_DONE(-1); - if (dt1->u.compnd.memb[idx1[i]].dim[j] > - dt2->u.compnd.memb[idx2[i]].dim[j]) HGOTO_DONE(1); - } - - for (j=0; j<dt1->u.compnd.memb[idx1[i]].ndims; j++) { - if (dt1->u.compnd.memb[idx1[i]].perm[j] < - dt2->u.compnd.memb[idx2[i]].perm[j]) HGOTO_DONE(-1); - if (dt1->u.compnd.memb[idx1[i]].perm[j] > - dt2->u.compnd.memb[idx2[i]].perm[j]) HGOTO_DONE(1); - } + /* Compare the members */ + for (i=0; i<dt1->u.compnd.nmembs; i++) { + tmp = HDstrcmp(dt1->u.compnd.memb[idx1[i]].name, + dt2->u.compnd.memb[idx2[i]].name); + if (tmp < 0) + HGOTO_DONE(-1); + if (tmp > 0) + HGOTO_DONE(1); + + if (dt1->u.compnd.memb[idx1[i]].offset < + dt2->u.compnd.memb[idx2[i]].offset) HGOTO_DONE(-1); + if (dt1->u.compnd.memb[idx1[i]].offset > + dt2->u.compnd.memb[idx2[i]].offset) HGOTO_DONE(1); + + if (dt1->u.compnd.memb[idx1[i]].size < + dt2->u.compnd.memb[idx2[i]].size) HGOTO_DONE(-1); + if (dt1->u.compnd.memb[idx1[i]].size > + dt2->u.compnd.memb[idx2[i]].size) HGOTO_DONE(1); + + tmp = H5T_cmp(dt1->u.compnd.memb[idx1[i]].type, + dt2->u.compnd.memb[idx2[i]].type); + if (tmp < 0) HGOTO_DONE(-1); + if (tmp > 0) HGOTO_DONE(1); + } + break; - tmp = H5T_cmp(dt1->u.compnd.memb[idx1[i]].type, - dt2->u.compnd.memb[idx2[i]].type); - if (tmp < 0) HGOTO_DONE(-1); - if (tmp > 0) HGOTO_DONE(1); - } - - } else if (H5T_ENUM==dt1->type) { - /* - * Enumeration data types... - */ - if (dt1->u.enumer.nmembs < dt2->u.enumer.nmembs) HGOTO_DONE(-1); - if (dt1->u.enumer.nmembs > dt2->u.enumer.nmembs) HGOTO_DONE(1); - - /* Build an index for each type so the names are sorted */ - if (NULL==(idx1 = H5MM_malloc(dt1->u.enumer.nmembs * sizeof(intn))) || - NULL==(idx2 = H5MM_malloc(dt1->u.enumer.nmembs * sizeof(intn)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, - "memory allocation failed"); - } - for (i=0; i<dt1->u.enumer.nmembs; i++) idx1[i] = idx2[i] = i; - for (i=dt1->u.enumer.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { - for (j=0, swapped=FALSE; j<i; j++) { - if (HDstrcmp(dt1->u.enumer.name[idx1[j]], - dt1->u.enumer.name[idx1[j+1]]) > 0) { - tmp = idx1[j]; - idx1[j] = idx1[j+1]; - idx1[j+1] = tmp; - swapped = TRUE; - } - } - } - for (i=dt2->u.enumer.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { - for (j=0, swapped=FALSE; j<i; j++) { - if (HDstrcmp(dt2->u.enumer.name[idx2[j]], - dt2->u.enumer.name[idx2[j+1]]) > 0) { - tmp = idx2[j]; - idx2[j] = idx2[j+1]; - idx2[j+1] = tmp; - swapped = TRUE; - } - } - } + case H5T_ENUM: + /* + * Enumeration data types... + */ + if (dt1->u.enumer.nmembs < dt2->u.enumer.nmembs) + HGOTO_DONE(-1); + if (dt1->u.enumer.nmembs > dt2->u.enumer.nmembs) + HGOTO_DONE(1); + + /* Build an index for each type so the names are sorted */ + if (NULL==(idx1 = H5MM_malloc(dt1->u.enumer.nmembs * sizeof(intn))) || + NULL==(idx2 = H5MM_malloc(dt1->u.enumer.nmembs * sizeof(intn)))) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, 0, + "memory allocation failed"); + } + for (i=0; i<dt1->u.enumer.nmembs; i++) + idx1[i] = idx2[i] = i; + for (i=dt1->u.enumer.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt1->u.enumer.name[idx1[j]], + dt1->u.enumer.name[idx1[j+1]]) > 0) { + tmp = idx1[j]; + idx1[j] = idx1[j+1]; + idx1[j+1] = tmp; + swapped = TRUE; + } + } + } + for (i=dt2->u.enumer.nmembs-1, swapped=TRUE; swapped && i>=0; --i) { + for (j=0, swapped=FALSE; j<i; j++) { + if (HDstrcmp(dt2->u.enumer.name[idx2[j]], + dt2->u.enumer.name[idx2[j+1]]) > 0) { + tmp = idx2[j]; + idx2[j] = idx2[j+1]; + idx2[j+1] = tmp; + swapped = TRUE; + } + } + } #ifdef H5T_DEBUG - /* I don't quite trust the code above yet :-) --RPM */ - for (i=0; i<dt1->u.enumer.nmembs-1; i++) { - assert(HDstrcmp(dt1->u.enumer.name[idx1[i]], - dt1->u.enumer.name[idx1[i+1]])); - assert(HDstrcmp(dt2->u.enumer.name[idx2[i]], - dt2->u.enumer.name[idx2[i+1]])); - } + /* I don't quite trust the code above yet :-) --RPM */ + for (i=0; i<dt1->u.enumer.nmembs-1; i++) { + assert(HDstrcmp(dt1->u.enumer.name[idx1[i]], + dt1->u.enumer.name[idx1[i+1]])); + assert(HDstrcmp(dt2->u.enumer.name[idx2[i]], + dt2->u.enumer.name[idx2[i+1]])); + } #endif - /* Compare the members */ - base_size = dt1->parent->size; - for (i=0; i<dt1->u.enumer.nmembs; i++) { - tmp = HDstrcmp(dt1->u.enumer.name[idx1[i]], - dt2->u.enumer.name[idx2[i]]); - if (tmp<0) HGOTO_DONE(-1); - if (tmp>0) HGOTO_DONE(1); - - tmp = HDmemcmp(dt1->u.enumer.value+idx1[i]*base_size, - dt2->u.enumer.value+idx2[i]*base_size, - base_size); - if (tmp<0) HGOTO_DONE(-1); - if (tmp>0) HGOTO_DONE(1); - } - - } else if (H5T_VLEN==dt1->type) { - assert(dt1->u.vlen.type>H5T_VLEN_BADTYPE && dt1->u.vlen.type<H5T_VLEN_MAXTYPE); - assert(dt2->u.vlen.type>H5T_VLEN_BADTYPE && dt2->u.vlen.type<H5T_VLEN_MAXTYPE); - assert(dt1->u.vlen.loc>H5T_VLEN_BADLOC && dt1->u.vlen.loc<H5T_VLEN_MAXLOC); - assert(dt2->u.vlen.loc>H5T_VLEN_BADLOC && dt2->u.vlen.loc<H5T_VLEN_MAXLOC); - - /* Arbitrarily sort sequence VL datatypes before string VL datatypes */ - if (dt1->u.vlen.type==H5T_VLEN_SEQUENCE && - dt2->u.vlen.type==H5T_VLEN_STRING) { - HGOTO_DONE(-1); - } else if (dt1->u.vlen.type==H5T_VLEN_STRING && - dt2->u.vlen.type==H5T_VLEN_SEQUENCE) { - HGOTO_DONE(1); - } - /* Arbitrarily sort VL datatypes in memory before disk */ - if (dt1->u.vlen.loc==H5T_VLEN_MEMORY && - dt2->u.vlen.loc==H5T_VLEN_DISK) { - HGOTO_DONE(-1); - } else if (dt1->u.vlen.loc==H5T_VLEN_DISK && - dt2->u.vlen.loc==H5T_VLEN_MEMORY) { - HGOTO_DONE(1); - } - - } else if (H5T_OPAQUE==dt1->type) { - HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag)); - - } else { - /* - * Atomic datatypes... - */ - if (dt1->u.atomic.order < dt2->u.atomic.order) HGOTO_DONE(-1); - if (dt1->u.atomic.order > dt2->u.atomic.order) HGOTO_DONE(1); - - if (dt1->u.atomic.prec < dt2->u.atomic.prec) HGOTO_DONE(-1); - if (dt1->u.atomic.prec > dt2->u.atomic.prec) HGOTO_DONE(1); - - if (dt1->u.atomic.offset < dt2->u.atomic.offset) HGOTO_DONE(-1); - if (dt1->u.atomic.offset > dt2->u.atomic.offset) HGOTO_DONE(1); - - if (dt1->u.atomic.lsb_pad < dt2->u.atomic.lsb_pad) HGOTO_DONE(-1); - if (dt1->u.atomic.lsb_pad > dt2->u.atomic.lsb_pad) HGOTO_DONE(1); - - if (dt1->u.atomic.msb_pad < dt2->u.atomic.msb_pad) HGOTO_DONE(-1); - if (dt1->u.atomic.msb_pad > dt2->u.atomic.msb_pad) HGOTO_DONE(1); - - switch (dt1->type) { - case H5T_INTEGER: - if (dt1->u.atomic.u.i.sign < dt2->u.atomic.u.i.sign) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.i.sign > dt2->u.atomic.u.i.sign) { - HGOTO_DONE(1); - } - break; - - case H5T_FLOAT: - if (dt1->u.atomic.u.f.sign < dt2->u.atomic.u.f.sign) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.f.sign > dt2->u.atomic.u.f.sign) { - HGOTO_DONE(1); - } - - if (dt1->u.atomic.u.f.epos < dt2->u.atomic.u.f.epos) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.f.epos > dt2->u.atomic.u.f.epos) { - HGOTO_DONE(1); - } - - if (dt1->u.atomic.u.f.esize < - dt2->u.atomic.u.f.esize) HGOTO_DONE(-1); - if (dt1->u.atomic.u.f.esize > - dt2->u.atomic.u.f.esize) HGOTO_DONE(1); - - if (dt1->u.atomic.u.f.ebias < - dt2->u.atomic.u.f.ebias) HGOTO_DONE(-1); - if (dt1->u.atomic.u.f.ebias > - dt2->u.atomic.u.f.ebias) HGOTO_DONE(1); - - if (dt1->u.atomic.u.f.mpos < dt2->u.atomic.u.f.mpos) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.f.mpos > dt2->u.atomic.u.f.mpos) { - HGOTO_DONE(1); - } - - if (dt1->u.atomic.u.f.msize < - dt2->u.atomic.u.f.msize) HGOTO_DONE(-1); - if (dt1->u.atomic.u.f.msize > - dt2->u.atomic.u.f.msize) HGOTO_DONE(1); - - if (dt1->u.atomic.u.f.norm < dt2->u.atomic.u.f.norm) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.f.norm > dt2->u.atomic.u.f.norm) { - HGOTO_DONE(1); - } - - if (dt1->u.atomic.u.f.pad < dt2->u.atomic.u.f.pad) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.f.pad > dt2->u.atomic.u.f.pad) { - HGOTO_DONE(1); - } - - break; - - case H5T_TIME: /* order and precision are checked above */ - /*void */ - break; - - case H5T_STRING: - if (dt1->u.atomic.u.s.cset < dt2->u.atomic.u.s.cset) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.s.cset > dt2->u.atomic.u.s.cset) { - HGOTO_DONE(1); - } - - if (dt1->u.atomic.u.s.pad < dt2->u.atomic.u.s.pad) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.s.pad > dt2->u.atomic.u.s.pad) { - HGOTO_DONE(1); - } - - break; + /* Compare the members */ + base_size = dt1->parent->size; + for (i=0; i<dt1->u.enumer.nmembs; i++) { + tmp = HDstrcmp(dt1->u.enumer.name[idx1[i]], + dt2->u.enumer.name[idx2[i]]); + if (tmp<0) HGOTO_DONE(-1); + if (tmp>0) HGOTO_DONE(1); + + tmp = HDmemcmp(dt1->u.enumer.value+idx1[i]*base_size, + dt2->u.enumer.value+idx2[i]*base_size, + base_size); + if (tmp<0) HGOTO_DONE(-1); + if (tmp>0) HGOTO_DONE(1); + } + break; - case H5T_BITFIELD: - /*void */ - break; + case H5T_VLEN: + assert(dt1->u.vlen.type>H5T_VLEN_BADTYPE && dt1->u.vlen.type<H5T_VLEN_MAXTYPE); + assert(dt2->u.vlen.type>H5T_VLEN_BADTYPE && dt2->u.vlen.type<H5T_VLEN_MAXTYPE); + assert(dt1->u.vlen.loc>H5T_VLEN_BADLOC && dt1->u.vlen.loc<H5T_VLEN_MAXLOC); + assert(dt2->u.vlen.loc>H5T_VLEN_BADLOC && dt2->u.vlen.loc<H5T_VLEN_MAXLOC); + + /* Arbitrarily sort sequence VL datatypes before string VL datatypes */ + if (dt1->u.vlen.type==H5T_VLEN_SEQUENCE && + dt2->u.vlen.type==H5T_VLEN_STRING) { + HGOTO_DONE(-1); + } else if (dt1->u.vlen.type==H5T_VLEN_STRING && + dt2->u.vlen.type==H5T_VLEN_SEQUENCE) { + HGOTO_DONE(1); + } + /* Arbitrarily sort VL datatypes in memory before disk */ + if (dt1->u.vlen.loc==H5T_VLEN_MEMORY && + dt2->u.vlen.loc==H5T_VLEN_DISK) { + HGOTO_DONE(-1); + } else if (dt1->u.vlen.loc==H5T_VLEN_DISK && + dt2->u.vlen.loc==H5T_VLEN_MEMORY) { + HGOTO_DONE(1); + } + break; - case H5T_REFERENCE: - if (dt1->u.atomic.u.r.rtype < dt2->u.atomic.u.r.rtype) { - HGOTO_DONE(-1); - } - if (dt1->u.atomic.u.r.rtype > dt2->u.atomic.u.r.rtype) { - HGOTO_DONE(1); - } + case H5T_OPAQUE: + HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag)); + + case H5T_ARRAY: + if (dt1->u.array.ndims < dt2->u.array.ndims) + HGOTO_DONE(-1); + if (dt1->u.array.ndims > dt2->u.array.ndims) + HGOTO_DONE(1); + + for (j=0; j<dt1->u.array.ndims; j++) { + if (dt1->u.array.dim[j] < dt2->u.array.dim[j]) + HGOTO_DONE(-1); + if (dt1->u.array.dim[j] > dt2->u.array.dim[j]) + HGOTO_DONE(1); + } - switch(dt1->u.atomic.u.r.rtype) { - case H5R_OBJECT: - case H5R_DATASET_REGION: - /* Does this need more to distinguish it? -QAK 11/30/98 */ - /*void */ - break; + for (j=0; j<dt1->u.array.ndims; j++) { + if (dt1->u.array.perm[j] < dt2->u.array.perm[j]) + HGOTO_DONE(-1); + if (dt1->u.array.perm[j] > dt2->u.array.perm[j]) + HGOTO_DONE(1); + } - default: - assert("not implemented yet" && 0); - } - break; + tmp = H5T_cmp(dt1->parent, dt2->parent); + if (tmp < 0) + HGOTO_DONE(-1); + if (tmp > 0) + HGOTO_DONE(1); + break; - default: - assert("not implemented yet" && 0); - } - } + default: + /* + * Atomic datatypes... + */ + if (dt1->u.atomic.order < dt2->u.atomic.order) HGOTO_DONE(-1); + if (dt1->u.atomic.order > dt2->u.atomic.order) HGOTO_DONE(1); + + if (dt1->u.atomic.prec < dt2->u.atomic.prec) HGOTO_DONE(-1); + if (dt1->u.atomic.prec > dt2->u.atomic.prec) HGOTO_DONE(1); + + if (dt1->u.atomic.offset < dt2->u.atomic.offset) HGOTO_DONE(-1); + if (dt1->u.atomic.offset > dt2->u.atomic.offset) HGOTO_DONE(1); + + if (dt1->u.atomic.lsb_pad < dt2->u.atomic.lsb_pad) HGOTO_DONE(-1); + if (dt1->u.atomic.lsb_pad > dt2->u.atomic.lsb_pad) HGOTO_DONE(1); + + if (dt1->u.atomic.msb_pad < dt2->u.atomic.msb_pad) HGOTO_DONE(-1); + if (dt1->u.atomic.msb_pad > dt2->u.atomic.msb_pad) HGOTO_DONE(1); + + switch (dt1->type) { + case H5T_INTEGER: + if (dt1->u.atomic.u.i.sign < dt2->u.atomic.u.i.sign) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.i.sign > dt2->u.atomic.u.i.sign) { + HGOTO_DONE(1); + } + break; + + case H5T_FLOAT: + if (dt1->u.atomic.u.f.sign < dt2->u.atomic.u.f.sign) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.f.sign > dt2->u.atomic.u.f.sign) { + HGOTO_DONE(1); + } + + if (dt1->u.atomic.u.f.epos < dt2->u.atomic.u.f.epos) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.f.epos > dt2->u.atomic.u.f.epos) { + HGOTO_DONE(1); + } + + if (dt1->u.atomic.u.f.esize < + dt2->u.atomic.u.f.esize) HGOTO_DONE(-1); + if (dt1->u.atomic.u.f.esize > + dt2->u.atomic.u.f.esize) HGOTO_DONE(1); + + if (dt1->u.atomic.u.f.ebias < + dt2->u.atomic.u.f.ebias) HGOTO_DONE(-1); + if (dt1->u.atomic.u.f.ebias > + dt2->u.atomic.u.f.ebias) HGOTO_DONE(1); + + if (dt1->u.atomic.u.f.mpos < dt2->u.atomic.u.f.mpos) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.f.mpos > dt2->u.atomic.u.f.mpos) { + HGOTO_DONE(1); + } + + if (dt1->u.atomic.u.f.msize < + dt2->u.atomic.u.f.msize) HGOTO_DONE(-1); + if (dt1->u.atomic.u.f.msize > + dt2->u.atomic.u.f.msize) HGOTO_DONE(1); + + if (dt1->u.atomic.u.f.norm < dt2->u.atomic.u.f.norm) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.f.norm > dt2->u.atomic.u.f.norm) { + HGOTO_DONE(1); + } + + if (dt1->u.atomic.u.f.pad < dt2->u.atomic.u.f.pad) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.f.pad > dt2->u.atomic.u.f.pad) { + HGOTO_DONE(1); + } + + break; + + case H5T_TIME: /* order and precision are checked above */ + /*void */ + break; + + case H5T_STRING: + if (dt1->u.atomic.u.s.cset < dt2->u.atomic.u.s.cset) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.s.cset > dt2->u.atomic.u.s.cset) { + HGOTO_DONE(1); + } + + if (dt1->u.atomic.u.s.pad < dt2->u.atomic.u.s.pad) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.s.pad > dt2->u.atomic.u.s.pad) { + HGOTO_DONE(1); + } + + break; + + case H5T_BITFIELD: + /*void */ + break; + + case H5T_REFERENCE: + if (dt1->u.atomic.u.r.rtype < dt2->u.atomic.u.r.rtype) { + HGOTO_DONE(-1); + } + if (dt1->u.atomic.u.r.rtype > dt2->u.atomic.u.r.rtype) { + HGOTO_DONE(1); + } + + switch(dt1->u.atomic.u.r.rtype) { + case H5R_OBJECT: + case H5R_DATASET_REGION: + /* Does this need more to distinguish it? -QAK 11/30/98 */ + /*void */ + break; + + default: + assert("not implemented yet" && 0); + } + break; + + default: + assert("not implemented yet" && 0); + } + break; + } /* end switch */ - done: +done: H5MM_xfree(idx1); H5MM_xfree(idx2); @@ -6873,6 +6780,255 @@ H5T_entof (H5T_t *dt) } +/*-------------------------------------------------------------------------- + NAME + H5T_get_ref_type + PURPOSE + Retrieves the type of reference for a datatype + USAGE + H5R_type_t H5Tget_ref_type(dt) + H5T_t *dt; IN: datatype pointer for the reference datatype + + RETURNS + Success: A reference type defined in H5Rpublic.h + Failure: H5R_BADTYPE + DESCRIPTION + Given a reference datatype object, this function returns the reference type + of the datatype. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5R_type_t +H5T_get_ref_type(const H5T_t *dt) +{ + H5R_type_t ret_value = H5R_BADTYPE; + + FUNC_ENTER(H5T_get_ref_type, H5R_BADTYPE); + + assert(dt); + + if(dt->type==H5T_REFERENCE) + ret_value=dt->u.atomic.u.r.rtype; + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE(ret_value); +} /* end H5T_get_ref_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5Tarray_create + * + * Purpose: Create a new array data type based on the specified BASE_TYPE. + * The type is an array with NDIMS dimensionality and the size of the + * array is DIMS. The total member size should be relatively small. + * PERM is currently unimplemented and unused, but is designed to contain + * the dimension permutation from C order. + * Array datatypes are currently limited to H5S_MAX_RANK number of + * dimensions and must have the number of dimensions set greater than + * 0. (i.e. 0 > ndims <= H5S_MAX_RANK) All dimensions sizes must be greater + * than 0 also. + * + * Return: Success: ID of new array data type + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, Oct 26, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Tarray_create(hid_t base_id, int ndims, const hsize_t dim[/* ndims */], + const int UNUSED perm[/* ndims */]) +{ + H5T_t *base = NULL; /* base data type */ + H5T_t *dt = NULL; /* new array data type */ + intn i; /* local index variable */ + hid_t ret_value = FAIL; /* return value */ + + FUNC_ENTER(H5Tarray_create, FAIL); + H5TRACE1("i","i",base_id); + + /* Check args */ + if (ndims<1 || ndims>H5S_MAX_RANK) + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimensionality"); + if (ndims>0 && !dim) + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified"); + for(i=0; i<ndims; i++) + if(!(dim[i]>0)) + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero-sized dimension specified"); + if (H5I_DATATYPE!=H5I_get_type(base_id) || NULL==(base=H5I_object(base_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); + + /* Create the actual array datatype */ + if ((dt=H5T_array_create(base,ndims,dim,perm))==NULL) + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to create datatype"); + + /* Atomize the type */ + if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); + + FUNC_LEAVE(ret_value); +} /* end H5Tarray_create */ + + +/*------------------------------------------------------------------------- + * Function: H5T_array_create + * + * Purpose: Internal routine to create a new array data type based on the + * specified BASE_TYPE. The type is an array with NDIMS dimensionality + * and the size of the array is DIMS. PERM is currently unimplemented + * and unused, but is designed to contain the dimension permutation from + * C order. Array datatypes are currently limited to H5S_MAX_RANK number + * of * dimensions. + * + * Return: Success: ID of new array data type + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, Oct 26, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */], + const int perm[/* ndims */]) +{ + H5T_t *ret_value = NULL; /*new array data type */ + intn i; /* local index variable */ + + FUNC_ENTER(H5T_array_create, NULL); + + assert(base); + assert(ndims>0 && ndims<=H5S_MAX_RANK); + assert(dim); + + /* Build new type */ + if (NULL==(ret_value = H5FL_ALLOC(H5T_t,1))) + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + ret_value->ent.header = HADDR_UNDEF; + ret_value->type = H5T_ARRAY; + + /* Copy the base type of the array */ + ret_value->parent = H5T_copy(base, H5T_COPY_ALL); + + /* Set the array parameters */ + ret_value->u.array.ndims = ndims; + + /* Copy the array dimensions & compute the # of elements in the array */ + for(i=0, ret_value->u.array.nelem=1; i<ndims; i++) { + ret_value->u.array.dim[i] = dim[i]; + ret_value->u.array.nelem *= dim[i]; + } /* end for */ + + /* Copy the dimension permutations */ + for(i=0; i<ndims; i++) + ret_value->u.array.perm[i] = perm ? perm[i] : i; + + /* Set the array's size (number of elements * element datatype's size) */ + ret_value->size = ret_value->parent->size * ret_value->u.array.nelem; + + /* + * 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(base->type==H5T_VLEN || base->force_conv==TRUE) + ret_value->force_conv=TRUE; + + FUNC_LEAVE(ret_value); +} /* end H5T_array_create */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_array_ndims + * + * Purpose: Query the number of dimensions for an array datatype. + * + * Return: Success: Number of dimensions of the array datatype + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Tget_array_ndims(hid_t type_id) +{ + H5T_t *dt = NULL; /* pointer to array data type */ + int ret_value = FAIL; /* return value */ + + FUNC_ENTER(H5Tget_array_ndims, FAIL); + + /* Check args */ + if (H5I_DATATYPE!=H5I_get_type(type_id) || NULL==(dt=H5I_object(type_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object"); + if(dt->type!=H5T_ARRAY) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); + + /* Retrieve the number of dimensions */ + ret_value=dt->u.array.ndims; + + FUNC_LEAVE(ret_value); +} /* end H5Tget_array_ndims */ + + +/*------------------------------------------------------------------------- + * Function: H5Tget_array_dims + * + * Purpose: Query the sizes of dimensions for an array datatype. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]) +{ + H5T_t *dt = NULL; /* pointer to array data type */ + herr_t ret_value = SUCCEED; /* return value */ + intn i; /* Local index variable */ + + FUNC_ENTER(H5Tget_array_dims, FAIL); + + /* Check args */ + if (H5I_DATATYPE!=H5I_get_type(type_id) || NULL==(dt=H5I_object(type_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object"); + if(dt->type!=H5T_ARRAY) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype"); + + /* Retrieve the sizes of the dimensions */ + if(dims) + for(i=0; i<dt->u.array.ndims; i++) + dims[i]=dt->u.array.dim[i]; + + /* Retrieve the dimension permutations */ + if(perm) + for(i=0; i<dt->u.array.ndims; i++) + perm[i]=dt->u.array.perm[i]; + + FUNC_LEAVE(ret_value); +} /* end H5Tget_array_dims */ + + /*------------------------------------------------------------------------- * Function: H5T_print_stats * @@ -6956,7 +7112,7 @@ herr_t H5T_debug(H5T_t *dt, FILE *stream) { const char *s1="", *s2=""; - int i, j; + int i; size_t k, base_size; uint64_t tmp; @@ -7106,6 +7262,7 @@ H5T_debug(H5T_t *dt, FILE *stream) fprintf(stream, "\n\"%s\" @%lu", dt->u.compnd.memb[i].name, (unsigned long) (dt->u.compnd.memb[i].offset)); +#ifdef OLD_WAY if (dt->u.compnd.memb[i].ndims) { fprintf(stream, "["); for (j = 0; j < dt->u.compnd.memb[i].ndims; j++) { @@ -7114,6 +7271,7 @@ H5T_debug(H5T_t *dt, FILE *stream) } fprintf(stream, "]"); } +#endif /* OLD_WAY */ fprintf(stream, " "); H5T_debug(dt->u.compnd.memb[i].type, stream); } @@ -7144,41 +7302,4 @@ H5T_debug(H5T_t *dt, FILE *stream) FUNC_LEAVE(SUCCEED); } - -/*-------------------------------------------------------------------------- - NAME - H5T_get_ref_type - PURPOSE - Retrieves the type of reference for a datatype - USAGE - H5R_type_t H5Tget_ref_type(dt) - H5T_t *dt; IN: datatype pointer for the reference datatype - - RETURNS - Success: A reference type defined in H5Rpublic.h - Failure: H5R_BADTYPE - DESCRIPTION - Given a reference datatype object, this function returns the reference type - of the datatype. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -H5R_type_t -H5T_get_ref_type(const H5T_t *dt) -{ - H5R_type_t ret_value = H5R_BADTYPE; - - FUNC_ENTER(H5T_get_ref_type, H5R_BADTYPE); - - assert(dt); - - if(dt->type==H5T_REFERENCE) - ret_value=dt->u.atomic.u.r.rtype; -#ifdef LATER -done: -#endif /* LATER */ - FUNC_LEAVE(ret_value); -} /* end H5T_get_ref_type() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 66fa3e2..4d3c2ba 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -23,7 +23,6 @@ typedef struct H5T_conv_struct_t { hid_t *src_memb_id; /*source member type ID's */ hid_t *dst_memb_id; /*destination member type ID's */ H5T_path_t **memb_path; /*conversion path for each member */ - size_t *memb_nelmts; /*member element count */ } H5T_conv_struct_t; /* Conversion data for H5T_conv_enum() */ @@ -803,9 +802,7 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) NULL==(priv->src_memb_id=H5MM_malloc(src->u.compnd.nmembs * sizeof(hid_t))) || NULL==(priv->dst_memb_id=H5MM_malloc(dst->u.compnd.nmembs * - sizeof(hid_t))) || - NULL==(priv->memb_nelmts=H5MM_malloc(src->u.compnd.nmembs * - sizeof(size_t)))) { + sizeof(hid_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } @@ -846,44 +843,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) priv->dst_memb_id[src2dst[i]] = tid; } } - - /* - * Those members which are in both the source and destination must be - * the same size and shape arrays. - */ - for (i=0; i<src->u.compnd.nmembs; i++) { - if (src2dst[i]>=0) { - H5T_cmemb_t *src_memb = src->u.compnd.memb + i; - H5T_cmemb_t *dst_memb = dst->u.compnd.memb + src2dst[i]; - if (src_memb->ndims != dst_memb->ndims) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source and dest members have incompatible " - "size or shape"); - } - for (j=0; j<src_memb->ndims; j++) { - if (src_memb->dim[j] != dst_memb->dim[j]) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source and dest members have " - "incompatible size or shape"); - } -#ifndef LATER - /* Their permutation vectors must be equal */ - if (src_memb->perm[j]!=dst_memb->perm[j]) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "member permutations must be equal"); - } -#endif - } - } - } - - /* Calculate number of elements of each member */ - for (i=0; i<src->u.compnd.nmembs; i++) { - priv->memb_nelmts[i] = 1; - for (j=0; j<src->u.compnd.memb[i].ndims; j++) { - priv->memb_nelmts[i] *= src->u.compnd.memb[i].dim[j]; - } - } } /* @@ -908,7 +867,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type"); @@ -1013,7 +971,6 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); break; @@ -1078,8 +1035,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], - priv->memb_nelmts[i], - 0, 0, /*no striding (packed array)*/ + 1, 0, 0, /*no striding (packed array)*/ xbuf+src_memb->offset, xbkg+dst_memb->offset, dset_xfer_plist)<0) { @@ -1114,8 +1070,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], - priv->memb_nelmts[i], - 0, 0, /*no striding (packed array)*/ + 1, 0, 0, /*no striding (packed array)*/ xbuf+offset, xbkg+dst_memb->offset, dset_xfer_plist)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -1224,11 +1179,9 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, intn *src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ - size_t src_memb_size; /*sizeof single source member */ - size_t dst_memb_size; /*sizeof single destination memb*/ size_t offset; /*byte offset wrt struct */ uintn elmtno; /*element counter */ - intn i, j; /*counters */ + intn i; /*counters */ H5T_conv_struct_t *priv = NULL; /*private data */ FUNC_ENTER (H5T_conv_struct_opt, FAIL); @@ -1270,41 +1223,31 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ if (dst->size > src->size) { for (i=0, offset=0; i<src->u.compnd.nmembs; i++) { - if (src2dst[i]<0) - continue; - src_memb = src->u.compnd.memb + i; - dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) { - if (dst_memb_size > src_memb_size) - offset += src_memb_size; - } + if (src2dst[i]<0) + continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + if (dst_memb->size > src_memb->size) + offset += src_memb->size; } for (i=src->u.compnd.nmembs-1; i>=0; --i) { - if (src2dst[i]<0) - continue; - src_memb = src->u.compnd.memb + i; - dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - - for (j=(intn)(priv->memb_nelmts[i]-1); j>=0; --j) { - if (dst_memb_size > src_memb_size) { - offset -= src_memb_size; - if (dst_memb_size > src->size-offset) { - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); - cdata->priv = priv = H5MM_xfree (priv); - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "convertion is unsupported by this " - "function"); - } - } - } + if (src2dst[i]<0) + continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; + if (dst_memb->size > src->size-offset) { + H5MM_xfree(priv->src2dst); + H5MM_xfree(priv->src_memb_id); + H5MM_xfree(priv->dst_memb_id); + H5MM_xfree(priv->memb_path); + cdata->priv = priv = H5MM_xfree (priv); + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "convertion is unsupported by this " + "function"); + } + } } } break; @@ -1318,7 +1261,6 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); break; @@ -1372,38 +1314,33 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if (src2dst[i]<0) continue; /*subsetting*/ src_memb = src->u.compnd.memb + i; dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) { - if (dst_memb_size <= src_memb_size) { - xbuf = buf + src_memb->offset + j*src_memb_size; - xbkg = bkg + dst_memb->offset + j*dst_memb_size; - if (H5T_convert(priv->memb_path[i], - priv->src_memb_id[i], - priv->dst_memb_id[src2dst[i]], nelmts, - buf_stride?buf_stride:src->size, - bkg_stride, xbuf, xbkg, - dset_xfer_plist)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to convert compound data " - "type member"); - } - for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb_size); - xbuf += buf_stride ? buf_stride : src->size; - xbkg += bkg_stride; - } - } else { - for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbuf+offset, - xbuf+src_memb->offset+j*src_memb_size, - src_memb_size); - xbuf += buf_stride ? buf_stride : src->size; - } - offset += src_memb_size; - } - } + if (dst_memb->size <= src_memb->size) { + xbuf = buf + src_memb->offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert(priv->memb_path[i], + priv->src_memb_id[i], + priv->dst_memb_id[src2dst[i]], nelmts, + buf_stride ? buf_stride : src->size, + bkg_stride, xbuf, xbkg, + dset_xfer_plist)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert compound data " + "type member"); + } + for (elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride ? buf_stride : src->size; + xbkg += bkg_stride; + } + } else { + for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbuf+offset, xbuf+src_memb->offset, + src_memb->size); + xbuf += buf_stride ? buf_stride : src->size; + } + offset += src_memb->size; + } } /* @@ -1414,21 +1351,18 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ for (i=src->u.compnd.nmembs-1; i>=0; --i) { if (src2dst[i]<0) - continue; + continue; src_memb = src->u.compnd.memb + i; dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=(intn)(priv->memb_nelmts[i]-1); j>=0; --j) { - if (dst_memb_size > src_memb_size) { - offset -= src_memb_size; + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; xbuf = buf + offset; - xbkg = bkg + dst_memb->offset + j*dst_memb_size; + xbkg = bkg + dst_memb->offset; if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], nelmts, - buf_stride?buf_stride:src->size, + buf_stride ? buf_stride : src->size, bkg_stride, xbuf, xbkg, dset_xfer_plist)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -1436,11 +1370,10 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, "member"); } for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb_size); + HDmemmove(xbkg, xbuf, dst_memb->size); xbuf += buf_stride ? buf_stride : src->size; xbkg += bkg_stride; } - } } } @@ -2027,6 +1960,174 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /*------------------------------------------------------------------------- + * Function: H5T_conv_array + * + * Purpose: Converts between array data types in memory and on disk. + * This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, + size_t buf_stride, size_t UNUSED bkg_stride, void *_buf, + void UNUSED *_bkg, hid_t dset_xfer_plist) +{ + const H5D_xfer_t *xfer_parms = NULL; + H5T_path_t *tpath; /* Type conversion path */ + hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */ + H5T_t *src = NULL; /*source data type */ + H5T_t *dst = NULL; /*destination data type */ + uint8_t *sp, *dp; /*source and dest traversal ptrs */ + size_t src_delta, dst_delta; /*source & destination stride */ + intn direction; /*direction of traversal */ + uintn elmtno; /*element number counter */ + intn i; /* local index variable */ + + FUNC_ENTER (H5T_conv_array, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC_ID-->DST_ID. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if (H5I_DATATYPE != H5I_get_type(src_id) || + NULL == (src = H5I_object(src_id)) || + H5I_DATATYPE != H5I_get_type(dst_id) || + NULL == (dst = H5I_object(dst_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + assert (H5T_ARRAY==src->type); + assert (H5T_ARRAY==dst->type); + + /* Check the number and sizes of the dimensions */ + if(src->u.array.ndims!=dst->u.array.ndims) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same number of dimensions"); + for(i=0; i<src->u.array.ndims; i++) + if(src->u.array.dim[i]!=dst->u.array.dim[i]) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same sizes of dimensions"); +#ifdef LATER + for(i=0; i<src->u.array.ndims; i++) + if(src->u.array.perm[i]!=dst->u.array.perm[i]) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same dimension permutations"); +#endif /* LATER */ + +#ifdef LATER + /* QAK - Set up conversion function? */ + if (H5T_conv_array_init (src, dst, cdata)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize conversion data"); + } +#endif /* LATER */ + break; + + case H5T_CONV_FREE: + /* QAK - Nothing to do currently */ + break; + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (H5I_DATATYPE != H5I_get_type(src_id) || + NULL == (src = H5I_object(src_id)) || + H5I_DATATYPE != H5I_get_type(dst_id) || + NULL == (dst = H5I_object(dst_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + /* Get the dataset transfer property list */ + if (H5P_DEFAULT == dset_xfer_plist) { + xfer_parms = &H5D_xfer_dflt; + } else if (H5P_DATA_XFER != H5P_get_class(dset_xfer_plist) || + NULL == (xfer_parms = H5I_object(dset_xfer_plist))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); + } + + /* + * Do we process the values from beginning to end or vice + * versa? Also, how many of the elements have the source and + * destination areas overlapping? + */ + if (src->size>=dst->size || buf_stride>0) { + sp = dp = (uint8_t*)_buf; + direction = 1; + } else { + sp = (uint8_t*)_buf + (nelmts-1) * + (buf_stride ? buf_stride : src->size); + dp = (uint8_t*)_buf + (nelmts-1) * + (buf_stride ? buf_stride : dst->size); + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + src_delta = direction * (buf_stride ? buf_stride : src->size); + dst_delta = direction * (buf_stride ? buf_stride : dst->size); + + /* Set up conversion path for base elements */ + tpath = H5T_path_find(src->parent, dst->parent, NULL, NULL); + if (NULL==(tpath=H5T_path_find(src->parent, dst->parent, + NULL, NULL))) { + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest " + "datatypes"); + } else if (!H5T_IS_NOOP(tpath)) { + if ((tsrc_id = H5I_register(H5I_DATATYPE, + H5T_copy(src->parent, + H5T_COPY_ALL)))<0 || + (tdst_id = H5I_register(H5I_DATATYPE, + H5T_copy(dst->parent, + H5T_COPY_ALL)))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + } + + /* Perform the actual conversion */ + for (elmtno=0; elmtno<nelmts; elmtno++) { + /* Copy the source array into the correct location for the destination */ + HDmemmove(dp, sp, src->size); + + /* Convert array */ + if (H5T_convert(tpath, tsrc_id, tdst_id, src->u.array.nelem, 0, 0, + dp, NULL, dset_xfer_plist)<0) + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "datatype conversion failed"); + + /* Advance the source & destination pointers */ + sp += src_delta; + dp += dst_delta; + } + + /* Release the temporary datatype IDs used */ + if (tsrc_id >= 0) + H5I_dec_ref(tsrc_id); + if (tdst_id >= 0) + H5I_dec_ref(tdst_id); + break; + + default: /* Some other command we don't know about yet.*/ + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } /* end switch */ + + FUNC_LEAVE (SUCCEED); +} /* end H5T_conv_array() */ + + +/*------------------------------------------------------------------------- * Function: H5T_conv_i_i * * Purpose: Convert one integer type to another. This is the catch-all diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 2e150ad..5917945 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -74,6 +74,9 @@ typedef struct H5T_compnd_t { intn nalloc; /*num entries allocated in MEMB array*/ intn nmembs; /*number of members defined in struct*/ H5T_sort_t sorted; /*how are members sorted? */ + hbool_t has_array; /* Set if this type has an array datatype member */ + /* and should be written with the new version of */ + /* the datatype object header message */ struct H5T_cmemb_t *memb; /*array of struct members */ } H5T_compnd_t; @@ -106,6 +109,14 @@ typedef struct H5T_opaque_t { char *tag; /*short type description string */ } H5T_opaque_t; +/* An array datatype */ +typedef struct H5T_array_t { + size_t nelem; /* total number of elements in array */ + intn ndims; /* member dimensionality */ + size_t dim[H5S_MAX_RANK]; /* size in each dimension */ + intn perm[H5S_MAX_RANK]; /* index permutation */ +} H5T_array_t; + typedef enum H5T_state_t { H5T_STATE_TRANSIENT, /*type is a modifiable transient */ H5T_STATE_RDONLY, /*transient, not modifiable, closable*/ @@ -123,11 +134,12 @@ struct H5T_t { 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 data types */ union { - H5T_atomic_t atomic; /*an atomic data type */ - H5T_compnd_t compnd; /*a compound data type (struct) */ - H5T_enum_t enumer; /*an enumeration type (enum) */ - H5T_vlen_t vlen; /*an VL type */ - H5T_opaque_t opaque; /*an opaque data type */ + H5T_atomic_t atomic; /* an atomic data type */ + H5T_compnd_t compnd; /* a compound data type (struct) */ + H5T_enum_t enumer; /* an enumeration type (enum) */ + H5T_vlen_t vlen; /* a variable-length datatype */ + H5T_opaque_t opaque; /* an opaque data type */ + H5T_array_t array; /* an array datatype */ } u; }; @@ -136,9 +148,6 @@ typedef struct H5T_cmemb_t { char *name; /*name of this member */ size_t offset; /*offset from beginning of struct */ size_t size; /*total size: dims * type_size */ - intn ndims; /*member dimensionality */ - size_t dim[4]; /*size in each dimension */ - intn perm[4]; /*index permutation */ struct H5T_t *type; /*type of this member */ } H5T_cmemb_t; @@ -235,6 +244,10 @@ __DLL__ herr_t H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg, hid_t dset_xfer_plist); +__DLL__ herr_t H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg, + hid_t dset_xfer_plist); __DLL__ herr_t H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *bkg, @@ -746,6 +759,10 @@ __DLL__ hssize_t H5T_vlen_disk_getlen(H5F_t *f, void *vl_addr); __DLL__ herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *_buf, size_t len); __DLL__ herr_t H5T_vlen_disk_write(const H5D_xfer_t *xfer_parms, H5F_t *f, void *vl_addr, void *_buf, hsize_t seq_len, hsize_t base_size); +/* Array functions */ +__DLL__ H5T_t * H5T_array_create(H5T_t *base, int ndims, + const hsize_t dim[/* ndims */], const int perm[/* ndims */]); + /* Reference specific functions */ __DLL__ H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 8fcf19c..59f3e8b 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -109,9 +109,8 @@ __DLL__ H5T_class_t H5T_get_class(const H5T_t *dt); __DLL__ size_t H5T_get_size(const H5T_t *dt); __DLL__ intn H5T_cmp(const H5T_t *dt1, const H5T_t *dt2); __DLL__ htri_t H5T_is_atomic(const H5T_t *dt); -__DLL__ herr_t H5T_struct_insert(H5T_t *parent, const char *name, - size_t offset, intn ndims, const size_t *dim, - const intn *perm, const H5T_t *member); +__DLL__ herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, + const H5T_t *member); __DLL__ herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value); __DLL__ herr_t H5T_pack(H5T_t *dt); __DLL__ herr_t H5T_debug(H5T_t *dt, FILE * stream); diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 5d218a9..95fa939 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -36,6 +36,7 @@ typedef enum H5T_class_t { H5T_REFERENCE = 7, /*reference types */ H5T_ENUM = 8, /*enumeration types */ H5T_VLEN = 9, /*Variable-Length types */ + H5T_ARRAY = 10, /*Array types */ H5T_NCLASSES /*this must be last */ } H5T_class_t; @@ -457,9 +458,11 @@ __DLL__ htri_t H5Tcommitted(hid_t type_id); /* Operations defined on compound data types */ __DLL__ herr_t H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id); +#ifdef QAK __DLL__ herr_t H5Tinsert_array(hid_t parent_id, const char *name, size_t offset, int ndims, const size_t dim[], const int *perm, hid_t member_id); +#endif /* QAK */ __DLL__ herr_t H5Tpack(hid_t type_id); /* Operations defined on enumeration data types */ @@ -473,6 +476,12 @@ __DLL__ herr_t H5Tenum_valueof(hid_t type, const char *name, /* Operations defined on variable-length data types */ __DLL__ hid_t H5Tvlen_create(hid_t base_id); +/* Operations defined on array data types */ +__DLL__ hid_t H5Tarray_create(hid_t base_id, int ndims, + const hsize_t dim[/* ndims */], const int perm[/* ndims */]); +__DLL__ int H5Tget_array_ndims(hid_t type_id); +__DLL__ herr_t H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]); + /* Operations defined on opaque data types */ __DLL__ herr_t H5Tset_tag(hid_t type, const char *tag); __DLL__ char *H5Tget_tag(hid_t type); @@ -497,8 +506,10 @@ __DLL__ H5T_str_t H5Tget_strpad(hid_t type_id); __DLL__ int H5Tget_nmembers(hid_t type_id); __DLL__ char *H5Tget_member_name(hid_t type_id, int membno); __DLL__ size_t H5Tget_member_offset(hid_t type_id, int membno); +#ifdef QAK __DLL__ int H5Tget_member_dims(hid_t type_id, int membno, size_t dims[]/*out*/, int perm[]/*out*/); +#endif /* QAK */ __DLL__ hid_t H5Tget_member_type(hid_t type_id, int membno); __DLL__ herr_t H5Tget_member_value(hid_t type_id, int membno, void *value/*out*/); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index f2958a0..ea2f7c0 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -473,7 +473,8 @@ herr_t H5T_vlen_disk_write(const H5D_xfer_t UNUSED *xfer_parms, H5F_t *f, void * static herr_t H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *free_info) { - intn i,j; /* local counting variable */ + intn i; /* local index variable */ + size_t j; /* local index variable */ herr_t ret_value = SUCCEED; FUNC_ENTER(H5T_vlen_reclaim_recurse, FAIL); @@ -483,36 +484,42 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre /* Check the datatype of this element */ switch(dt->type) { - /* Check each field and recurse on VL and compound ones */ + case H5T_ARRAY: + /* Recurse on each element, if the array's base type is array, VL or compound */ + if(dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) { + void *off; /* offset of field */ + + /* Calculate the offset member and recurse on it */ + for(j=0; j<dt->u.array.nelem; j++) { + off=((uint8_t *)elem)+j*(dt->parent->size); + if(H5T_vlen_reclaim_recurse(off,dt->parent,free_func,free_info)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free array element"); + } /* end for */ + } /* end if */ + break; + case H5T_COMPOUND: + /* Check each field and recurse on VL, compound or array ones */ for (i=0; i<dt->u.compnd.nmembs; i++) { - /* Recurse if it's VL or compound */ - if(dt->u.compnd.memb[i].type->type==H5T_COMPOUND || dt->u.compnd.memb[i].type->type==H5T_VLEN) { - uintn nelem=1; /* Number of array elements in field */ + /* Recurse if it's VL, compound or array */ + if(dt->u.compnd.memb[i].type->type==H5T_COMPOUND || dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->type==H5T_ARRAY) { void *off; /* offset of field */ - /* Compute the number of array elements in field */ - for(j=0; j<dt->u.compnd.memb[i].ndims; j++) - nelem *= dt->u.compnd.memb[i].dim[j]; - - /* Calculate the offset of each array element and recurse on it */ - while(nelem>0) { - off=((uint8_t *)elem)+dt->u.compnd.memb[i].offset+(nelem-1)*dt->u.compnd.memb[i].type->size; - if(H5T_vlen_reclaim_recurse(off,dt->u.compnd.memb[i].type,free_func,free_info)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field"); - nelem--; - } /* end while */ + /* Calculate the offset member and recurse on it */ + off=((uint8_t *)elem)+dt->u.compnd.memb[i].offset; + if(H5T_vlen_reclaim_recurse(off,dt->u.compnd.memb[i].type,free_func,free_info)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field"); } /* end if */ } /* end for */ break; - /* Recurse on the VL information if it's VL or compound, then free VL sequence */ case H5T_VLEN: + /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */ if(dt->u.vlen.type==H5T_VLEN_SEQUENCE) { hvl_t *vl=(hvl_t *)elem; /* Temp. ptr to the vl info */ /* Recurse if it's VL or compound */ - if(dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN) { + if(dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) { void *off; /* offset of field */ /* Calculate the offset of each array element and recurse on it */ @@ -527,8 +534,9 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre /* Free the VL sequence */ if(free_func!=NULL) (*free_func)(vl->p,free_info); - else + else { H5MM_xfree(vl->p); + } } else if(dt->u.vlen.type==H5T_VLEN_STRING) { /* Free the VL string */ if(free_func!=NULL) @@ -628,6 +636,9 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) { htri_t vlen_changed; /* Whether H5T_vlen_mark changed the type (even if the size didn't change) */ htri_t ret_value = 0; /* Indicate that success, but no location change */ + intn i; /* Local index variable */ + intn accum_change=0; /* Amount of change in the offset of the fields */ + size_t old_size; /* Previous size of a field */ FUNC_ENTER(H5T_vlen_mark, FAIL); @@ -636,14 +647,30 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) /* Check the datatype of this element */ switch(dt->type) { - /* Check each field and recurse on VL and compound ones */ - case H5T_COMPOUND: + case H5T_ARRAY: /* Recurse on VL, compound and array base element type */ + /* Recurse if it's VL, compound or array */ + /* (If the type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */ + if((dt->parent->type==H5T_COMPOUND && dt->parent->force_conv) || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) { + /* Keep the old base element size for later */ + old_size=dt->parent->size; + + /* Mark the VL, compound or array type */ + if((vlen_changed=H5T_vlen_mark(dt->parent,f,loc))<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location"); + if(vlen_changed>0) + ret_value=vlen_changed; + + /* Check if the field changed size */ + if(old_size != dt->parent->size) { + /* Adjust the size of the array */ + dt->size = dt->u.array.nelem*dt->parent->size; + } /* end if */ + } /* end if */ + break; + + case H5T_COMPOUND: /* Check each field and recurse on VL, compound and array type */ /* Compound datatypes can't change in size if the force_conv flag is not set */ if(dt->force_conv) { - intn i; /* local counting variable */ - intn accum_change=0; /* Amount of change in the offset of the fields */ - size_t old_size; /* Preview size of a field */ - /* Sort the fields based on offsets */ H5T_sort_value(dt,NULL); @@ -651,13 +678,13 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) /* Apply the accumulated size change to the offset of the field */ dt->u.compnd.memb[i].offset += accum_change; - /* Recurse if it's VL or compound */ + /* Recurse if it's VL, compound or array */ /* (If the type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */ - if((dt->u.compnd.memb[i].type->type==H5T_COMPOUND && dt->u.compnd.memb[i].type->force_conv) || dt->u.compnd.memb[i].type->type==H5T_VLEN) { + if((dt->u.compnd.memb[i].type->type==H5T_COMPOUND && dt->u.compnd.memb[i].type->force_conv) || dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->type==H5T_ARRAY) { /* Keep the old field size for later */ old_size=dt->u.compnd.memb[i].type->size; - /* Mark the VL or compound type */ + /* Mark the VL, compound or array type */ if((vlen_changed=H5T_vlen_mark(dt->u.compnd.memb[i].type,f,loc))<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location"); if(vlen_changed>0) @@ -679,11 +706,10 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) } /* end if */ break; - /* Recurse on the VL information if it's VL or compound, then free VL sequence */ - case H5T_VLEN: - /* Recurse if it's VL or compound */ + case H5T_VLEN: /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */ + /* Recurse if it's VL, compound or array */ /* (If the type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */ - if((dt->parent->type==H5T_COMPOUND && dt->parent->force_conv) || dt->parent->type==H5T_VLEN) { + if((dt->parent->type==H5T_COMPOUND && dt->parent->force_conv) || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) { if((vlen_changed=H5T_vlen_mark(dt->parent,f,loc))<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location"); if(vlen_changed>0) |