mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-12 17:31:09 +08:00
[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
This commit is contained in:
parent
987e281c8a
commit
965a4cd7c9
@ -1071,15 +1071,15 @@ H5Tget_overflow ()
|
||||
<dd>Sets the total size for an atomic datatype.
|
||||
<dt><strong>Description:</strong>
|
||||
<dd><code>H5Tset_size</code> sets the total size in bytes,
|
||||
<code>size</code>, 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
|
||||
<code>size</code>, 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.
|
||||
<dt><strong>Parameters:</strong>
|
||||
<dl>
|
||||
<dt><em>hid_t</em> <code>type_id</code>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
10
src/H5T.c
10
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(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) {
|
||||
|
@ -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; 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");
|
||||
}
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* Check for packing unmodifiable datatype */
|
||||
if (H5T_STATE_TRANSIENT!=dt->state)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only");
|
||||
|
||||
/* 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 datatype");
|
||||
|
||||
/* 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() */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user