summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5Sall.c8
-rw-r--r--src/H5T.c92
-rw-r--r--src/H5Tconv.c6
-rw-r--r--src/H5Tpkg.h13
-rw-r--r--src/H5Tvlen.c98
6 files changed, 115 insertions, 104 deletions
diff --git a/src/H5D.c b/src/H5D.c
index af4a188..5c366ba 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -987,7 +987,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
}
/* Create (open for write access) an object header */
- if (H5O_create(f, 96, &(new_dset->ent)) < 0) {
+ if (H5O_create(f, 256, &(new_dset->ent)) < 0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
"unable to create dataset object header");
}
diff --git a/src/H5Sall.c b/src/H5Sall.c
index db27b00..ff08fbc 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -991,15 +991,15 @@ H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op
ret_value=(*operator)(tmp_buf,type_id,rank,mem_offset,operator_data);
+ /* Decrement the number of elements to iterate through */
+ nelemts--;
+
/* Advance the coordinate (currently in C memory order) */
index=rank-1; /* Leave the byte offset in the element alone */
- while(++mem_offset[index]==mem_size[index] && index>=0) {
+ while(index>=0 && ++mem_offset[index]==mem_size[index]) {
mem_offset[index]=0;
index--;
} /* end while */
-
- /* Decrement the number of elements to iterate through */
- nelemts--;
} /* end while */
FUNC_LEAVE (ret_value);
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) {
/*
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index e34d980..eaf930d 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -1903,12 +1903,8 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
if (H5T_convert(tpath, tsrc_id, tdst_id, seq_len, 0, conv_buf_ptr, NULL, dset_xfer_plist)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");
- /* Allocate new VL buffer */
- if((*(dst->u.vlen.alloc))(xfer_parms,d,seq_len,dst_base_size)<0)
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "allocation failed for VL data");
-
/* Write sequence to destination location */
- if((*(dst->u.vlen.write))(dst->u.vlen.f,d,conv_buf_ptr,dst_size)<0)
+ if((*(dst->u.vlen.write))(xfer_parms,dst->u.vlen.f,d,conv_buf_ptr,seq_len,dst_base_size)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data");
/*
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 5941e0a..bb41580 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -88,8 +88,7 @@ typedef struct H5T_enum_t {
/* VL function pointers */
typedef hsize_t (*H5T_vlen_getlenfunc_t)(H5F_t *f, void *vl_addr);
typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, void *vl_addr, void *buf, size_t len);
-typedef herr_t (*H5T_vlen_allocfunc_t)(const H5F_xfer_t *xfer_parms, void *vl_addr, hsize_t seq_len, hsize_t base_size);
-typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, void *vl_addr, void *buf, size_t len);
+typedef herr_t (*H5T_vlen_writefunc_t)(const H5F_xfer_t *xfer_parms, H5F_t *f, void *vl_addr, void *buf, hsize_t seq_len, hsize_t base_size);
/* A VL datatype */
typedef struct H5T_vlen_t {
@@ -97,7 +96,6 @@ typedef struct H5T_vlen_t {
H5F_t *f; /* File ID (if VL data is on disk) */
H5T_vlen_getlenfunc_t getlen; /* Function to get VL sequence size (in element units, not bytes) */
H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */
- H5T_vlen_allocfunc_t alloc; /* Function to allocate space for VL sequence */
H5T_vlen_writefunc_t write; /* Function to write VL sequence from buffer */
} H5T_vlen_t;
@@ -208,6 +206,9 @@ __DLLVAR__ size_t H5T_NATIVE_UINT_LEAST64_ALIGN_g;
__DLLVAR__ size_t H5T_NATIVE_INT_FAST64_ALIGN_g;
__DLLVAR__ size_t H5T_NATIVE_UINT_FAST64_ALIGN_g;
+/* H5Tcopy support functions */
+__DLL__ int H5T_cmp_field_off(const void *_field1, const void *_field2);
+
/* Conversion functions */
__DLL__ herr_t H5T_conv_noop(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, size_t stride, void *buf,
@@ -541,12 +542,10 @@ __DLL__ htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size);
/* VL functions */
__DLL__ hsize_t H5T_vlen_mem_getlen(H5F_t *f, void *vl_addr);
__DLL__ herr_t H5T_vlen_mem_read(H5F_t *f, void *vl_addr, void *_buf, size_t len);
-__DLL__ herr_t H5T_vlen_mem_alloc(const H5F_xfer_t *xfer_parms, void *vl_addr, hsize_t seq_len, hsize_t base_size);
-__DLL__ herr_t H5T_vlen_mem_write(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+__DLL__ herr_t H5T_vlen_mem_write(const H5F_xfer_t *xfer_parms, H5F_t *f, void *vl_addr, void *_buf, hsize_t seq_len, hsize_t base_size);
__DLL__ hsize_t H5T_vlen_disk_getlen(H5F_t *f, void *vl_addr);
__DLL__ herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *_buf, size_t len);
-__DLL__ herr_t H5T_vlen_disk_alloc(const H5F_xfer_t *xfer_parms, void *vl_addr, hsize_t seq_len, hsize_t base_size);
-__DLL__ herr_t H5T_vlen_disk_write(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+__DLL__ herr_t H5T_vlen_disk_write(const H5F_xfer_t *xfer_parms, H5F_t *f, void *vl_addr, void *_buf, hsize_t seq_len, hsize_t base_size);
/* Reference specific functions */
__DLL__ H5R_type_t H5T_get_ref_type(H5T_t *dt);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index 1a70aa8..c9d0e35 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -71,7 +71,6 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc)
/* Set up the function pointers to access the VL information (in memory) */
dt->u.vlen.getlen=H5T_vlen_mem_getlen;
dt->u.vlen.read=H5T_vlen_mem_read;
- dt->u.vlen.alloc=H5T_vlen_mem_alloc;
dt->u.vlen.write=H5T_vlen_mem_write;
/* Reset file ID (since this VL is in memory) */
@@ -86,14 +85,14 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc)
/*
* Size of element on disk is 4 bytes for the length, plus the size
- * of an address in this file. Memory size is different
+ * of an address in this file, plus 4 bytes for the size of a heap
+ * ID. Memory size is different
*/
- dt->size = H5F_SIZEOF_ADDR(f)+4;
+ dt->size = 4 + H5F_SIZEOF_ADDR(f) + 4;
/* Set up the function pointers to access the VL information (in memory) */
dt->u.vlen.getlen=H5T_vlen_disk_getlen;
dt->u.vlen.read=H5T_vlen_disk_read;
- dt->u.vlen.alloc=H5T_vlen_disk_alloc;
dt->u.vlen.write=H5T_vlen_disk_write;
/* Set file ID (since this VL is on disk) */
@@ -169,9 +168,9 @@ herr_t H5T_vlen_mem_read(H5F_t UNUSED *f, void *vl_addr, void *buf, size_t len)
/*-------------------------------------------------------------------------
- * Function: H5T_vlen_mem_alloc
+ * Function: H5T_vlen_mem_write
*
- * Purpose: Allocates a memory based VL sequence
+ * Purpose: "Writes" the memory based VL sequence from a buffer
*
* Return: Non-negative on success/Negative on failure
*
@@ -182,14 +181,16 @@ herr_t H5T_vlen_mem_read(H5F_t UNUSED *f, void *vl_addr, void *buf, size_t len)
*
*-------------------------------------------------------------------------
*/
-herr_t H5T_vlen_mem_alloc(const H5F_xfer_t *xfer_parms, void *vl_addr, hsize_t seq_len, hsize_t base_size)
+herr_t H5T_vlen_mem_write(const H5F_xfer_t *xfer_parms, H5F_t UNUSED *f, void *vl_addr, void *buf, hsize_t seq_len, hsize_t base_size)
{
hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
+ size_t len=seq_len*base_size;
- FUNC_ENTER (H5T_vlen_mem_alloc, FAIL);
+ FUNC_ENTER (H5T_vlen_mem_write, FAIL);
/* check parameters */
assert(vl);
+ assert(buf);
/* Use the user's memory allocation routine is one is defined */
if(xfer_parms->vlen_alloc!=NULL) {
@@ -202,34 +203,6 @@ herr_t H5T_vlen_mem_alloc(const H5F_xfer_t *xfer_parms, void *vl_addr, hsize_t s
} /* end else */
vl->len=seq_len;
- FUNC_LEAVE (SUCCEED);
-} /* end H5T_vlen_mem_alloc() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5T_vlen_mem_write
- *
- * Purpose: "Writes" the memory based VL sequence from a buffer
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, June 2, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t H5T_vlen_mem_write(H5F_t UNUSED *f, void *vl_addr, void *buf, size_t len)
-{
- hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
-
- FUNC_ENTER (H5T_vlen_mem_write, FAIL);
-
- /* check parameters */
- assert(vl && vl->p);
- assert(buf);
-
HDmemcpy(vl->p,buf,len);
FUNC_LEAVE (SUCCEED);
@@ -309,32 +282,6 @@ herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *buf, size_t UNUSED len)
/*-------------------------------------------------------------------------
- * Function: H5T_vlen_disk_alloc
- *
- * Purpose: Allocates a disk based VL sequence
- * NOTE: This function is currently a NOOP, allocation of the heap block
- * is done when the block is written out.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, June 2, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t H5T_vlen_disk_alloc(const H5F_xfer_t UNUSED *f, void UNUSED *vl_addr, hsize_t UNUSED seq_len, hsize_t UNUSED base_size)
-{
- FUNC_ENTER (H5T_vlen_disk_alloc, FAIL);
-
- /* check parameters */
-
- FUNC_LEAVE (SUCCEED);
-} /* end H5T_vlen_disk_alloc() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5T_vlen_disk_write
*
* Purpose: Writes the disk based VL sequence from a buffer
@@ -348,11 +295,11 @@ herr_t H5T_vlen_disk_alloc(const H5F_xfer_t UNUSED *f, void UNUSED *vl_addr, hsi
*
*-------------------------------------------------------------------------
*/
-herr_t H5T_vlen_disk_write(H5F_t *f, void *vl_addr, void *buf, size_t len)
+herr_t H5T_vlen_disk_write(const H5F_xfer_t UNUSED *xfer_parms, H5F_t *f, void *vl_addr, void *buf, hsize_t seq_len, hsize_t base_size)
{
uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the user's hvl_t information */
H5HG_t hobjid;
- uint32_t seq_len;
+ size_t len=seq_len*base_size;
FUNC_ENTER (H5T_vlen_disk_write, FAIL);
@@ -554,13 +501,36 @@ H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc)
switch(dt->type) {
/* Check each field and recurse on VL and compound ones */
case H5T_COMPOUND:
+ {
+ intn accum_change=0; /* Amount of change in the offset of the fields */
+ size_t old_size; /* Preview size of a field */
+
+ /* Sort the fields based on offsets */
+ qsort(dt->u.compnd.memb, dt->u.compnd.nmembs, sizeof(H5T_cmemb_t), H5T_cmp_field_off);
+
for (i=0; i<dt->u.compnd.nmembs; i++) {
+ /* Apply the accumulated size change to the offset of the field */
+ dt->u.compnd.memb[i].offset += accum_change;
+
/* Recurse if it's VL or compound */
if(dt->u.compnd.memb[i].type->type==H5T_COMPOUND || dt->u.compnd.memb[i].type->type==H5T_VLEN) {
+ /* Keep the old field size for later */
+ old_size=dt->u.compnd.memb[i].type->size;
+
+ /* Mark the VL or compound type */
if(H5T_vlen_mark(dt->u.compnd.memb[i].type,f,loc)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
+
+ /* If the field changed size, add that change to the accumulated size change */
+ if(old_size != dt->u.compnd.memb[i].type->size)
+ accum_change += (dt->u.compnd.memb[i].type->size - (int)old_size);
} /* end if */
} /* end for */
+
+ /* Apply the accumulated size change to the datatype */
+ dt->size += accum_change;
+
+ } /* end case */
break;
/* Recurse on the VL information if it's VL or compound, then free VL sequence */