diff options
-rw-r--r-- | MANIFEST | 4 | ||||
-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 |
9 files changed, 1351 insertions, 964 deletions
@@ -608,11 +608,15 @@ ./test/overhead.c ./test/ragged.c ./test/space_overflow.c _DO_NOT_DISTRIBUTE_ +./test/gen_old_array.c _DO_NOT_DISTRIBUTE_ +./test/gen_new_array.c _DO_NOT_DISTRIBUTE_ ./test/srb_append.c ./test/srb_read.c ./test/srb_write.c ./test/stab.c ./test/stream_test.c +./test/tarray.c +./test/tarrold.h5 ./test/tattr.c ./test/testhdf5.c ./test/testhdf5.h 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) |