From 965a4cd7c9a2339bd559a3d5fbbc14a957318da4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 11 Sep 2003 23:35:48 -0500 Subject: [svn-r7468] Purpose: Code cleanup, etc. Description: Generalize Ray's datatype fixes to handle packing compound datatypes which are the base type of an array or variable-length type, etc. Also track "packedness" of a compound datatype from it's creation, instead of only setting the 'packed' flag after the datatype was explicitly packed. Updated docs to reflect that a compound datatype is allowed to grow (but not shrink). Platforms tested: FreeBSD 4.9 (sleipnir) h5committest --- doc/html/RM_H5T.html | 8 +-- release_docs/RELEASE.txt | 3 + src/H5Odtype.c | 24 +++++++ src/H5T.c | 10 ++- src/H5Tcompound.c | 178 +++++++++++++++++++++++++++++++++-------------- src/H5Tpkg.h | 6 +- test/dtypes.c | 89 +++++++++++++++++++----- 7 files changed, 240 insertions(+), 78 deletions(-) diff --git a/doc/html/RM_H5T.html b/doc/html/RM_H5T.html index a877ff5..7895b71 100644 --- a/doc/html/RM_H5T.html +++ b/doc/html/RM_H5T.html @@ -1071,15 +1071,15 @@ H5Tget_overflow ()
Sets the total size for an atomic datatype.
Description:
H5Tset_size sets the total size in bytes, - size, for an atomic datatype (this operation - is not permitted on compound datatypes). If the size is - decreased so that the significant bits of the datatype extend beyond + size, for a datatype. If the datatype is atomic and size + is decreased so that the significant bits of the datatype extend beyond the edge of the new size, then the `offset' property is decreased toward zero. If the `offset' becomes zero and the significant bits of the datatype still hang over the edge of the new size, then the number of significant bits is decreased. Adjusting the size of an H5T_STRING automatically sets the precision - to 8*size. All datatypes have a positive size. + to 8*size. A compound datatype may increase in size, but may not + shrink. All datatypes must have a positive size.
Parameters:
hid_t type_id diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 92997b7..1d56f38 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -74,6 +74,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - Allow compound datatypes to grow in size. SLU - 2003/09/10 + - Detect if a type is already packed before attempting to pack it + again or check if it is locked. SLU - 2003/09/10 - Corrected bug when opening a file twice with read-only permission for one open and then closing the read-only access file ID would generate an error. QAK - 2003/09/10 diff --git a/src/H5Odtype.c b/src/H5Odtype.c index d6de6f6..2c943cf 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; diff --git a/src/H5T.c b/src/H5T.c index 0c7257c..cea739e 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -2633,7 +2633,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)) + 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"); @@ -3307,6 +3307,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: @@ -3955,10 +3957,12 @@ H5T_set_size(H5T_t *dt, size_t size) case H5T_OPAQUE: /* nothing to check */ break; + case H5T_COMPOUND: - if(size>dt->size) - dt->size = size; + if(sizesize) + 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 a571d97..e21f865 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -68,7 +68,7 @@ H5T_init_compound_interface(void) * Function: H5Tget_member_offset * * Purpose: Returns the byte offset of the beginning of a member with - * respect to the beginning of the compound data type datum. + * respect to the beginning of the compound datatype datum. * * Return: Success: Byte offset. * @@ -95,7 +95,7 @@ H5Tget_member_offset(hid_t type_id, int membno) /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a compound datatype"); if (membno < 0 || membno >= dt->u.compnd.nmembs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid member number"); @@ -112,7 +112,7 @@ done: * * Purpose: Private function for H5Tget_member_offset. Returns the byte * offset of the beginning of a member with respect to the i - * beginning of the compound data type datum. + * beginning of the compound datatype datum. * * Return: Success: Byte offset. * @@ -173,7 +173,7 @@ H5Tget_member_class(hid_t type_id, int membno) /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a compound datatype"); if (membno < 0 || membno >= dt->u.compnd.nmembs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number"); @@ -188,12 +188,12 @@ done: /*------------------------------------------------------------------------- * Function: H5Tget_member_type * - * Purpose: Returns the data type of the specified member. The caller + * Purpose: Returns the datatype of the specified member. The caller * should invoke H5Tclose() to release resources associated with * the type. * - * Return: Success: An OID of a copy of the member data type; - * modifying the returned data type does not + * Return: Success: An OID of a copy of the member datatype; + * modifying the returned datatype does not * modify the member type. * * Failure: Negative @@ -220,13 +220,13 @@ H5Tget_member_type(hid_t type_id, int membno) /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)) || H5T_COMPOUND != dt->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype"); if (membno < 0 || membno >= dt->u.compnd.nmembs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); if ((memb_dt=H5T_get_member_type(dt, membno))==NULL) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to retrieve member type"); if ((ret_value = H5I_register(H5I_DATATYPE, memb_dt)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable register data type atom"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable register datatype atom"); done: if(ret_value<0) { @@ -244,8 +244,8 @@ done: * Purpose: Private function for H5Tget_member_type. Returns the data * type of the specified member. * - * Return: Success: A copy of the member data type; - * modifying the returned data type does not + * Return: Success: A copy of the member datatype; + * modifying the returned datatype does not * modify the member type. * * Failure: NULL @@ -267,9 +267,9 @@ H5T_get_member_type(H5T_t *dt, int membno) assert(dt); assert(membno >=0 && membno < dt->u.compnd.nmembs); - /* Copy data type into an atom */ + /* Copy datatype into an atom */ if (NULL == (ret_value = H5T_copy(dt->u.compnd.memb[membno].type, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member data type"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member datatype"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -279,10 +279,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Tinsert * - * Purpose: Adds another member to the compound data type PARENT_ID. The + * Purpose: Adds another member to the compound datatype 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 + * compound datatype. The OFFSET argument defines the start of + * the member in an instance of the compound datatype, and * MEMBER_ID is the type of the new member. * * Return: Success: Non-negative, the PARENT_ID compound data @@ -303,7 +303,7 @@ done: herr_t H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id) { - H5T_t *parent = NULL; /*the compound parent data type */ + H5T_t *parent = NULL; /*the compound parent datatype */ H5T_t *member = NULL; /*the atomic member type */ herr_t ret_value=SUCCEED; /* Return value */ @@ -314,19 +314,17 @@ H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id) if (parent_id==member_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't insert compound datatype within itself"); if (NULL == (parent = H5I_object_verify(parent_id,H5I_DATATYPE)) || H5T_COMPOUND != parent->type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype"); if (H5T_STATE_TRANSIENT!=parent->state) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only"); if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no member name"); if (NULL == (member = H5I_object_verify(member_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); /* Insert */ if (H5T_insert(parent, name, offset, member) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "unable to insert member"); - - parent->packed = FALSE; done: FUNC_LEAVE_API(ret_value); @@ -336,7 +334,7 @@ done: /*------------------------------------------------------------------------- * Function: H5Tpack * - * Purpose: Recursively removes padding from within a compound data type + * Purpose: Recursively removes padding from within a compound datatype * to make it more efficient (space-wise) to store that data. * * Return: Non-negative on success/Negative on failure @@ -358,21 +356,13 @@ 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) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); - /* If datatype has been packed, skip this step and go to done */ - if(dt->packed == TRUE) - HGOTO_DONE(ret_value); - if (H5T_STATE_TRANSIENT!=dt->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only"); + 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 datatype"); /* Pack */ if (H5T_pack(dt) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound data type"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound datatype"); - /* Indicate datatype has been packed */ - dt->packed = TRUE; - done: FUNC_LEAVE_API(ret_value); } @@ -381,7 +371,7 @@ done: /*------------------------------------------------------------------------- * Function: H5T_insert * - * Purpose: Adds a new MEMBER to the compound data type PARENT. The new + * Purpose: Adds a new MEMBER to the compound datatype PARENT. The new * member will have a NAME that is unique within PARENT and an * instance of PARENT will have the member begin at byte offset * OFFSET from the beginning. @@ -454,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 */ @@ -468,7 +481,7 @@ done: /*------------------------------------------------------------------------- * Function: H5T_pack * - * Purpose: Recursively packs a compound data type by removing padding + * Purpose: Recursively packs a compound datatype by removing padding * bytes. This is done in place (that is, destructively). * * Return: Non-negative on success/Negative on failure @@ -487,29 +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) { - /* Recursively pack the members */ - for (i=0; iu.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; iu.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(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"); + + 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; iu.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 datatype"); + + /* Remove padding between members */ + H5T_sort_value(dt, NULL); + for (i=0, offset=0; iu.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 e6127af..2058e6a 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -128,6 +128,7 @@ 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? */ + hbool_t packed; /*are members packed together? */ struct H5T_cmemb_t *memb; /*array of struct members */ } H5T_compnd_t; @@ -194,7 +195,6 @@ struct H5T_t { H5T_class_t type; /*which class of type is this? */ size_t size; /*total size of an instance of this type */ hbool_t force_conv;/* Set if this type always needs to be converted and H5T_conv_noop cannot be called */ - hbool_t packed; /*whether a compound type is packed */ struct H5T_t *parent;/*parent type for derived datatypes */ union { H5T_atomic_t atomic; /* an atomic datatype */ @@ -873,4 +873,8 @@ H5_DLL htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); /* 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 diff --git a/test/dtypes.c b/test/dtypes.c index eb42834..d8a6229 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1135,7 +1135,9 @@ test_compound_6(void) /*------------------------------------------------------------------------- * Function: test_compound_7 * - * Purpose: Tests increasing compound type size. + * Purpose: Tests inserting fields into compound datatypes when the field + * overlaps the end of the compound datatype. Also, tests + * increasing compound type size. * * Return: Success: 0 * @@ -1208,7 +1210,33 @@ test_compound_7(void) goto error; } /* end if */ - /* Increase compound type size */ + if(H5Tget_size(tid2)==sizeof(struct s2)) { + H5_FAILED(); + printf("Incorrect size for struct 2\n"); + goto error; + } /* end if */ + + /* Should not be able to insert field past end of compound datatype */ + H5E_BEGIN_TRY { + ret=H5Tinsert(tid2,"d",HOFFSET(struct s2,d),H5T_NATIVE_DOUBLE); + } H5E_END_TRY; + if(ret>=0) { + H5_FAILED(); + printf("Inserted field 'd'?\n"); + goto error; + } /* end if */ + + /* Should not be able to shrink size of compound datatype */ + H5E_BEGIN_TRY { + ret=H5Tset_size(tid2, sizeof(struct s1)/2); + } H5E_END_TRY; + if(ret>=0) { + H5_FAILED(); + printf("Shrunk compound type?\n"); + goto error; + } /* end if */ + + /* Increase compound type size and try inserting field again */ if(H5Tset_size(tid2, sizeof(struct s2))<0) { H5_FAILED(); printf("Incorrect size for struct 2\n"); @@ -1272,46 +1300,46 @@ test_compound_8(void) s1 d; } s2; - hid_t tid1, tid2; - size_t cmpd_size; + hid_t tid1, tid2, tid3; herr_t ret; - TESTING("H5Tpack for compound data types"); + TESTING("packing compound data types"); /* Create first compound datatype */ if((tid1 = H5Tcreate( H5T_COMPOUND, sizeof(struct s1)))<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't create datatype!\n"); goto error; } /* end if */ if(H5Tinsert(tid1,"a",HOFFSET(struct s1,a),H5T_NATIVE_CHAR)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't insert field 'a'\n"); goto error; } /* end if */ if(H5Tinsert(tid1,"b",HOFFSET(struct s1,b),H5T_NATIVE_INT)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't insert field 'b'\n"); goto error; } /* end if */ /* Test H5Tpack for the first compound type */ if(H5Tpack(tid1)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't pack the compound data type\n"); goto error; } /* end if */ if(H5Tlock(tid1)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't lock the compound data type\n"); goto error; } /* end if */ + /* If the type is already packed, packing a locked type is OK */ if(H5Tpack(tid1)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't pack the compound data type for second time\n"); goto error; } /* end if */ @@ -1319,42 +1347,69 @@ test_compound_8(void) /* Create second compound datatype */ if((tid2 = H5Tcreate( H5T_COMPOUND, sizeof(struct s2)))<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't create datatype!\n"); goto error; } /* end if */ if(H5Tinsert(tid2,"c",HOFFSET(struct s2,c),H5T_NATIVE_CHAR)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't insert field 'c'\n"); goto error; } /* end if */ if(H5Tinsert(tid2,"d",HOFFSET(struct s2,d),tid1)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't insert field 'd'\n"); goto error; } /* end if */ + /* Make a copy of the type for later */ + if((tid3=H5Tcopy(tid2))<0) { + H5_FAILED(); AT(); + printf("Can't copy type #2\n"); + goto error; + } /* end if */ + /* Test H5Tpack for the second compound type */ if(H5Tpack(tid2)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't pack the compound data type\n"); goto error; } /* end if */ if(H5Tlock(tid2)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't lock the compound data type\n"); goto error; } /* end if */ + /* If the type is already packed, packing a locked type is OK */ if(H5Tpack(tid2)<0) { - H5_FAILED(); + H5_FAILED(); AT(); printf("Can't pack the compound data type for second time\n"); goto error; } /* end if */ + /* Lock unpacked type */ + if(H5Tlock(tid3)<0) { + H5_FAILED(); AT(); + printf("Can't lock the compound data type\n"); + goto error; + } /* end if */ + + /* If the type is not packed, packing a locked type shouldn't work */ + H5E_BEGIN_TRY { + ret=H5Tpack(tid3); + } H5E_END_TRY; + if(ret>=0) { + H5_FAILED(); AT(); + printf("Packing locked datatype worked?\n"); + goto error; + } /* end if */ + + /* Can't release resources - they are locked */ + PASSED(); return 0; -- cgit v0.12