From d762ea6a31d69a9ebe00e6ed818ab6415091b629 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 16 Jul 1999 13:11:52 -0500 Subject: [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. --- src/H5D.c | 2 +- src/H5Sall.c | 8 ++--- src/H5T.c | 92 +++++++++++++++++++++++++++++++++++++++++-------------- src/H5Tconv.c | 6 +--- src/H5Tpkg.h | 13 ++++---- src/H5Tvlen.c | 98 +++++++++++++++++++++-------------------------------------- 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; iu.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; iu.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; iu.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 */ -- cgit v0.12