diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Odtype.c | 24 | ||||
-rw-r--r-- | src/H5T.c | 10 | ||||
-rw-r--r-- | src/H5Tcompound.c | 122 | ||||
-rw-r--r-- | src/H5Tpkg.h | 9 |
4 files changed, 139 insertions, 26 deletions
diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 849e0b9..934c113 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -187,6 +187,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) */ dt->u.compnd.nmembs = flags & 0xffff; assert(dt->u.compnd.nmembs > 0); + dt->u.compnd.packed = TRUE; /* Start off packed */ dt->u.compnd.nalloc = dt->u.compnd.nmembs; dt->u.compnd.memb = H5MM_calloc(dt->u.compnd.nalloc* sizeof(H5T_cmemb_t)); @@ -278,6 +279,29 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) /* Set the field datatype (finally :-) */ dt->u.compnd.memb[i].type=temp_type; + + /* Check if the datatype stayed packed */ + if(dt->u.compnd.packed) { + /* Check if the member type is packed */ + if(H5T_is_packed(temp_type)>0) { + if(i==0) { + /* If the is the first member, the datatype is not packed + * if the first member isn't at offset 0 + */ + if(dt->u.compnd.memb[i].offset>0) + dt->u.compnd.packed=FALSE; + } /* end if */ + else { + /* If the is not the first member, the datatype is not + * packed if the new member isn't adjoining the previous member + */ + if(dt->u.compnd.memb[i].offset!=(dt->u.compnd.memb[i-1].offset+dt->u.compnd.memb[i-1].size)) + dt->u.compnd.packed=FALSE; + } /* end else */ + } /* end if */ + else + dt->u.compnd.packed=FALSE; + } /* end if */ } break; @@ -2660,7 +2660,7 @@ H5Tset_size(hid_t type_id, size_t size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive"); if (size == H5T_VARIABLE && dt->type!=H5T_STRING) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length"); - if ((H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) || (H5T_COMPOUND==dt->type && dt->u.compnd.nmembs>0)) + if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); if (H5T_REFERENCE==dt->type) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype"); @@ -3334,6 +3334,8 @@ H5T_create(H5T_class_t type, size_t size) if (NULL==(dt = H5FL_CALLOC(H5T_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); dt->type = type; + if(type==H5T_COMPOUND) + dt->u.compnd.packed=TRUE; /* Start out packed */ break; case H5T_ENUM: @@ -4014,10 +4016,14 @@ H5T_set_size(H5T_t *dt, size_t size) case H5T_TIME: case H5T_BITFIELD: case H5T_OPAQUE: - case H5T_COMPOUND: /* nothing to check */ break; + case H5T_COMPOUND: + if(size<dt->size) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "can't shrink compound datatype"); + break; + case H5T_STRING: /* Convert string to variable-length datatype */ if(size==H5T_VARIABLE) { diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index 790de46..a1c93a1 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -356,10 +356,8 @@ H5Tpack(hid_t type_id) H5TRACE1("e","i",type_id); /* Check args */ - if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) + if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_detect_class(dt,H5T_COMPOUND)<=0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only"); /* Pack */ if (H5T_pack(dt) < 0) @@ -446,6 +444,29 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) parent->u.compnd.sorted = H5T_SORT_NONE; parent->u.compnd.nmembs++; + /* Determine if the compound datatype stayed packed */ + if(parent->u.compnd.packed) { + /* Check if the member type is packed */ + if(H5T_is_packed(parent->u.compnd.memb[idx].type)>0) { + if(idx==0) { + /* If the is the first member, the datatype is not packed + * if the first member isn't at offset 0 + */ + if(parent->u.compnd.memb[idx].offset>0) + parent->u.compnd.packed=FALSE; + } /* end if */ + else { + /* If the is not the first member, the datatype is not + * packed if the new member isn't adjoining the previous member + */ + if(parent->u.compnd.memb[idx].offset!=(parent->u.compnd.memb[idx-1].offset+parent->u.compnd.memb[idx-1].size)) + parent->u.compnd.packed=FALSE; + } /* end else */ + } /* end if */ + else + parent->u.compnd.packed=FALSE; + } /* end if */ + /* * Set the "force conversion" flag if the field's datatype indicates */ @@ -479,31 +500,88 @@ H5T_pack(H5T_t *dt) size_t offset; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_pack, FAIL); + FUNC_ENTER_NOINIT(H5T_pack); assert(dt); - if (H5T_COMPOUND == dt->type) { - assert(H5T_STATE_TRANSIENT==dt->state); + if(H5T_detect_class(dt,H5T_COMPOUND)>0) { + /* If datatype has been packed, skip packing it and indicate success */ + if(H5T_is_packed(dt)== TRUE) + HGOTO_DONE(SUCCEED); + + /* Check for packing unmodifiable datatype */ + if (H5T_STATE_TRANSIENT!=dt->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only"); - /* Recursively pack the members */ - for (i=0; i<dt->u.compnd.nmembs; i++) { - if (H5T_pack(dt->u.compnd.memb[i].type) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound data type"); - } - - /* Remove padding between members */ - H5T_sort_value(dt, NULL); - for (i=0, offset=0; i<dt->u.compnd.nmembs; i++) { - dt->u.compnd.memb[i].offset = offset; - offset += dt->u.compnd.memb[i].size; - } - - /* Change total size */ - dt->size = MAX(1, offset); - } + if(dt->parent) { + if (H5T_pack(dt->parent) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack parent of datatype"); + + /* Adjust size of datatype appropriately */ + if(dt->type==H5T_ARRAY) + dt->size = dt->parent->size * dt->u.array.nelem; + else if(dt->type!=H5T_VLEN) + dt->size = dt->parent->size; + } /* end if */ + else if(dt->type==H5T_COMPOUND) { + /* Recursively pack the members */ + for (i=0; i<dt->u.compnd.nmembs; i++) + if (H5T_pack(dt->u.compnd.memb[i].type) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound data type"); + + /* Remove padding between members */ + H5T_sort_value(dt, NULL); + for (i=0, offset=0; i<dt->u.compnd.nmembs; i++) { + dt->u.compnd.memb[i].offset = offset; + offset += dt->u.compnd.memb[i].size; + } + + /* Change total size */ + dt->size = MAX(1, offset); + + /* Mark the type as packed now */ + dt->u.compnd.packed=TRUE; + } /* end if */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value); } + +/*------------------------------------------------------------------------- + * Function: H5T_is_packed + * + * Purpose: Checks whether a datatype which is compound (or has compound + * components) is packed. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, September 11, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5T_is_packed(H5T_t *dt) +{ + htri_t ret_value=TRUE; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_is_packed,FAIL); + + assert(dt); + + /* Go up the chain as far as possible */ + while(dt->parent) + dt=dt->parent; + + /* If this is a compound datatype, check if it is packed */ + if(dt->type==H5T_COMPOUND) + ret_value=dt->u.compnd.packed; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5T_is_packed() */ + diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 3ccbd0f..80a4075 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -123,8 +123,9 @@ typedef enum H5T_sort_t { typedef struct H5T_compnd_t { int nalloc; /*num entries allocated in MEMB array*/ int nmembs; /*number of members defined in struct*/ - H5T_sort_t sorted; /*how are members sorted? */ - struct H5T_cmemb_t *memb; /*array of struct members */ + H5T_sort_t sorted; /*how are members sorted? */ + hbool_t packed; /*are members packed together? */ + struct H5T_cmemb_t *memb; /*array of struct members */ } H5T_compnd_t; /* An enumeration data type */ @@ -861,4 +862,8 @@ H5_DLL herr_t H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void * /* Array functions */ H5_DLL H5T_t * H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */], const int perm[/* ndims */]); + +/* Compound functions */ +H5_DLL htri_t H5T_is_packed(H5T_t *dt); + #endif |