diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-06-15 17:52:25 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-06-15 17:52:25 (GMT) |
commit | 40160d4d740ff706520b396fd9367089e8e4e2a2 (patch) | |
tree | eeac17c555696cc94dcbc9493629a056ee6ccd39 /src/H5Dio.c | |
parent | 71c91c6e85219d325c23ef8f71ff0af23989c0da (diff) | |
download | hdf5-40160d4d740ff706520b396fd9367089e8e4e2a2.zip hdf5-40160d4d740ff706520b396fd9367089e8e4e2a2.tar.gz hdf5-40160d4d740ff706520b396fd9367089e8e4e2a2.tar.bz2 |
[svn-r13870] Description:
Fix writing variable-length datatype fill values for contiguous dataset
storage
Tested on:
Mac OS X/32 10.4.9 (amazon)
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
Diffstat (limited to 'src/H5Dio.c')
-rw-r--r-- | src/H5Dio.c | 109 |
1 files changed, 66 insertions, 43 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 3c36953..b494596 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -202,24 +202,22 @@ done: static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id) { - H5T_path_t *tpath = NULL; /* Conversion information*/ uint8_t *tconv_buf = NULL; /* Data type conv buffer */ uint8_t *bkg_buf = NULL; /* Background conversion buffer */ uint8_t *tmp_buf = NULL; /* Temp conversion buffer */ hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */ size_t src_type_size; /* Size of source type */ size_t dst_type_size; /* Size of destination type*/ - hssize_t nelmts; /* Number of data elements */ size_t buf_size; /* Desired buffer size */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_fill) /* Check args */ - assert(fill_type); - assert(buf); - assert(buf_type); - assert(space); + HDassert(fill_type); + HDassert(buf); + HDassert(buf_type); + HDassert(space); /* Make sure the dataspace has an extent set (or is NULL) */ if(!(H5S_has_extent(space))) @@ -230,25 +228,26 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t dst_type_size = H5T_get_size(buf_type); /* Get the maximum buffer size needed and allocate it */ - buf_size = MAX(src_type_size,dst_type_size); - - /* Allocate space for conversion buffer */ - if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_elem, buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + buf_size = MAX(src_type_size, dst_type_size); /* If there's no fill value, just use zeros */ if(fill == NULL) { - HDmemset(tconv_buf, 0, dst_type_size); + /* Allocate space & initialize conversion buffer to zeros */ + if(NULL == (tconv_buf = H5FL_BLK_CALLOC(type_elem, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Fill the selection in the memory buffer */ if(H5S_select_fill(tconv_buf, dst_type_size, space, buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed") } /* end if */ else { + H5T_path_t *tpath; /* Conversion path information */ + /* Set up type conversion function */ if(NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id, FALSE))) HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest datatype") + /* Construct source & destination datatype IDs, if we will need them */ if(!H5T_path_noop(tpath)) { if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL))) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") @@ -257,46 +256,65 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") } /* end if */ - /* Copy the user's data into the buffer for conversion */ - HDmemcpy(tconv_buf, fill, src_type_size); - + /* If there's VL type of data, make multiple copies of fill value first, + * then do conversion on each element so that each of them has a copy + * of the VL data. + */ if(TRUE == H5T_detect_class(fill_type, H5T_VLEN)) { - /* If there's VL type of data, make multiple copies of fill value first, - * then do conversion on each element so that each of them has a copy - * of the VL data. - */ + H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ + H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ + H5S_sel_iter_t mem_iter; /* Memory selection iteration info */ + hssize_t nelmts; /* Number of data elements */ - /* Get the number of elements */ - nelmts = H5S_get_simple_extent_npoints(space); + /* Get the number of elements in the selection */ + nelmts = H5S_GET_SELECT_NPOINTS(space); + HDassert(nelmts >= 0); + H5_CHECK_OVERFLOW(nelmts, hssize_t, size_t); /* Allocate a temporary buffer */ if(NULL == (tmp_buf = H5FL_BLK_MALLOC(type_conv, (size_t)nelmts * buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") -/* XXX: Should replicate the fill value into the temp. buffer elements, then - * type convert the temp. buffer, then scatter the temp. buffer elements - * to the user's buffer. - QAK, 2007/05/31 - */ - /* Fill the selection in the temporary buffer */ - if(H5S_select_fill(tconv_buf, src_type_size, space, tmp_buf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed") - - /* Convert disk buffer into memory buffer */ - if(!H5T_path_noop(tpath)) { - /* Allocate a background buffer */ - if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (size_t)nelmts * buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + /* Allocate a background buffer, if necessary */ + if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (size_t)nelmts * buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Perform datatype conversion */ - if(H5T_convert(tpath, src_id, dst_id, (size_t)nelmts, (size_t)0, (size_t)0, tmp_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + /* Replicate the file's fill value into the temporary buffer */ + H5V_array_fill(tmp_buf, fill, src_type_size, (size_t)nelmts); + + /* Convert from file's fill value into memory form */ + if(H5T_convert(tpath, src_id, dst_id, (size_t)nelmts, (size_t)0, (size_t)0, tmp_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed") + + /* Fill the DXPL cache values for later use */ + if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + + /* Create a selection iterator for scattering the elements to memory buffer */ + if(H5S_select_iter_init(&mem_iter, space, dst_type_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") + + /* Scatter the data into memory */ + if(H5D_select_mscat(tmp_buf, space, &mem_iter, (size_t)nelmts, dxpl_cache, buf/*out*/) < 0) { + H5S_SELECT_ITER_RELEASE(&mem_iter); + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "scatter failed") } /* end if */ - /* Copy the final data into the memory buffer */ - HDmemcpy(buf, tmp_buf, (size_t)nelmts * dst_type_size); + /* Release the selection iterator */ + if(H5S_SELECT_ITER_RELEASE(&mem_iter) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") } else { + const uint8_t *fill_buf; /* Buffer to use for writing fill values */ + /* Convert disk buffer into memory buffer */ if(!H5T_path_noop(tpath)) { + /* Allocate space for conversion buffer */ + if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_elem, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the user's data into the buffer for conversion */ + HDmemcpy(tconv_buf, fill, src_type_size); + /* If there's no VL type of data, do conversion first then fill the data into * the memory buffer. */ if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_elem, buf_size))) @@ -304,11 +322,16 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t /* Perform datatype conversion */ if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed") + + /* Point at temporary buffer */ + fill_buf = tconv_buf; } /* end if */ + else + fill_buf = fill; /* Fill the selection in the memory buffer */ - if(H5S_select_fill(tconv_buf, dst_type_size, space, buf) < 0) + if(H5S_select_fill(fill_buf, dst_type_size, space, buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed") } /* end else */ } /* end else */ @@ -319,9 +342,9 @@ done: if(dst_id != (-1) && H5I_dec_ref(dst_id) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") if(tmp_buf) - H5FL_BLK_FREE(type_conv,tmp_buf); + H5FL_BLK_FREE(type_conv, tmp_buf); if(tconv_buf) - H5FL_BLK_FREE(type_elem,tconv_buf); + H5FL_BLK_FREE(type_elem, tconv_buf); if(bkg_buf) { if(TRUE == H5T_detect_class(fill_type, H5T_VLEN)) H5FL_BLK_FREE(type_conv, bkg_buf); |