diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-11-13 15:19:50 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-11-13 15:19:50 (GMT) |
commit | e1792ebb22c1fee3eb349b83543e6e915bd1e6f7 (patch) | |
tree | 6e3f936d7809ff0191d17454ba0cb6047abda784 /src | |
parent | 71f3513337e800f6500551448559cecc6853aca9 (diff) | |
download | hdf5-e1792ebb22c1fee3eb349b83543e6e915bd1e6f7.zip hdf5-e1792ebb22c1fee3eb349b83543e6e915bd1e6f7.tar.gz hdf5-e1792ebb22c1fee3eb349b83543e6e915bd1e6f7.tar.bz2 |
[svn-r7842] Purpose:
Bug fix
Description:
Variable length strings and sequences with NULL pointers were not handled
by library, causing problems access the data. This also affected fill values
for variable-length datatypes.
Solution:
Address the issues in the library by detecting NULL sequences/strings
and avoid trying to convert them.
Patched up dumper to display NULL sequences/strings.
Platforms tested:
FreeBSD 4.9 (sleipnir)
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dio.c | 35 | ||||
-rw-r--r-- | src/H5HG.c | 8 | ||||
-rw-r--r-- | src/H5Ofill.c | 70 | ||||
-rw-r--r-- | src/H5Tconv.c | 152 | ||||
-rw-r--r-- | src/H5Tpkg.h | 19 | ||||
-rw-r--r-- | src/H5Tvlen.c | 402 |
6 files changed, 458 insertions, 228 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 8188303..c053737 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -237,25 +237,28 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t if (NULL==(tconv_buf = H5FL_BLK_MALLOC(type_elem,buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(type_elem,buf_size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Copy the user's data into the buffer for conversion */ + /* Check for actual fill value to replicate */ if(fill==NULL) - HDmemset(tconv_buf,0,src_type_size); - else + /* If there's no fill value, just use zeros */ + HDmemset(tconv_buf,0,dst_type_size); + else { + /* Copy the user's data into the buffer for conversion */ HDmemcpy(tconv_buf,fill,src_type_size); - /* Convert memory buffer into disk buffer */ - /* Set up type conversion function */ - if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id))) { - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types") - } else if (!H5T_path_noop(tpath)) { - if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 || - (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") - } - - /* Perform data type conversion */ - if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed") + /* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id))) { + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types") + } else if (!H5T_path_noop(tpath)) { + if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") + } + + /* Perform data type conversion */ + if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed") + } /* end if */ /* Fill the selection in the memory buffer */ if(H5S_select_fill(tconv_buf, dst_type_size, space, buf)<0) @@ -715,9 +715,11 @@ H5HG_insert (H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out* assert (idx>0); /* Copy data into the heap */ - HDmemcpy(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f), obj, size); - HDmemset(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f)+size, 0, - need-(H5HG_SIZEOF_OBJHDR(f)+size)); + if(size>0) { + HDmemcpy(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f), obj, size); + HDmemset(heap->obj[idx].begin+H5HG_SIZEOF_OBJHDR(f)+size, 0, + need-(H5HG_SIZEOF_OBJHDR(f)+size)); + } /* end if */ heap->cache_info.dirty = TRUE; /* Return value */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index b2595a0..ec34202 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -877,42 +877,44 @@ H5O_fill_convert(void *_fill, H5T_t *dset_type, hid_t dxpl_id) /* * Can we convert between source and destination data types? */ - if (NULL==(tpath=H5T_path_find(fill->type, dset_type, NULL, NULL, dxpl_id))) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to convert between src and dst data types"); - } - if ((src_id = H5I_register(H5I_DATATYPE, - H5T_copy(fill->type, H5T_COPY_TRANSIENT)))<0 || - (dst_id = H5I_register(H5I_DATATYPE, - H5T_copy(dset_type, H5T_COPY_TRANSIENT)))<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register data type"); - - /* - * Data type conversions are always done in place, so we need a buffer - * that is large enough for both source and destination. - */ - if (H5T_get_size(fill->type)>=H5T_get_size(dset_type)) { - buf = fill->buf; - } else { - if (NULL==(buf=H5MM_malloc(H5T_get_size(dset_type)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - HDmemcpy(buf, fill->buf, H5T_get_size(fill->type)); - } - if (H5T_path_bkg(tpath) && NULL==(bkg=H5MM_malloc(H5T_get_size(dset_type)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + if (NULL==(tpath=H5T_path_find(fill->type, dset_type, NULL, NULL, dxpl_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types") + + /* Don't bother doing anything if there will be no actual conversion */ + if (!H5T_path_noop(tpath)) { + if ((src_id = H5I_register(H5I_DATATYPE, + H5T_copy(fill->type, H5T_COPY_TRANSIENT)))<0 || + (dst_id = H5I_register(H5I_DATATYPE, + H5T_copy(dset_type, H5T_COPY_TRANSIENT)))<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register data type"); + + /* + * Data type conversions are always done in place, so we need a buffer + * that is large enough for both source and destination. + */ + if (H5T_get_size(fill->type)>=H5T_get_size(dset_type)) { + buf = fill->buf; + } else { + if (NULL==(buf=H5MM_malloc(H5T_get_size(dset_type)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + HDmemcpy(buf, fill->buf, H5T_get_size(fill->type)); + } + if (H5T_path_bkg(tpath) && NULL==(bkg=H5MM_malloc(H5T_get_size(dset_type)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - /* Do the conversion */ - if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, buf, bkg, dxpl_id)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); + /* Do the conversion */ + if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, buf, bkg, dxpl_id)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); - /* Update the fill message */ - if (buf!=fill->buf) { - H5MM_xfree(fill->buf); - fill->buf = buf; - } - H5T_close(fill->type); - fill->type = NULL; - H5_ASSIGN_OVERFLOW(fill->size,H5T_get_size(dset_type),size_t,ssize_t); + /* Update the fill message */ + if (buf!=fill->buf) { + H5MM_xfree(fill->buf); + fill->buf = buf; + } + H5T_close(fill->type); + fill->type = NULL; + H5_ASSIGN_OVERFLOW(fill->size,H5T_get_size(dset_type),size_t,ssize_t); + } /* end if */ done: if (src_id>=0) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 897f20b..4950371 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -2384,86 +2384,94 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, s = sp; d = *dptr; - /* Get length of element sequences */ - if((seq_len=(*(src->u.vlen.getlen))(src->u.vlen.f,s))<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length"); - H5_CHECK_OVERFLOW(seq_len,hssize_t,size_t); - src_size=(size_t)seq_len*src_base_size; - dst_size=(size_t)seq_len*dst_base_size; - - /* Check if conversion buffer is large enough, resize if - * necessary */ - if(conv_buf_size<MAX(src_size,dst_size)) { - conv_buf_size=MAX(src_size,dst_size); - if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf, conv_buf_size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - } /* end if */ - - /* Read in VL sequence */ - if((*(src->u.vlen.read))(src->u.vlen.f,dxpl_id,s,conv_buf,src_size)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); - - /* Check if temporary buffer is large enough, resize if necessary */ - /* (Chain off the conversion buffer size) */ - if((tpath->cdata.need_bkg || H5T_detect_class(dst->parent, H5T_VLEN)) - && tmp_buf_size<conv_buf_size) { - /* Set up initial background buffer */ - tmp_buf_size=conv_buf_size; - if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf,tmp_buf_size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + /* Check for "nil" source sequence */ + if((*(src->u.vlen.isnull))(src->u.vlen.f,s)) { + /* Write "nil" sequence to destination location */ + if((*(dst->u.vlen.setnull))(dst->u.vlen.f,dxpl_id,d,bg_ptr)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'"); } /* end if */ + else { + /* Get length of element sequences */ + if((seq_len=(*(src->u.vlen.getlen))(s))<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length"); + H5_CHECK_OVERFLOW(seq_len,hssize_t,size_t); + src_size=(size_t)seq_len*src_base_size; + dst_size=(size_t)seq_len*dst_base_size; + + /* Check if conversion buffer is large enough, resize if + * necessary */ + if(conv_buf_size<MAX(src_size,dst_size)) { + conv_buf_size=MAX(src_size,dst_size); + if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf, conv_buf_size))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + } /* end if */ - /* If we are writing and there is a nested VL type, read - * the sequence into the background buffer */ - if(nested) { - uint8_t *tmp=bg_ptr; - UINT32DECODE(tmp, bg_seq_len); - if(bg_seq_len>0) { - H5_CHECK_OVERFLOW( bg_seq_len*MAX(src_base_size,dst_base_size) ,hsize_t,size_t); - if(tmp_buf_size<(size_t)(bg_seq_len*MAX(src_base_size, dst_base_size))) { - tmp_buf_size=(size_t)(bg_seq_len*MAX(src_base_size, dst_base_size)); - if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf, tmp_buf_size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - } - H5F_addr_decode(dst->u.vlen.f, (const uint8_t **)&tmp, &(bg_hobjid.addr)); - INT32DECODE(tmp, bg_hobjid.idx); - if(H5HG_read(dst->u.vlen.f,dxpl_id,&bg_hobjid,tmp_buf)==NULL) - HGOTO_ERROR (H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer"); - } /* end if */ + /* Read in VL sequence */ + if((*(src->u.vlen.read))(src->u.vlen.f,dxpl_id,s,conv_buf,src_size)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data"); + + /* Check if temporary buffer is large enough, resize if necessary */ + /* (Chain off the conversion buffer size) */ + if((tpath->cdata.need_bkg || H5T_detect_class(dst->parent, H5T_VLEN)) + && tmp_buf_size<conv_buf_size) { + /* Set up initial background buffer */ + tmp_buf_size=conv_buf_size; + if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf,tmp_buf_size))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + } /* end if */ - /* If the sequence gets shorter, pad out the original sequence with zeros */ - H5_CHECK_OVERFLOW(bg_seq_len,hsize_t,hssize_t); - if((hssize_t)bg_seq_len<seq_len) { - H5_CHECK_OVERFLOW((seq_len-bg_seq_len),hsize_t,size_t); - HDmemset((uint8_t *)tmp_buf+dst_base_size*bg_seq_len,0,(size_t)(seq_len-bg_seq_len)*dst_base_size); + /* If we are writing and there is a nested VL type, read + * the sequence into the background buffer */ + if(nested) { + uint8_t *tmp=bg_ptr; + UINT32DECODE(tmp, bg_seq_len); + if(bg_seq_len>0) { + H5_CHECK_OVERFLOW( bg_seq_len*MAX(src_base_size,dst_base_size) ,hsize_t,size_t); + if(tmp_buf_size<(size_t)(bg_seq_len*MAX(src_base_size, dst_base_size))) { + tmp_buf_size=(size_t)(bg_seq_len*MAX(src_base_size, dst_base_size)); + if((tmp_buf=H5FL_BLK_REALLOC(vlen_seq,tmp_buf, tmp_buf_size))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); + } + H5F_addr_decode(dst->u.vlen.f, (const uint8_t **)&tmp, &(bg_hobjid.addr)); + INT32DECODE(tmp, bg_hobjid.idx); + if(H5HG_read(dst->u.vlen.f,dxpl_id,&bg_hobjid,tmp_buf)==NULL) + HGOTO_ERROR (H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer"); + } /* end if */ + + /* If the sequence gets shorter, pad out the original sequence with zeros */ + H5_CHECK_OVERFLOW(bg_seq_len,hsize_t,hssize_t); + if((hssize_t)bg_seq_len<seq_len) { + H5_CHECK_OVERFLOW((seq_len-bg_seq_len),hsize_t,size_t); + HDmemset((uint8_t *)tmp_buf+dst_base_size*bg_seq_len,0,(size_t)(seq_len-bg_seq_len)*dst_base_size); + } /* end if */ } /* end if */ - } /* end if */ - /* Convert VL sequence */ - H5_CHECK_OVERFLOW(seq_len,hssize_t,hsize_t); - if (H5T_convert(tpath, tsrc_id, tdst_id, (hsize_t)seq_len, 0, bkg_stride, conv_buf, tmp_buf, dxpl_id)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed"); + /* Convert VL sequence */ + H5_CHECK_OVERFLOW(seq_len,hssize_t,hsize_t); + if (H5T_convert(tpath, tsrc_id, tdst_id, (hsize_t)seq_len, 0, bkg_stride, conv_buf, tmp_buf, dxpl_id)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed"); + + /* Write sequence to destination location */ + if((*(dst->u.vlen.write))(dst->u.vlen.f,dxpl_id,d,conv_buf, bg_ptr, (hsize_t)seq_len,(hsize_t)dst_base_size)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data"); - /* Write sequence to destination location */ - if((*(dst->u.vlen.write))(dst->u.vlen.f,dxpl_id,d,conv_buf, bg_ptr, (hsize_t)seq_len,(hsize_t)dst_base_size)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data"); - - /* For nested VL case, free leftover heap objects from the deeper level if the length of new data elements is shorted than the old data elements.*/ - H5_CHECK_OVERFLOW(bg_seq_len,hsize_t,hssize_t); - if(nested && seq_len<(hssize_t)bg_seq_len) { - uint8_t *tmp_p=tmp_buf; - tmp_p += seq_len*dst_base_size; - for(i=0; i<(bg_seq_len-seq_len); i++) { - UINT32DECODE(tmp_p, parent_seq_len); - if(parent_seq_len>0) { - H5F_addr_decode(dst->u.vlen.f, (const uint8_t **)&tmp_p, &(parent_hobjid.addr)); - INT32DECODE(tmp_p, parent_hobjid.idx); - if(H5HG_remove(dst->u.vlen.f, dxpl_id,&parent_hobjid)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object"); + /* For nested VL case, free leftover heap objects from the deeper level if the length of new data elements is shorted than the old data elements.*/ + H5_CHECK_OVERFLOW(bg_seq_len,hsize_t,hssize_t); + if(nested && seq_len<(hssize_t)bg_seq_len) { + uint8_t *tmp_p=tmp_buf; + tmp_p += seq_len*dst_base_size; + for(i=0; i<(bg_seq_len-seq_len); i++) { + UINT32DECODE(tmp_p, parent_seq_len); + if(parent_seq_len>0) { + H5F_addr_decode(dst->u.vlen.f, (const uint8_t **)&tmp_p, &(parent_hobjid.addr)); + INT32DECODE(tmp_p, parent_hobjid.idx); + if(H5HG_remove(dst->u.vlen.f, dxpl_id,&parent_hobjid)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object"); + } } } - } - + } /* end else */ + /* * If we had used a temporary buffer for the destination * then we should copy the value to the true destination diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index dba89bc..01465ef 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -142,9 +142,11 @@ typedef struct H5T_enum_t { } H5T_enum_t; /* VL function pointers */ -typedef hssize_t (*H5T_vlen_getlenfunc_t)(H5F_t *f, void *vl_addr); -typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, size_t len); -typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, void *bg_addr, hsize_t seq_len, hsize_t base_size); +typedef hssize_t (*H5T_vlen_getlenfunc_t)(void *vl_addr); +typedef htri_t (*H5T_vlen_isnullfunc_t)(H5F_t *f, void *vl_addr); +typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t len); +typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, void *_bg, hsize_t seq_len, hsize_t base_size); +typedef herr_t (*H5T_vlen_setnullfunc_t)(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg); /* VL types */ typedef enum { @@ -163,8 +165,10 @@ typedef struct H5T_vlen_t { * extra bytes */ 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_isnullfunc_t isnull; /* Function to check if VL value is NIL */ H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */ H5T_vlen_writefunc_t write; /* Function to write VL sequence from buffer */ + H5T_vlen_setnullfunc_t setnull; /* Function to set a VL value to NIL */ } H5T_vlen_t; /* An opaque datatype */ @@ -859,15 +863,6 @@ H5_DLL htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size); /* VL functions */ H5_DLL H5T_t * H5T_vlen_create(const H5T_t *base); -H5_DLL hssize_t H5T_vlen_seq_mem_getlen(H5F_t *f, void *vl_addr); -H5_DLL herr_t H5T_vlen_seq_mem_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, size_t len); -H5_DLL herr_t H5T_vlen_seq_mem_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, void *bg_addr, hsize_t seq_len, hsize_t base_size); -H5_DLL hssize_t H5T_vlen_str_mem_getlen(H5F_t *f, void *vl_addr); -H5_DLL herr_t H5T_vlen_str_mem_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, size_t len); -H5_DLL herr_t H5T_vlen_str_mem_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, void *bg_addr, hsize_t seq_len, hsize_t base_size); -H5_DLL hssize_t H5T_vlen_disk_getlen(H5F_t *f, void *vl_addr); -H5_DLL herr_t H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, size_t len); -H5_DLL herr_t H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, void *bg_addr, hsize_t seq_len, hsize_t base_size); H5_DLL htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); /* Array functions */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 1b113a7..13ff95f 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -43,6 +43,21 @@ H5FL_EXTERN(H5T_t); /* Local functions */ static herr_t H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info); +static hssize_t H5T_vlen_seq_mem_getlen(void *_vl); +static htri_t H5T_vlen_seq_mem_isnull(H5F_t *f, void *_vl); +static herr_t H5T_vlen_seq_mem_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len); +static herr_t H5T_vlen_seq_mem_write(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size); +static herr_t H5T_vlen_seq_mem_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg); +static hssize_t H5T_vlen_str_mem_getlen(void *_vl); +static htri_t H5T_vlen_str_mem_isnull(H5F_t *f, void *_vl); +static herr_t H5T_vlen_str_mem_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len); +static herr_t H5T_vlen_str_mem_write(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size); +static herr_t H5T_vlen_str_mem_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg); +static hssize_t H5T_vlen_disk_getlen(void *_vl); +static htri_t H5T_vlen_disk_isnull(H5F_t *f, void *_vl); +static herr_t H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len); +static herr_t H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size); +static herr_t H5T_vlen_disk_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg); /*-------------------------------------------------------------------------- @@ -214,16 +229,20 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Set up the function pointers to access the VL sequence in memory */ dt->u.vlen.getlen=H5T_vlen_seq_mem_getlen; + dt->u.vlen.isnull=H5T_vlen_seq_mem_isnull; dt->u.vlen.read=H5T_vlen_seq_mem_read; dt->u.vlen.write=H5T_vlen_seq_mem_write; + dt->u.vlen.setnull=H5T_vlen_seq_mem_setnull; } else if(dt->u.vlen.type==H5T_VLEN_STRING) { /* size in memory, disk size is different */ dt->size = sizeof(char *); /* Set up the function pointers to access the VL string in memory */ dt->u.vlen.getlen=H5T_vlen_str_mem_getlen; + dt->u.vlen.isnull=H5T_vlen_str_mem_isnull; dt->u.vlen.read=H5T_vlen_str_mem_read; dt->u.vlen.write=H5T_vlen_str_mem_write; + dt->u.vlen.setnull=H5T_vlen_str_mem_setnull; } else { assert(0 && "Invalid VL type"); } @@ -248,8 +267,10 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Set up the function pointers to access the VL information on disk */ /* VL sequences and VL strings are stored identically on disk, so use the same functions */ dt->u.vlen.getlen=H5T_vlen_disk_getlen; + dt->u.vlen.isnull=H5T_vlen_disk_isnull; dt->u.vlen.read=H5T_vlen_disk_read; dt->u.vlen.write=H5T_vlen_disk_write; + dt->u.vlen.setnull=H5T_vlen_disk_setnull; /* Set file ID (since this VL is on disk) */ dt->u.vlen.f=f; @@ -279,27 +300,50 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ -hssize_t -H5T_vlen_seq_mem_getlen(H5F_t UNUSED *f, void *vl_addr) +static hssize_t +H5T_vlen_seq_mem_getlen(void *_vl) { - hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */ - hssize_t ret_value; /* Return value */ + hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ - FUNC_ENTER_NOAPI(H5T_vlen_seq_mem_getlen, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_seq_mem_getlen) /* check parameters */ assert(vl); - /* Set return value */ - ret_value=(hssize_t)vl->len; - -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI((hssize_t)vl->len) } /* end H5T_vlen_seq_mem_getlen() */ /*------------------------------------------------------------------------- + * Function: H5T_vlen_seq_mem_isnull + * + * Purpose: Checks if a memory sequence is the "null" sequence + * + * Return: TRUE/FALSE on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static htri_t +H5T_vlen_seq_mem_isnull(H5F_t UNUSED *f, void *_vl) +{ + hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + + FUNC_ENTER_NOINIT(H5T_vlen_seq_mem_isnull) + + /* check parameters */ + assert(vl); + + FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE) +} /* end H5T_vlen_seq_mem_isnull() */ + + +/*------------------------------------------------------------------------- * Function: H5T_vlen_seq_mem_read * * Purpose: "Reads" the memory based VL sequence into a buffer @@ -314,13 +358,12 @@ done: *------------------------------------------------------------------------- */ /* ARGSUSED */ -herr_t -H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *vl_addr, void *buf, size_t len) +static herr_t +H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { - hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */ - herr_t ret_value=SUCCEED; /* Return value */ + hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */ - FUNC_ENTER_NOAPI(H5T_vlen_seq_mem_read, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_seq_mem_read) /* check parameters */ assert(vl && vl->p); @@ -328,8 +371,7 @@ H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *vl_addr, void HDmemcpy(buf,vl->p,len); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5T_vlen_seq_mem_read() */ @@ -348,8 +390,8 @@ done: *------------------------------------------------------------------------- */ /* ARGSUSED */ -herr_t -H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, void UNUSED *bg_addr, hsize_t seq_len, hsize_t base_size) +static herr_t +H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, void UNUSED *_bg, hsize_t seq_len, hsize_t base_size) { H5MM_allocate_t alloc_func; /* Vlen allocation function */ void *alloc_info; /* Vlen allocation information */ @@ -358,10 +400,10 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, H5P_genplist_t *plist; /* Property list */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_vlen_seq_mem_write, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_seq_mem_write) /* check parameters */ - assert(vl_addr); + assert(_vl); assert(buf); if(seq_len!=0) { @@ -397,7 +439,7 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, H5_ASSIGN_OVERFLOW(vl.len,seq_len,hsize_t,size_t); /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(vl_addr,&vl,sizeof(hvl_t)); + HDmemcpy(_vl,&vl,sizeof(hvl_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -405,6 +447,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_vlen_seq_mem_setnull + * + * Purpose: Sets a VL info object in memory to the "nil" value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5T_vlen_seq_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void UNUSED *_bg) +{ + hvl_t vl; /* Temporary hvl_t to use during operation */ + + FUNC_ENTER_NOINIT(H5T_vlen_seq_mem_setnull) + + /* check parameters */ + assert(_vl); + + /* Set the "nil" hvl_t */ + vl.len=0; + vl.p=NULL; + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + HDmemcpy(_vl,&vl,sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T_vlen_seq_mem_setnull() */ + + +/*------------------------------------------------------------------------- * Function: H5T_vlen_str_mem_getlen * * Purpose: Retrieves the length of a memory based VL string. @@ -418,27 +496,47 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ -hssize_t -H5T_vlen_str_mem_getlen(H5F_t UNUSED *f, void *vl_addr) +static hssize_t +H5T_vlen_str_mem_getlen(void *_vl) { - char *s=*(char **)vl_addr; /* Pointer to the user's hvl_t information */ - hssize_t ret_value; /* Return value */ + char *s=*(char **)_vl; /* Pointer to the user's string information */ - FUNC_ENTER_NOAPI(H5T_vlen_str_mem_getlen, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_str_mem_getlen) - /* Set return value */ - if(s) - ret_value=(hssize_t)HDstrlen(s); - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "null pointer") + /* check parameters */ + assert(s); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI((hssize_t)HDstrlen(s)) } /* end H5T_vlen_str_mem_getlen() */ /*------------------------------------------------------------------------- + * Function: H5T_vlen_str_mem_isnull + * + * Purpose: Checks if a memory string is a NULL pointer + * + * Return: TRUE/FALSE on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static htri_t +H5T_vlen_str_mem_isnull(H5F_t UNUSED *f, void *_vl) +{ + char *s=*(char **)_vl; /* Pointer to the user's string information */ + + FUNC_ENTER_NOINIT(H5T_vlen_str_mem_isnull) + + FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE); +} /* end H5T_vlen_str_mem_isnull() */ + + +/*------------------------------------------------------------------------- * Function: H5T_vlen_str_mem_read * * Purpose: "Reads" the memory based VL string into a buffer @@ -453,13 +551,12 @@ done: *------------------------------------------------------------------------- */ /* ARGSUSED */ -herr_t -H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *vl_addr, void *buf, size_t len) +static herr_t +H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { - char *s=*(char **)vl_addr; /* Pointer to the user's hvl_t information */ - herr_t ret_value=SUCCEED; /* Return value */ + char *s=*(char **)_vl; /* Pointer to the user's hvl_t information */ - FUNC_ENTER_NOAPI(H5T_vlen_str_mem_read, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_str_mem_read) /* check parameters */ assert(s); @@ -468,8 +565,7 @@ H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *vl_addr, void if(len>0) HDmemcpy(buf,s,len); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5T_vlen_str_mem_read() */ @@ -488,8 +584,8 @@ done: *------------------------------------------------------------------------- */ /* ARGSUSED */ -herr_t -H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, void UNUSED *bg_addr, hsize_t seq_len, hsize_t base_size) +static herr_t +H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, void UNUSED *_bg, hsize_t seq_len, hsize_t base_size) { H5MM_allocate_t alloc_func; /* Vlen allocation function */ void *alloc_info; /* Vlen allocation information */ @@ -498,7 +594,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, H5P_genplist_t *plist; /* Property list */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_vlen_str_mem_write, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_str_mem_write) /* check parameters */ assert(buf); @@ -528,7 +624,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *vl_addr, void *buf, t[len]='\0'; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(vl_addr,&t,sizeof(char *)); + HDmemcpy(_vl,&t,sizeof(char *)); done: FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ @@ -536,6 +632,35 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_vlen_str_mem_setnull + * + * Purpose: Sets a VL info object in memory to the "null" value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5T_vlen_str_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void UNUSED *_bg) +{ + char *t=NULL; /* Pointer to temporary buffer allocated */ + + FUNC_ENTER_NOINIT(H5T_vlen_str_mem_write) + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + HDmemcpy(_vl,&t,sizeof(char *)); + + FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ +} /* end H5T_vlen_str_mem_setnull() */ + + +/*------------------------------------------------------------------------- * Function: H5T_vlen_disk_getlen * * Purpose: Retrieves the length of a disk based VL element. @@ -549,26 +674,59 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ -hssize_t -H5T_vlen_disk_getlen(H5F_t UNUSED *f, void *vl_addr) +static hssize_t +H5T_vlen_disk_getlen(void *_vl) { - uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the disk VL information */ - hssize_t ret_value; /*return value */ + uint8_t *vl=(uint8_t *)_vl; /* Pointer to the disk VL information */ + hssize_t seq_len; /* Sequence length */ - FUNC_ENTER_NOAPI(H5T_vlen_disk_getlen, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_disk_getlen) /* check parameters */ assert(vl); - UINT32DECODE(vl, ret_value); + UINT32DECODE(vl, seq_len); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(seq_len) } /* end H5T_vlen_disk_getlen() */ /*------------------------------------------------------------------------- + * Function: H5T_vlen_disk_isnull + * + * Purpose: Checks if a disk VL info object is the "nil" object + * + * Return: TRUE/FALSE on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static htri_t +H5T_vlen_disk_isnull(H5F_t *f, void *_vl) +{ + uint8_t *vl=(uint8_t *)_vl; /* Pointer to the disk VL information */ + haddr_t addr; /* Sequence's heap address */ + + FUNC_ENTER_NOINIT(H5T_vlen_disk_isnull) + + /* check parameters */ + assert(vl); + + /* Skip the sequence's length */ + vl+=4; + + /* Get the heap address */ + H5F_addr_decode(f,(const uint8_t **)&vl,&addr); + + FUNC_LEAVE_NOAPI(addr==0 ? TRUE : FALSE) +} /* end H5T_vlen_disk_isnull() */ + + +/*------------------------------------------------------------------------- * Function: H5T_vlen_disk_read * * Purpose: Reads the disk based VL element into a buffer @@ -583,15 +741,15 @@ done: *------------------------------------------------------------------------- */ /* ARGSUSED */ -herr_t -H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, size_t UNUSED len) +static herr_t +H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t UNUSED len) { - uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the user's hvl_t information */ + uint8_t *vl=(uint8_t *)_vl; /* Pointer to the user's hvl_t information */ H5HG_t hobjid; uint32_t seq_len; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_vlen_disk_read, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_disk_read) /* check parameters */ assert(vl); @@ -601,14 +759,14 @@ H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, size_t UNU /* Get the length of the sequence */ UINT32DECODE(vl, seq_len); /* Not used */ - /* Check if this sequence actually has any data */ - if(seq_len!=0) { - /* Get the heap information */ - H5F_addr_decode(f,(const uint8_t **)&vl,&(hobjid.addr)); - INT32DECODE(vl,hobjid.idx); + /* Get the heap information */ + H5F_addr_decode(f,(const uint8_t **)&vl,&(hobjid.addr)); + INT32DECODE(vl,hobjid.idx); + /* Check if this sequence actually has any data */ + if(hobjid.addr>0) { /* Read the VL information from disk */ - if(H5HG_read(f,dxpl_id, &hobjid,buf)==NULL) + if(H5HG_read(f,dxpl_id,&hobjid,buf)==NULL) HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read VL information") } /* end if */ @@ -635,35 +793,37 @@ done: * *------------------------------------------------------------------------- */ -herr_t -H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, void *bg_addr, hsize_t seq_len, hsize_t base_size) +static herr_t +H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, void *_bg, hsize_t seq_len, hsize_t base_size) { - uint8_t *vl=(uint8_t *)vl_addr; /*Pointer to the user's hvl_t information*/ - uint8_t *bg=(uint8_t *)bg_addr; /*Pointer to the old data hvl_t */ - H5HG_t hobjid; - H5HG_t bg_hobjid; - size_t len; - hsize_t bg_seq_len=0; + uint8_t *vl=(uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ + uint8_t *bg=(uint8_t *)_bg; /*Pointer to the old data hvl_t */ + H5HG_t hobjid; /* New VL sequence's heap ID */ + size_t len; /* Size of new sequence on disk (in bytes) */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5T_vlen_disk_write, FAIL) + FUNC_ENTER_NOINIT(H5T_vlen_disk_write) /* check parameters */ assert(vl); assert(buf); assert(f); - /* Get the length of the sequence and heap object ID from background data. - * Free heap object for old data. */ + /* Free heap object for old data. */ if(bg!=NULL) { + hsize_t bg_seq_len=0; /* "Background" VL info sequence's length */ + H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ + + /* Get the length of the sequence and heap object ID from background data. */ HDmemset(&bg_hobjid,0,sizeof(H5HG_t)); UINT32DECODE(bg, bg_seq_len); + /* Get heap information */ + H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); + INT32DECODE(bg, bg_hobjid.idx); + /* Free heap object for old data */ - if(bg_seq_len>0) { - /* Get heap information */ - H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); - INT32DECODE(bg, bg_hobjid.idx); + if(bg_hobjid.addr>0) { /* Free heap object */ if(H5HG_remove(f, dxpl_id, &bg_hobjid)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") @@ -674,17 +834,12 @@ H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, void *bg_ H5_CHECK_OVERFLOW(seq_len,hsize_t,size_t); UINT32ENCODE(vl, seq_len); - /* Check if this sequence actually has any data */ - if(seq_len!=0) { - /* Write the VL information to disk (allocates space also) */ - H5_ASSIGN_OVERFLOW(len,(seq_len*base_size),hsize_t,size_t); - if(H5HG_insert(f,dxpl_id, len,buf,&hobjid)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write VL information") - } /* end if */ - else - HDmemset(&hobjid,0,sizeof(H5HG_t)); + /* Write the VL information to disk (allocates space also) */ + H5_ASSIGN_OVERFLOW(len,(seq_len*base_size),hsize_t,size_t); + if(H5HG_insert(f,dxpl_id,len,buf,&hobjid)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write VL information") - /* Get the heap information */ + /* Encode the heap information */ H5F_addr_encode(f,&vl,hobjid.addr); INT32ENCODE(vl,hobjid.idx); @@ -693,6 +848,71 @@ done: } /* end H5T_vlen_disk_write() */ +/*------------------------------------------------------------------------- + * Function: H5T_vlen_disk_setnull + * + * Purpose: Sets a VL info object on disk to the "nil" value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T_vlen_disk_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg) +{ + uint8_t *vl=(uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ + uint8_t *bg=(uint8_t *)_bg; /*Pointer to the old data hvl_t */ + uint32_t seq_len=0; /* Sequence length */ + H5HG_t hobjid; /* New VL sequence's heap ID */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOINIT(H5T_vlen_disk_setnull) + + /* check parameters */ + assert(f); + assert(vl); + + /* Free heap object for old data. */ + if(bg!=NULL) { + hsize_t bg_seq_len=0; /* "Background" VL info sequence's length */ + H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ + + /* Get the length of the sequence and heap object ID from background data. */ + HDmemset(&bg_hobjid,0,sizeof(H5HG_t)); + UINT32DECODE(bg, bg_seq_len); + + /* Get heap information */ + H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); + INT32DECODE(bg, bg_hobjid.idx); + + /* Free heap object for old data */ + if(bg_hobjid.addr>0) { + /* Free heap object */ + if(H5HG_remove(f, dxpl_id, &bg_hobjid)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") + } /* end if */ + } /* end if */ + + /* Set the length of the sequence */ + UINT32ENCODE(vl, seq_len); + + /* Set the "nil" pointer information for the heap ID */ + HDmemset(&hobjid,0,sizeof(H5HG_t)); + + /* Encode the heap information */ + H5F_addr_encode(f,&vl,hobjid.addr); + INT32ENCODE(vl,hobjid.idx); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_vlen_disk_setnull() */ + + /*-------------------------------------------------------------------------- NAME H5T_vlen_reclaim_recurse |