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