summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-09-12 04:35:48 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-09-12 04:35:48 (GMT)
commit965a4cd7c9a2339bd559a3d5fbbc14a957318da4 (patch)
tree61df28e4cbb1d88eb1d3390e5a04e1db8cfb4276 /src
parent987e281c8afa3ebd4113d9efba251be4074fd55f (diff)
downloadhdf5-965a4cd7c9a2339bd559a3d5fbbc14a957318da4.zip
hdf5-965a4cd7c9a2339bd559a3d5fbbc14a957318da4.tar.gz
hdf5-965a4cd7c9a2339bd559a3d5fbbc14a957318da4.tar.bz2
[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
Diffstat (limited to 'src')
-rw-r--r--src/H5Odtype.c24
-rw-r--r--src/H5T.c10
-rw-r--r--src/H5Tcompound.c178
-rw-r--r--src/H5Tpkg.h6
4 files changed, 161 insertions, 57 deletions
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(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 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; 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(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; 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() */
+
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