summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-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 */