summaryrefslogtreecommitdiffstats
path: root/src/H5T.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1999-07-16 18:11:52 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1999-07-16 18:11:52 (GMT)
commitd762ea6a31d69a9ebe00e6ed818ab6415091b629 (patch)
tree88c21004ba9aa981aeb5bf18e9002ed9ceae633d /src/H5T.c
parent04e309953892847f42c8c3f8cffffbc862c462f2 (diff)
downloadhdf5-d762ea6a31d69a9ebe00e6ed818ab6415091b629.zip
hdf5-d762ea6a31d69a9ebe00e6ed818ab6415091b629.tar.gz
hdf5-d762ea6a31d69a9ebe00e6ed818ab6415091b629.tar.bz2
[svn-r1494] Lots of various bug-fixes on VL datatypes. VL datatype fields in compound
datatypes aren't yet working, but other ways of using them (vlen atomic, vlen compound and vlen vlen atomic, etc.) are working.
Diffstat (limited to 'src/H5T.c')
-rw-r--r--src/H5T.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/src/H5T.c b/src/H5T.c
index 51c4fff..4b7184f 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -4696,6 +4696,35 @@ H5T_open_oid (H5G_entry_t *ent)
FUNC_LEAVE (dt);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_cmp_field_off
+ *
+ * Purpose: Compares field offsets for qsort
+ *
+ * Return: <0, 0, or >0 if field1's offset is less than, equal to, or greater
+ * than field2's offset
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, July 15th, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5T_cmp_field_off(const void *_field1, const void *_field2)
+{
+ const H5T_cmemb_t *field1=(const H5T_cmemb_t *)_field1,
+ *field2=(const H5T_cmemb_t *)_field2;
+
+ if(field1->offset < field2->offset)
+ return(-1);
+ else if(field1->offset > field2->offset)
+ return(1);
+ else
+ return(0);
+}
/*-------------------------------------------------------------------------
@@ -4794,27 +4823,42 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
}
if (H5T_COMPOUND == new_dt->type) {
- /*
- * Copy all member fields to new type, then overwrite the
- * name and type fields of each new member with copied values.
- * That is, H5T_copy() is a deep copy.
- */
- new_dt->u.compnd.memb = H5MM_malloc(new_dt->u.compnd.nalloc *
- sizeof(H5T_cmemb_t));
- if (NULL==new_dt->u.compnd.memb) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
- HDmemcpy(new_dt->u.compnd.memb, old_dt->u.compnd.memb,
- new_dt->u.compnd.nmembs * sizeof(H5T_cmemb_t));
-
- for (i=0; i<new_dt->u.compnd.nmembs; i++) {
- s = new_dt->u.compnd.memb[i].name;
- new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method);
- new_dt->u.compnd.memb[i].type = tmp;
- }
+ intn accum_change=0; /* Amount of change in the offset of the fields */
+
+ /*
+ * Copy all member fields to new type, then overwrite the
+ * name and type fields of each new member with copied values.
+ * That is, H5T_copy() is a deep copy.
+ */
+ new_dt->u.compnd.memb = H5MM_malloc(new_dt->u.compnd.nalloc *
+ sizeof(H5T_cmemb_t));
+ if (NULL==new_dt->u.compnd.memb) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ HDmemcpy(new_dt->u.compnd.memb, old_dt->u.compnd.memb,
+ new_dt->u.compnd.nmembs * sizeof(H5T_cmemb_t));
+
+ /* Sort the fields based on offsets */
+ qsort(new_dt->u.compnd.memb, new_dt->u.compnd.nmembs, sizeof(H5T_cmemb_t), H5T_cmp_field_off);
+ for (i=0; i<new_dt->u.compnd.nmembs; i++) {
+ s = new_dt->u.compnd.memb[i].name;
+ new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s);
+ tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method);
+ new_dt->u.compnd.memb[i].type = tmp;
+
+ /* Apply the accumulated size change to the offset of the field */
+ new_dt->u.compnd.memb[i].offset += accum_change;
+
+ /* If the field changed size, add that change to the accumulated size change */
+ if(new_dt->u.compnd.memb[i].type->size != old_dt->u.compnd.memb[i].type->size)
+ accum_change += (new_dt->u.compnd.memb[i].type->size - old_dt->u.compnd.memb[i].type->size);
+ }
+
+ /* Apply the accumulated size change to the size of the compound struct */
+ new_dt->size += accum_change;
+
} else if (H5T_ENUM == new_dt->type) {
/*
* Copy all member fields to new type, then overwrite the name fields
@@ -4836,9 +4880,11 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
new_dt->u.enumer.name[i] = H5MM_xstrdup(s);
}
} else if (H5T_VLEN == new_dt->type) {
- /* H5T_copy converts any VL type into a memory VL type */
- if (H5T_vlen_mark(new_dt, NULL, H5T_VLEN_MEMORY)<0) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ if(method==H5T_COPY_TRANSIENT || method==H5T_COPY_REOPEN) {
+ /* H5T_copy converts any VL type into a memory VL type */
+ if (H5T_vlen_mark(new_dt, NULL, H5T_VLEN_MEMORY)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ }
}
} else if (H5T_OPAQUE == new_dt->type) {
/*