diff options
-rw-r--r-- | src/H5D.c | 7 | ||||
-rw-r--r-- | src/H5Tconv.c | 317 | ||||
-rw-r--r-- | src/H5Tpkg.h | 67 | ||||
-rw-r--r-- | src/H5Tprivate.h | 15 | ||||
-rw-r--r-- | src/H5Tvlen.c | 214 |
5 files changed, 324 insertions, 296 deletions
@@ -3380,6 +3380,7 @@ done: herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) { + H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ herr_t ret_value; FUNC_ENTER_API(H5Dvlen_reclaim, FAIL) @@ -3398,8 +3399,12 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + /* Get the allocation info */ + if(H5T_vlen_get_alloc_info(plist_id,&vl_alloc_info)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); + /* Call H5Diterate with args, etc. */ - ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,&plist_id); + ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,&vl_alloc_info); done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 15f0701..f1b75b6 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -2219,19 +2219,21 @@ done: */ herr_t H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, - size_t buf_stride, size_t bkg_stride, void *_buf, - void *_bkg, hid_t dxpl_id) + size_t buf_stride, size_t bkg_stride, void *buf, + void *bkg, hid_t dxpl_id) { + H5T_vlen_alloc_info_t vl_alloc_info;/* VL allocation information */ H5T_path_t *tpath; /* Type conversion path */ hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */ H5T_t *src = NULL; /*source data type */ H5T_t *dst = NULL; /*destination data type */ - hsize_t olap; /*num overlapping elements */ - uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs */ - uint8_t **dptr; /*pointer to correct destination pointer*/ - uint8_t *bg_ptr=NULL; /*background buf traversal pointer */ H5HG_t bg_hobjid, parent_hobjid; - size_t src_delta, dst_delta, bkg_delta;/*source & destination stride*/ + uint8_t *s; /*source buffer */ + uint8_t *d; /*destination buffer */ + uint8_t *b; /*background buffer */ + ssize_t s_stride, d_stride; /*src and dst strides */ + ssize_t b_stride; /*bkg stride */ + size_t safe; /*how many elements are safe to process in each pass */ hssize_t seq_len; /*the number of elements in the current sequence*/ hsize_t bg_seq_len=0, parent_seq_len=0; size_t src_base_size, dst_base_size;/*source & destination base size*/ @@ -2240,8 +2242,6 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, size_t conv_buf_size=0; /*size of conversion buffer in bytes */ void *tmp_buf=NULL; /*temporary background buffer */ size_t tmp_buf_size=0; /*size of temporary bkg buffer */ - void *dbuf=NULL; /*temp destination buffer */ - int direction; /*direction of traversal */ int nested=0; /*flag of nested VL case */ hsize_t elmtno; /*element number counter */ hsize_t i; @@ -2281,67 +2281,28 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, NULL == (dst = H5I_object(dst_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - /* - * Do we process the values from beginning to end or vice - * versa? Also, how many of the elements have the source and - * destination areas overlapping? - */ - if (src->size==dst->size || buf_stride>0) { - olap = nelmts; - sp = dp = (uint8_t*)_buf; - bg_ptr = (uint8_t*)_bkg; - direction = 1; - } else if (src->size>=dst->size) { - /* potentially this uses the destination buffer 1 extra - * time, but its faster that floating-point calcs */ - olap = ((dst->size)/(src->size-dst->size))+1; - sp = dp = (uint8_t*)_buf; - bg_ptr = (uint8_t*)_bkg; - direction = 1; - } else { - /* potentially this uses the destination buffer 1 extra - * time, but its faster that floating-point calcs */ - olap = nelmts-(((src->size)/(dst->size-src->size))+1); - sp = (uint8_t*)_buf + (nelmts-1) * - (buf_stride ? buf_stride : src->size); - dp = (uint8_t*)_buf + (nelmts-1) * - (buf_stride ? buf_stride : dst->size); - if(_bkg!=NULL) - bg_ptr = (uint8_t*)_bkg + (nelmts-1) * - (bkg_stride ? bkg_stride : dst->size); - direction = -1; - } - - /* - * Direction & size of buffer traversal. - */ - src_delta = direction * (buf_stride ? buf_stride : src->size); - dst_delta = direction * (buf_stride ? buf_stride : dst->size); - bkg_delta = direction * (bkg_stride ? bkg_stride : dst->size); - - /* Dynamically allocate the destination buffer */ - if ((dbuf=H5FL_BLK_MALLOC(vlen_seq,dst->size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - - /* - * If the source and destination buffers overlap then use a - * temporary buffer for the destination. - */ - if (direction>0) { - dptr = (uint8_t **)&dbuf; + /* Initialize source & destination strides */ + if (buf_stride) { + assert(buf_stride>=src->size); + assert(buf_stride>=dst->size); + s_stride = d_stride = buf_stride; } else { - dptr = &dp; + s_stride = src->size; + d_stride = dst->size; } + if(bkg) { + if(bkg_stride) + b_stride=bkg_stride; + else + b_stride=d_stride; + } /* end if */ + else + b_stride=0; /* Get the size of the base types in src & dst */ src_base_size=H5T_get_size(src->parent); dst_base_size=H5T_get_size(dst->parent); - /* Get initial conversion buffer */ - conv_buf_size=MAX(src_base_size,dst_base_size); - if ((conv_buf=H5FL_BLK_CALLOC(vlen_seq,conv_buf_size))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); - /* Set up conversion path for base elements */ if (NULL==(tpath=H5T_path_find(src->parent, dst->parent, NULL, NULL, dxpl_id))) { HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatypes"); @@ -2359,122 +2320,147 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); } /* end if */ + /* Get the allocation info */ + if(H5T_vlen_get_alloc_info(dxpl_id,&vl_alloc_info)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info"); + /* Set the flag for nested VL case */ - if(dst->u.vlen.f!=NULL && H5T_detect_class(dst->parent,H5T_VLEN) && bg_ptr!=NULL) + if(dst->u.vlen.f!=NULL && H5T_detect_class(dst->parent,H5T_VLEN) && bkg!=NULL) nested=1; - for (elmtno=0; elmtno<nelmts; elmtno++) { - s = sp; - d = *dptr; - - /* 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'"); + /* The outer loop of the type conversion macro, controlling which */ + /* direction the buffer is walked */ + while (nelmts>0) { + /* Check if we need to go backwards through the buffer */ + if(d_stride>s_stride) { + /* Compute the number of "safe" destination elements at */ + /* the end of the buffer (Those which don't overlap with */ + /* any source elements at the beginning of the buffer) */ + safe=nelmts-(((nelmts*s_stride)+(d_stride-1))/d_stride); + + /* If we're down to the last few elements, just wrap up */ + /* with a "real" reverse copy */ + if(safe<2) { + s = (uint8_t*)buf+(nelmts-1)*s_stride; + d = (uint8_t*)buf+(nelmts-1)*d_stride; + b = (uint8_t*)bkg+(nelmts-1)*b_stride; + s_stride = -s_stride; + d_stride = -d_stride; + b_stride = -b_stride; + + safe=nelmts; + } /* end if */ + else { + s = (uint8_t*)buf+(nelmts-safe)*s_stride; + d = (uint8_t*)buf+(nelmts-safe)*d_stride; + b = (uint8_t*)bkg+(nelmts-safe)*b_stride; + } /* end else */ } /* 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 */ + /* Single forward pass over all data */ + s = d = buf; + b = bkg; + safe=nelmts; + } /* end else */ - /* 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"); + for (elmtno=0; elmtno<safe; elmtno++) { + /* 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,b)<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"); + /* 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(tmp_buf && 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=b; + 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, 0, 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"); - - /* 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"); + /* 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, 0, 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,&vl_alloc_info,d,conv_buf, b, (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 shorter 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 */ - + } /* end else */ - /* - * If we had used a temporary buffer for the destination - * then we should copy the value to the true destination - * buffer. - */ - if (d==dbuf) HDmemcpy (dp, d, dst->size); - sp += src_delta; - dp += dst_delta; - if(bg_ptr!=NULL) - bg_ptr += bkg_delta; - - /* switch destination pointer around when the olap gets to 0 */ - if(--olap==0) { - if(dptr==(uint8_t **)&dbuf) - dptr=&dp; - else - dptr=(uint8_t **)&dbuf; - } /* end if */ - } + /* Advance pointers */ + s += s_stride; + d += d_stride; + b += b_stride; + } /* end for */ + + /* Decrement number of elements left to convert */ + nelmts-=safe; + } /* end while */ /* Release the temporary datatype IDs used */ if (tsrc_id >= 0) @@ -2494,9 +2480,6 @@ done: /* Release the background buffer, if we have one */ if(tmp_buf!=NULL) H5FL_BLK_FREE(vlen_seq,tmp_buf); - /* Release the destination buffer, if we have one */ - if(dbuf!=NULL) - H5FL_BLK_FREE(vlen_seq,dbuf); FUNC_LEAVE_NOAPI(ret_value); } diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 7d891e7..2a72f93 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -37,6 +37,7 @@ /* Get package's private header */ #include "H5Tprivate.h" +/* Other private headers needed by this file */ #include "H5Dprivate.h" /* Datasets */ #include "H5Fprivate.h" /* Files */ #include "H5HGprivate.h" /* Global heaps */ @@ -60,11 +61,11 @@ struct H5T_stats_t { H5_timer_t timer; /*total time for conversion */ }; -/* The data type conversion database */ +/* The datatype conversion database */ struct H5T_path_t { char name[H5T_NAMELEN]; /*name for debugging only */ - H5T_t *src; /*source data type ID */ - H5T_t *dst; /*destination data type ID */ + H5T_t *src; /*source datatype ID */ + H5T_t *dst; /*destination datatype ID */ H5T_conv_t func; /*data conversion function */ hbool_t is_hard; /*is it a hard function? */ hbool_t is_noop; /*is it the noop conversion? */ @@ -72,14 +73,6 @@ struct H5T_path_t { H5T_cdata_t cdata; /*data for this function */ }; -/* VL types */ -typedef enum { - H5T_VLEN_BADTYPE = -1, /* invalid VL Type */ - H5T_VLEN_SEQUENCE=0, /* VL sequence */ - H5T_VLEN_STRING, /* VL string */ - H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */ -} H5T_vlen_type_t; - typedef struct H5T_atomic_t { H5T_order_t order; /*byte order */ size_t prec; /*precision in bits */ @@ -113,14 +106,14 @@ typedef struct H5T_atomic_t { } u; } H5T_atomic_t; -/* How members are sorted for compound or enum data types */ +/* How members are sorted for compound or enum datatypes */ typedef enum H5T_sort_t { H5T_SORT_NONE = 0, /*not sorted */ H5T_SORT_NAME = 1, /*sorted by member name */ H5T_SORT_VALUE = 2 /*sorted by memb offset or enum value*/ } H5T_sort_t; -/* A compound data type */ +/* A compound datatype */ typedef struct H5T_compnd_t { int nalloc; /*num entries allocated in MEMB array*/ int nmembs; /*number of members defined in struct*/ @@ -129,22 +122,30 @@ typedef struct H5T_compnd_t { struct H5T_cmemb_t *memb; /*array of struct members */ } H5T_compnd_t; -/* An enumeration data type */ +/* An enumeration datatype */ typedef struct H5T_enum_t { int nalloc; /*num entries allocated */ int nmembs; /*number of members defined in enum */ - H5T_sort_t sorted; /*how are members sorted? */ - uint8_t *value; /*array of values */ - char **name; /*array of symbol names */ + H5T_sort_t sorted; /*how are members sorted? */ + uint8_t *value; /*array of values */ + char **name; /*array of symbol names */ } H5T_enum_t; /* VL function pointers */ 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_writefunc_t)(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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 { + H5T_VLEN_BADTYPE = -1, /* invalid VL Type */ + H5T_VLEN_SEQUENCE=0, /* VL sequence */ + H5T_VLEN_STRING, /* VL string */ + H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */ +} H5T_vlen_type_t; + /* A VL datatype */ typedef struct H5T_vlen_t { H5T_vlen_type_t type; /* Type of VL data in buffer */ @@ -160,16 +161,16 @@ typedef struct H5T_vlen_t { H5T_vlen_setnullfunc_t setnull; /* Function to set a VL value to NIL */ } H5T_vlen_t; -/* An opaque data type */ +/* An opaque datatype */ typedef struct H5T_opaque_t { char *tag; /*short type description string */ } H5T_opaque_t; /* An array datatype */ typedef struct H5T_array_t { - size_t nelem; /* total number of elements in array */ + size_t nelem; /* total number of elements in array */ int ndims; /* member dimensionality */ - size_t dim[H5S_MAX_RANK]; /* size in each dimension */ + size_t dim[H5S_MAX_RANK]; /* size in each dimension */ int perm[H5S_MAX_RANK]; /* index permutation */ } H5T_array_t; @@ -187,19 +188,19 @@ struct H5T_t { H5F_t *sh_file;/*file pointer if this is a shared type */ H5T_class_t type; /*which class of type is this? */ size_t size; /*total size of an instance of this type */ - hbool_t force_conv; /* Set if this type always needs to be converted and H5T_conv_noop cannot be called */ - struct H5T_t *parent;/*parent type for derived data types */ + hbool_t force_conv;/* Set if this type always needs to be converted and H5T_conv_noop cannot be called */ + struct H5T_t *parent;/*parent type for derived datatypes */ union { - H5T_atomic_t atomic; /* an atomic data type */ - H5T_compnd_t compnd; /* a compound data type (struct) */ - H5T_enum_t enumer; /* an enumeration type (enum) */ - H5T_vlen_t vlen; /* a variable-length datatype */ - H5T_opaque_t opaque; /* an opaque data type */ - H5T_array_t array; /* an array datatype */ + H5T_atomic_t atomic; /* an atomic datatype */ + H5T_compnd_t compnd; /* a compound datatype (struct) */ + H5T_enum_t enumer; /* an enumeration type (enum) */ + H5T_vlen_t vlen; /* a variable-length datatype */ + H5T_opaque_t opaque; /* an opaque datatype */ + H5T_array_t array; /* an array datatype */ } u; }; -/* A compound data type member */ +/* A compound datatype member */ typedef struct H5T_cmemb_t { char *name; /*name of this member */ size_t offset; /*offset from beginning of struct */ @@ -210,8 +211,8 @@ typedef struct H5T_cmemb_t { /* The master list of soft conversion functions */ typedef struct H5T_soft_t { char name[H5T_NAMELEN]; /*name for debugging only */ - H5T_class_t src; /*source data type class */ - H5T_class_t dst; /*destination data type class */ + H5T_class_t src; /*source datatype class */ + H5T_class_t dst; /*destination datatype class */ H5T_conv_t func; /*the conversion function */ } H5T_soft_t; @@ -860,7 +861,7 @@ H5_DLL ssize_t H5T_bit_find(uint8_t *buf, size_t offset, size_t size, 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(H5T_t *base); +H5_DLL H5T_t * H5T_vlen_create(const H5T_t *base); /* Array functions */ H5_DLL H5T_t * H5T_array_create(H5T_t *base, int ndims, diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 9d40e85..b28c01f 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -18,8 +18,12 @@ #ifndef _H5Tprivate_H #define _H5Tprivate_H +/* Get package's public header */ #include "H5Tpublic.h" +/* Other public headers needed by this file */ +#include "H5MMpublic.h" /* Memory management */ + /* Private headers needed by this file */ #include "H5private.h" /* Generic Functions */ #include "H5Gprivate.h" /* Groups */ @@ -30,7 +34,7 @@ typedef struct H5T_t H5T_t; typedef struct H5T_stats_t H5T_stats_t; typedef struct H5T_path_t H5T_path_t; -/* How to copy a data type */ +/* How to copy a datatype */ typedef enum H5T_copy_t { H5T_COPY_TRANSIENT, H5T_COPY_ALL, @@ -45,6 +49,14 @@ typedef enum { H5T_VLEN_MAXLOC /* highest type (Invalid as true type) */ } H5T_vlen_loc_t; +/* VL allocation information */ +typedef struct { + H5MM_allocate_t alloc_func; /* Allocation function */ + void *alloc_info; /* Allocation information */ + H5MM_free_t free_func; /* Free function */ + void *free_info; /* Free information */ +} H5T_vlen_alloc_info_t; + /* Private functions */ H5_DLL herr_t H5TN_init_interface(void); H5_DLL herr_t H5T_init(void); @@ -69,6 +81,7 @@ H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, hsize_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg, hid_t dset_xfer_plist); H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data); +H5_DLL herr_t H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t *vl_alloc_info); H5_DLL htri_t H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); H5_DLL htri_t H5T_committed(H5T_t *type); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index d78f4d3..3d91a57 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -19,6 +19,10 @@ #define H5T_PACKAGE /*suppress error about including H5Tpkg */ +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5Tvlen_mask + #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Errors */ #include "H5FLprivate.h" /* Free Lists */ @@ -28,8 +32,6 @@ #include "H5Pprivate.h" /* Property Lists */ #include "H5Tpkg.h" /* Datatypes */ -#define PABLO_MASK H5Tvlen_mask - /* Interface initialization */ static int interface_initialize_g = 0; #define INTERFACE_INIT H5T_init_vlen_interface @@ -40,21 +42,21 @@ H5FL_EXTERN(H5T_t); /* Local functions */ static htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc); -static herr_t H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *free_info); +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_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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); @@ -74,19 +76,19 @@ DESCRIPTION static herr_t H5T_init_vlen_interface(void) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_vlen_interface); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_init_vlen_interface) - FUNC_LEAVE_NOAPI(H5T_init()); + FUNC_LEAVE_NOAPI(H5T_init()) } /* H5T_init_vlen_interface() */ /*------------------------------------------------------------------------- * Function: H5Tvlen_create * - * Purpose: Create a new variable-length data type based on the specified + * Purpose: Create a new variable-length datatype based on the specified * BASE_TYPE. * - * Return: Success: ID of new VL data type + * Return: Success: ID of new VL datatype * * Failure: Negative * @@ -100,37 +102,37 @@ H5T_init_vlen_interface(void) hid_t H5Tvlen_create(hid_t base_id) { - H5T_t *base = NULL; /*base data type */ - H5T_t *dt = NULL; /*new data type */ + H5T_t *base = NULL; /*base datatype */ + H5T_t *dt = NULL; /*new datatype */ hid_t ret_value; /*return value */ - FUNC_ENTER_API(H5Tvlen_create, FAIL); + FUNC_ENTER_API(H5Tvlen_create, FAIL) H5TRACE1("i","i",base_id); /* Check args */ if (NULL==(base=H5I_object_verify(base_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype") /* Create up VL datatype */ if ((dt=H5T_vlen_create(base))==NULL) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location") /* Atomize the type */ if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype") done: - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } /*------------------------------------------------------------------------- * Function: H5T_vlen_create * - * Purpose: Create a new variable-length data type based on the specified + * Purpose: Create a new variable-length datatype based on the specified * BASE_TYPE. * - * Return: Success: new VL data type + * Return: Success: new VL datatype * * Failure: NULL * @@ -142,19 +144,19 @@ done: *------------------------------------------------------------------------- */ H5T_t * -H5T_vlen_create(H5T_t *base) +H5T_vlen_create(const H5T_t *base) { - H5T_t *dt = NULL; /*new VL data type */ + H5T_t *dt = NULL; /*new VL datatype */ H5T_t *ret_value; /*return value */ - FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_create); + FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_create) /* Check args */ assert(base); /* Build new type */ if (NULL==(dt = H5FL_CALLOC(H5T_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") dt->ent.header = HADDR_UNDEF; dt->type = H5T_VLEN; @@ -170,13 +172,13 @@ H5T_vlen_create(H5T_t *base) /* Set up VL information */ if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location") /* Set return value */ ret_value=dt; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -203,7 +205,7 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) { htri_t ret_value = 0; /* Indicate that success, but no location change */ - FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_set_loc); + FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_set_loc) /* check parameters */ assert(dt); @@ -275,12 +277,12 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc) break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location"); + HGOTO_ERROR (H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location") } /* end switch */ } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_set_loc() */ @@ -326,6 +328,7 @@ H5T_vlen_seq_mem_getlen(void *_vl) * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static htri_t H5T_vlen_seq_mem_isnull(H5F_t UNUSED *f, void *_vl) { @@ -354,6 +357,7 @@ H5T_vlen_seq_mem_isnull(H5F_t UNUSED *f, void *_vl) * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static herr_t H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { @@ -385,14 +389,12 @@ H5T_vlen_seq_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *bu * *------------------------------------------------------------------------- */ +/* ARGSUSED */ 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) +H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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 */ hvl_t vl; /* Temporary hvl_t to use during operation */ size_t len; - H5P_genplist_t *plist; /* Property list */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_seq_mem_write) @@ -405,22 +407,13 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, voi H5_ASSIGN_OVERFLOW(len,(seq_len*base_size),hsize_t,size_t); /* Use the user's memory allocation routine is one is defined */ - - /* Get the allocation function & info */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); - if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_NAME,&alloc_func)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); - if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_INFO_NAME,&alloc_info)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); - - if(alloc_func!=NULL) { - if(NULL==(vl.p=(alloc_func)(len,alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data"); + if(vl_alloc_info->alloc_func!=NULL) { + if(NULL==(vl.p=(vl_alloc_info->alloc_func)(len,vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end if */ else { /* Default to system malloc */ if(NULL==(vl.p=H5MM_malloc(len))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end else */ /* Copy the data into the newly allocated buffer */ @@ -437,7 +430,7 @@ H5T_vlen_seq_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, voi HDmemcpy(_vl,&vl,sizeof(hvl_t)); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_seq_mem_write() */ @@ -519,6 +512,7 @@ H5T_vlen_str_mem_getlen(void *_vl) * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static htri_t H5T_vlen_str_mem_isnull(H5F_t UNUSED *f, void *_vl) { @@ -544,6 +538,7 @@ H5T_vlen_str_mem_isnull(H5F_t UNUSED *f, void *_vl) * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static herr_t H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *buf, size_t len) { @@ -577,14 +572,12 @@ H5T_vlen_str_mem_read(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void *bu * *------------------------------------------------------------------------- */ +/* ARGSUSED */ 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) +H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, 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 */ char *t; /* Pointer to temporary buffer allocated */ size_t len; /* Maximum length of the string to copy */ - H5P_genplist_t *plist; /* Property list */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_str_mem_write) @@ -594,22 +587,13 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, voi H5_CHECK_OVERFLOW(((seq_len+1)*base_size),hsize_t,size_t); /* Use the user's memory allocation routine if one is defined */ - - /* Get the allocation function & info */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); - if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_NAME,&alloc_func)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); - if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_INFO_NAME,&alloc_info)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); - - if(alloc_func!=NULL) { - if(NULL==(t=(alloc_func)((size_t)((seq_len+1)*base_size),alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data"); + if(vl_alloc_info->alloc_func!=NULL) { + if(NULL==(t=(vl_alloc_info->alloc_func)((size_t)((seq_len+1)*base_size),vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end if */ else { /* Default to system malloc */ if(NULL==(t=H5MM_malloc((size_t)((seq_len+1)*base_size)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end else */ H5_ASSIGN_OVERFLOW(len,(seq_len*base_size),hsize_t,size_t); @@ -620,7 +604,7 @@ H5T_vlen_str_mem_write(H5F_t UNUSED *f, hid_t dxpl_id, void *_vl, void *buf, voi HDmemcpy(_vl,&t,sizeof(char *)); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ } /* end H5T_vlen_str_mem_write() */ @@ -638,6 +622,7 @@ done: * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static herr_t H5T_vlen_str_mem_setnull(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_vl, void UNUSED *_bg) { @@ -732,6 +717,7 @@ H5T_vlen_disk_isnull(H5F_t *f, void *_vl) * *------------------------------------------------------------------------- */ +/* ARGSUSED */ static herr_t H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t UNUSED len) { @@ -785,7 +771,7 @@ done: *------------------------------------------------------------------------- */ 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) +H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, hsize_t seq_len, hsize_t base_size) { 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 */ @@ -817,7 +803,7 @@ H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, void *_bg, hs /* 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 */ } /* end if */ /* Set the length of the sequence */ @@ -920,13 +906,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *free_info) +H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info) { - int i; /* local index variable */ - size_t j; /* local index variable */ + unsigned i; /* local index variable */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_reclaim_recurse); + FUNC_ENTER_NOAPI_NOINIT(H5T_vlen_reclaim_recurse) assert(elem); assert(dt); @@ -939,17 +924,17 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre void *off; /* offset of field */ /* Calculate the offset member and recurse on it */ - for(j=0; j<dt->u.array.nelem; j++) { - off=((uint8_t *)elem)+j*(dt->parent->size); + for(i=0; i<dt->u.array.nelem; i++) { + off=((uint8_t *)elem)+i*(dt->parent->size); if(H5T_vlen_reclaim_recurse(off,dt->parent,free_func,free_info)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free array element"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free array element") } /* end for */ } /* end if */ break; case H5T_COMPOUND: /* Check each field and recurse on VL, compound, enum or array ones */ - for (i=0; i<dt->u.compnd.nmembs; i++) { + for (i=0; i<(unsigned)dt->u.compnd.nmembs; i++) { /* Recurse if it's VL, compound, enum or array */ if(H5T_IS_COMPLEX(dt->u.compnd.memb[i].type->type)) { void *off; /* offset of field */ @@ -957,7 +942,7 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre /* Calculate the offset member and recurse on it */ off=((uint8_t *)elem)+dt->u.compnd.memb[i].offset; if(H5T_vlen_reclaim_recurse(off,dt->u.compnd.memb[i].type,free_func,free_info)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field") } /* end if */ } /* end for */ break; @@ -977,7 +962,7 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre while(vl->len>0) { off=((uint8_t *)vl->p)+(vl->len-1)*dt->parent->size; if(H5T_vlen_reclaim_recurse(off,dt->parent,free_func,free_info)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free VL element"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free VL element") vl->len--; } /* end while */ } /* end if */ @@ -1004,7 +989,7 @@ H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *fre } /* end switch */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_reclaim_recurse() */ @@ -1032,43 +1017,84 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ +/* ARGSUSED */ herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t UNUSED *point, void *op_data) { - hid_t plist_id = *(hid_t *)op_data; /* Dataset transfer plist from iterator */ - H5MM_free_t free_func; /* Vlen free function */ - void *free_info=NULL; /* Vlen free information */ - H5T_t *dt = NULL; - H5P_genplist_t *plist; /* Property list */ + H5T_vlen_alloc_info_t *vl_alloc_info = (H5T_vlen_alloc_info_t *)op_data; /* VL allocation info from iterator */ + H5T_t *dt; herr_t ret_value; - FUNC_ENTER_NOAPI(H5T_vlen_reclaim, FAIL); + FUNC_ENTER_NOAPI(H5T_vlen_reclaim, FAIL) assert(elem); + assert(vl_alloc_info); assert(H5I_DATATYPE == H5I_get_type(type_id)); /* Check args */ if (NULL==(dt=H5I_object_verify(type_id,H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - - /* Get the free func & information */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); - if (H5P_get(plist,H5D_XFER_VLEN_FREE_NAME,&free_func)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); - if (H5P_get(plist,H5D_XFER_VLEN_FREE_INFO_NAME,&free_info)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Pull the free function and free info pointer out of the op_data and call the recurse datatype free function */ - ret_value=H5T_vlen_reclaim_recurse(elem,dt,free_func,free_info); + ret_value=H5T_vlen_reclaim_recurse(elem,dt,vl_alloc_info->free_func,vl_alloc_info->free_info); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_reclaim() */ /*-------------------------------------------------------------------------- NAME + H5T_vlen_get_alloc_info + PURPOSE + Retrieve allocation info for VL datatypes + USAGE + herr_t H5T_vlen_get_alloc_info(dxpl_id,vl_alloc_info) + hid_t dxpl_id; IN: Data transfer property list to query + H5T_vlen_alloc_info_t *vl_alloc_info; IN/OUT: Pointer to VL allocation information to fill + + RETURNS + SUCCEED/FAIL + DESCRIPTION + Retrieve the VL allocation functions and information from a dataset + transfer property list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t *vl_alloc_info) +{ + H5P_genplist_t *plist; /* DX property list */ + herr_t ret_value=SUCCEED; + + FUNC_ENTER_NOAPI(H5T_vlen_get_alloc_info, FAIL) + + assert(H5I_GENPROP_LST == H5I_get_type(dxpl_id)); + assert(vl_alloc_info); + + /* Check args */ + if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") + + /* Get the allocation functions & information */ + if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_NAME,&vl_alloc_info->alloc_func)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + if (H5P_get(plist,H5D_XFER_VLEN_ALLOC_INFO_NAME,&vl_alloc_info->alloc_info)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + if (H5P_get(plist,H5D_XFER_VLEN_FREE_NAME,&vl_alloc_info->free_func)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + if (H5P_get(plist,H5D_XFER_VLEN_FREE_INFO_NAME,&vl_alloc_info->free_info)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get value") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_vlen_get_alloc_info() */ + + +/*-------------------------------------------------------------------------- + NAME H5T_vlen_mark PURPOSE Recursively mark any VL datatypes as on disk/in memory |