hdf5/src/H5Dcompact.c

674 lines
28 KiB
C
Raw Normal View History

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Programmer: Raymond Lu
* August 5, 2002
*
* Purpose: Compact dataset I/O functions. These routines are similar
* H5D_contig_* and H5D_chunk_*.
*/
/****************/
/* Module Setup */
/****************/
2020-09-30 22:27:10 +08:00
#include "H5Dmodule.h" /* This source code file is part of the H5D module */
/***********/
/* Headers */
/***********/
2020-09-30 22:27:10 +08:00
#include "H5private.h" /* Generic Functions */
#include "H5Dpkg.h" /* Dataset functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5VMprivate.h" /* Vector and array functions */
/****************/
/* Local Macros */
/****************/
/******************/
/* Local Typedefs */
/******************/
/* Callback info for I/O operation when file driver
* wishes to do its own memory management
*/
typedef struct H5D_compact_iovv_memmanage_ud_t {
H5F_shared_t *f_sh; /* Shared file for dataset */
void * dstbuf; /* Pointer to buffer to be read into/written into */
const void * srcbuf; /* Pointer to buffer to be read from/written from */
} H5D_compact_iovv_memmanage_ud_t;
/********************/
/* Local Prototypes */
/********************/
/* Layout operation callbacks */
2020-09-30 22:27:10 +08:00
static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset);
static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage);
2020-09-30 22:27:10 +08:00
static herr_t H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
static herr_t H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata);
2020-09-30 22:27:10 +08:00
static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
static ssize_t H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
static herr_t H5D__compact_flush(H5D_t *dset);
static herr_t H5D__compact_dest(H5D_t *dset);
/*********************/
/* Package Variables */
/*********************/
/* Compact storage layout I/O ops */
const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
H5D__compact_construct, /* construct */
NULL, /* init */
H5D__compact_is_space_alloc, /* is_space_alloc */
NULL, /* is_data_cached */
H5D__compact_io_init, /* io_init */
H5D__contig_read, /* ser_read */
H5D__contig_write, /* ser_write */
#ifdef H5_HAVE_PARALLEL
NULL, /* par_read */
NULL, /* par_write */
#endif
H5D__compact_readvv, /* readvv */
H5D__compact_writevv, /* writevv */
H5D__compact_flush, /* flush */
NULL, /* io_term */
H5D__compact_dest /* dest */
}};
/*******************/
/* Local Variables */
/*******************/
/* Declare extern the free list to manage blocks of type conversion data */
H5FL_BLK_EXTERN(type_conv);
/*-------------------------------------------------------------------------
* Function: H5D__compact_fill
*
* Purpose: Write fill values to a compactly stored dataset.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* May 6, 2007
*
*-------------------------------------------------------------------------
*/
herr_t
H5D__compact_fill(const H5D_t *dset)
{
2020-09-30 22:27:10 +08:00
H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Check args */
HDassert(dset && H5D_COMPACT == dset->shared->layout.type);
HDassert(dset->shared->layout.storage.u.compact.buf);
HDassert(dset->shared->type);
HDassert(dset->shared->space);
/* Initialize the fill value buffer */
/* (use the compact dataset storage buffer as the fill value buffer) */
2020-09-30 22:27:10 +08:00
if (H5D__fill_init(&fb_info, dset->shared->layout.storage.u.compact.buf, NULL, NULL, NULL, NULL,
&dset->shared->dcpl_cache.fill, dset->shared->type, dset->shared->type_id, (size_t)0,
dset->shared->layout.storage.u.compact.size) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info")
fb_info_init = TRUE;
/* Check for VL datatype & non-default fill value */
2020-09-30 22:27:10 +08:00
if (fb_info.has_vlen_fill_type)
/* Fill the buffer with VL datatype fill values */
2020-09-30 22:27:10 +08:00
if (H5D__fill_refill_vl(&fb_info, fb_info.elmts_per_buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "can't refill fill value buffer")
done:
/* Release the fill buffer info, if it's been initialized */
2020-09-30 22:27:10 +08:00
if (fb_info_init && H5D__fill_term(&fb_info) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release fill buffer info")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__compact_fill() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_construct
*
* Purpose: Constructs new compact layout information for dataset
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, May 22, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D__compact_construct(H5F_t *f, H5D_t *dset)
{
2020-09-30 22:27:10 +08:00
hssize_t stmp_size; /* Temporary holder for raw data size */
hsize_t tmp_size; /* Temporary holder for raw data size */
hsize_t max_comp_data_size; /* Max. allowed size of compact data */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(f);
HDassert(dset);
/* Check for invalid dataset dimensions */
2020-09-30 22:27:10 +08:00
for (u = 0; u < dset->shared->ndims; u++)
if (dset->shared->max_dims[u] > dset->shared->curr_dims[u])
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "extendible compact dataset not allowed")
/*
* Compact dataset is stored in dataset object header message of
* layout.
*/
stmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space);
HDassert(stmp_size >= 0);
tmp_size = H5T_get_size(dset->shared->type);
HDassert(tmp_size > 0);
tmp_size = tmp_size * (hsize_t)stmp_size;
H5_CHECKED_ASSIGN(dset->shared->layout.storage.u.compact.size, size_t, tmp_size, hssize_t);
/* Verify data size is smaller than maximum header message size
* (64KB) minus other layout message fields.
*/
max_comp_data_size = H5O_MESG_MAX_SIZE - H5D__layout_meta_size(f, &(dset->shared->layout), FALSE);
2020-09-30 22:27:10 +08:00
if (dset->shared->layout.storage.u.compact.size > max_comp_data_size)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"compact dataset size is bigger than header message maximum size")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__compact_construct() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_is_space_alloc
*
* Purpose: Query if space is allocated for layout
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, January 15, 2009
*
*-------------------------------------------------------------------------
*/
static hbool_t
H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
{
FUNC_ENTER_STATIC_NOERR
/* Sanity checks */
HDassert(storage);
/* Compact storage is currently always allocated */
FUNC_LEAVE_NOAPI(TRUE)
} /* end H5D__compact_is_space_alloc() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_io_init
*
* Purpose: Performs initialization before any sort of I/O on the raw data
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, March 20, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
{
FUNC_ENTER_STATIC_NOERR
2020-09-30 22:27:10 +08:00
io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf;
io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D__compact_io_init() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_iovv_memmanage_cb
*
* Purpose: Callback operator for H5D__compact_readvv()/_writevv() to
* send a memory copy request to the underlying file driver.
*
* Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
{
H5D_compact_iovv_memmanage_ud_t *udata = (H5D_compact_iovv_memmanage_ud_t *)_udata;
H5FD_ctl_memcpy_args_t op_args;
uint64_t op_flags;
H5FD_t * file_handle = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
/* Retrieve pointer to file driver structure for ctl call */
if (H5F_shared_get_file_driver(udata->f_sh, &file_handle) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get file handle")
/* Setup operation flags and arguments */
op_flags = H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG | H5FD_CTL__FAIL_IF_UNKNOWN_FLAG;
op_args.dstbuf = udata->dstbuf;
op_args.dst_off = dst_off;
op_args.srcbuf = udata->srcbuf;
op_args.src_off = src_off;
op_args.len = len;
/* Make request to file driver */
if (H5FD_ctl(file_handle, H5FD_CTL__MEM_COPY, op_flags, &op_args, NULL) < 0)
HGOTO_ERROR(H5E_IO, H5E_FCNTL, FAIL, "VFD memcpy request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__compact_iovv_memmanage_cb() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
* to the beginning address of the dataset. The offsets and
* sequence lengths are in bytes.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* May 7, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
*
*-------------------------------------------------------------------------
*/
static ssize_t
2020-09-30 22:27:10 +08:00
H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
{
2020-09-30 22:27:10 +08:00
ssize_t ret_value = -1; /* Return value */
FUNC_ENTER_STATIC
HDassert(io_info);
/* Check if file driver wishes to do its own memory management */
if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
H5D_compact_iovv_memmanage_ud_t udata;
/* Set up udata for memory copy operation */
udata.f_sh = io_info->f_sh;
udata.dstbuf = io_info->u.rbuf;
udata.srcbuf = io_info->store->compact.buf;
/* Request that file driver does the memory copy */
if ((ret_value = H5VM_opvv(mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, dset_max_nseq,
dset_curr_seq, dset_size_arr, dset_offset_arr,
H5D__compact_iovv_memmanage_cb, &udata)) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
}
else {
/* Use the vectorized memory copy routine to do actual work */
if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
mem_offset_arr, io_info->store->compact.buf, dset_max_nseq,
dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
}
done:
FUNC_LEAVE_NOAPI(ret_value)
2020-09-30 22:27:10 +08:00
} /* end H5D__compact_readvv() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_writevv
*
* Purpose: Writes some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
* to the beginning address for the file. The offsets and
* sequence lengths are in bytes. This function only copies
* data into the buffer in the LAYOUT struct and mark it
* as DIRTY. Later in H5D_close, the data is copied into
* header message in memory.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
*
*-------------------------------------------------------------------------
*/
static ssize_t
2020-09-30 22:27:10 +08:00
H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
{
2020-09-30 22:27:10 +08:00
ssize_t ret_value = -1; /* Return value */
FUNC_ENTER_STATIC
HDassert(io_info);
/* Check if file driver wishes to do its own memory management */
if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
H5D_compact_iovv_memmanage_ud_t udata;
/* Set up udata for memory copy operation */
udata.f_sh = io_info->f_sh;
udata.dstbuf = io_info->store->compact.buf;
udata.srcbuf = io_info->u.wbuf;
/* Request that file driver does the memory copy */
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, mem_max_nseq,
mem_curr_seq, mem_size_arr, mem_offset_arr, H5D__compact_iovv_memmanage_cb,
&udata)) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
}
else {
/* Use the vectorized memory copy routine to do actual work */
if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq,
dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq,
mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
}
/* Mark the compact dataset's buffer as dirty */
*io_info->store->compact.dirty = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
2020-09-30 22:27:10 +08:00
} /* end H5D__compact_writevv() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_flush
*
* Purpose: Writes dirty compact data to object header
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Monday, July 27, 2009
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D__compact_flush(H5D_t *dset)
{
2020-09-30 22:27:10 +08:00
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
/* Sanity check */
HDassert(dset);
/* Check if the buffered compact information is dirty */
2020-09-30 22:27:10 +08:00
if (dset->shared->layout.storage.u.compact.dirty) {
dset->shared->layout.storage.u.compact.dirty = FALSE;
2020-09-30 22:27:10 +08:00
if (H5O_msg_write(&(dset->oloc), H5O_LAYOUT_ID, 0, H5O_UPDATE_TIME, &(dset->shared->layout)) < 0) {
dset->shared->layout.storage.u.compact.dirty = TRUE;
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message")
}
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__compact_flush() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_dest
*
* Purpose: Free the compact buffer
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Thursday, Sept 3, 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5D__compact_dest(H5D_t *dset)
{
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(dset);
/* Free the buffer for the raw data for compact datasets */
dset->shared->layout.storage.u.compact.buf = H5MM_xfree(dset->shared->layout.storage.u.compact.buf);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D__compact_dest() */
/*-------------------------------------------------------------------------
* Function: H5D__compact_copy
*
* Purpose: Copy compact storage raw data from SRC file to DST file.
*
* Return: Non-negative on success, negative on failure.
*
* Programmer: Peter Cao
* December 11, 2005
*
*-------------------------------------------------------------------------
*/
herr_t
H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_dst,
2020-09-30 22:27:10 +08:00
H5O_storage_compact_t *storage_dst, H5T_t *dt_src, H5O_copy_t *cpy_info)
{
2020-09-30 22:27:10 +08:00
hid_t tid_src = -1; /* Datatype ID for source datatype */
hid_t tid_dst = -1; /* Datatype ID for destination datatype */
hid_t tid_mem = -1; /* Datatype ID for memory datatype */
void * buf = NULL; /* Buffer for copying data */
void * bkg = NULL; /* Temporary buffer for copying data */
void * reclaim_buf = NULL; /* Buffer for reclaiming data */
hid_t buf_sid = -1; /* ID for buffer dataspace */
H5D_shared_t *shared_fo =
(H5D_shared_t *)cpy_info->shared_fo; /* Pointer to the shared struct for dataset object */
H5O_storage_compact_t *storage_src = _storage_src; /* Pointer to storage_src */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Check args */
HDassert(f_src);
HDassert(storage_src);
HDassert(f_dst);
HDassert(storage_dst);
HDassert(storage_dst->buf);
HDassert(dt_src);
/* If the dataset is open in the file, point to "layout" in the shared struct */
2020-09-30 22:27:10 +08:00
if (shared_fo != NULL)
storage_src = &(shared_fo->layout.storage.u.compact);
/* Create datatype ID for src datatype, so it gets freed */
2020-09-30 22:27:10 +08:00
if ((tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register source file datatype")
/* If there's a VLEN source datatype, do type conversion information */
2020-09-30 22:27:10 +08:00
if (H5T_detect_class(dt_src, H5T_VLEN, FALSE) > 0) {
H5T_path_t *tpath_src_mem, *tpath_mem_dst; /* Datatype conversion paths */
H5T_t * dt_dst; /* Destination datatype */
H5T_t * dt_mem; /* Memory datatype */
H5S_t * buf_space; /* Dataspace describing buffer */
size_t buf_size; /* Size of copy buffer */
size_t nelmts; /* Number of elements in buffer */
size_t src_dt_size; /* Source datatype size */
size_t tmp_dt_size; /* Temporary datatype size */
size_t max_dt_size; /* Max atatype size */
hsize_t buf_dim; /* Dimension for buffer */
/* create a memory copy of the variable-length datatype */
2020-09-30 22:27:10 +08:00
if (NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
2020-09-30 22:27:10 +08:00
if ((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) {
(void)H5T_close_real(dt_mem);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
[svn-r18011] Description: Bring Coverity changes into the trunk: (also other minor cleanups) r17991: Fix Coverity items 175 and 176. Fixed memory leak on error in print_enum in H5LT.c. r17993: (r17992 was not a Coverity change) Close Coverity issue #206: inconsistently checking whether dt->shared was non-NULL after H5T_alloc() returned a valid 'dt' value (which should guarantee that dt->shared is valid). r17994: Fix Coverity item 149. Fixed file handle leak on error in H5FD_stdio_open. r17995: Fixed Coverity issues 154 to 161: Added H5MP_close routine to error handling in the event *mp has not been freed before error. r17996: Close Coverity issue #126: potentially leaking merged_spans on routine failure. r17997: Fix Coverity items 147 and 148. Fixed resource leaks on error in H5FDloc.c. r17998: Coverity issue 269-272: Added integer result variable to functions that could return negative. Assigned to unsigned after checking. Added H5E_BEGIN_TRY block around H5Tclose and removed H5E_THROW in the catch block. Checked buffer is NULL before free. Changed HGOTO_ERROR outside of the if block to H5E_THROW. r17999: Close Coverity issue #127: release temporary spans in more generic manner. (Also add error checking to previous fix) r18000: Resolved Coverity issues 211 and 212 in H5T.c. Added comments to ignore Coverity warning regarding not checking pointer for NULL, as we are using an assert which catches the issue. r18001: Fix Coverity item 146. Fixed resource leak on error in H5O_layout_copy. r18002: Fix Coverity items 143 and 145. Fixed resource leaks on error in H5D_compact_copy and H5D_contig_copy. r18003: Close Coverity issue #192: close file on error r18004: Fix Coverity issue #125: release temporary spans on error r18005: Resolved Coverity issues 5, 25, and 83 (in H5T.c): Separated embedded functions in order to check for NULL on return of H5I_object before passing into H5T_copy. Check to see if new_dt is NULL within error handling before dereferencing it. Ignore Coverity's dead code warnings as the checks that lead to the code are machine dependent. r18006: Coverity 63,70,73: Checked result of function before assigning to an unsigned variable. r18007: Coverity 78,79: added continue statement if H5Pget_filter2 returns negative. r18008: Fixed Coverity issue # 138: Added support in error handling to free dst pointer (if allocated) on error. r18009: Whitespace & coding style cleanup
2009-12-13 13:28:30 +08:00
} /* end if */
/* create variable-length datatype at the destinaton file */
2020-09-30 22:27:10 +08:00
if (NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
2020-09-30 22:27:10 +08:00
if (H5T_set_loc(dt_dst, H5F_VOL_OBJ(f_dst), H5T_LOC_DISK) < 0) {
(void)H5T_close_real(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
[svn-r18011] Description: Bring Coverity changes into the trunk: (also other minor cleanups) r17991: Fix Coverity items 175 and 176. Fixed memory leak on error in print_enum in H5LT.c. r17993: (r17992 was not a Coverity change) Close Coverity issue #206: inconsistently checking whether dt->shared was non-NULL after H5T_alloc() returned a valid 'dt' value (which should guarantee that dt->shared is valid). r17994: Fix Coverity item 149. Fixed file handle leak on error in H5FD_stdio_open. r17995: Fixed Coverity issues 154 to 161: Added H5MP_close routine to error handling in the event *mp has not been freed before error. r17996: Close Coverity issue #126: potentially leaking merged_spans on routine failure. r17997: Fix Coverity items 147 and 148. Fixed resource leaks on error in H5FDloc.c. r17998: Coverity issue 269-272: Added integer result variable to functions that could return negative. Assigned to unsigned after checking. Added H5E_BEGIN_TRY block around H5Tclose and removed H5E_THROW in the catch block. Checked buffer is NULL before free. Changed HGOTO_ERROR outside of the if block to H5E_THROW. r17999: Close Coverity issue #127: release temporary spans in more generic manner. (Also add error checking to previous fix) r18000: Resolved Coverity issues 211 and 212 in H5T.c. Added comments to ignore Coverity warning regarding not checking pointer for NULL, as we are using an assert which catches the issue. r18001: Fix Coverity item 146. Fixed resource leak on error in H5O_layout_copy. r18002: Fix Coverity items 143 and 145. Fixed resource leaks on error in H5D_compact_copy and H5D_contig_copy. r18003: Close Coverity issue #192: close file on error r18004: Fix Coverity issue #125: release temporary spans on error r18005: Resolved Coverity issues 5, 25, and 83 (in H5T.c): Separated embedded functions in order to check for NULL on return of H5I_object before passing into H5T_copy. Check to see if new_dt is NULL within error handling before dereferencing it. Ignore Coverity's dead code warnings as the checks that lead to the code are machine dependent. r18006: Coverity 63,70,73: Checked result of function before assigning to an unsigned variable. r18007: Coverity 78,79: added continue statement if H5Pget_filter2 returns negative. r18008: Fixed Coverity issue # 138: Added support in error handling to free dst pointer (if allocated) on error. r18009: Whitespace & coding style cleanup
2009-12-13 13:28:30 +08:00
} /* end if */
2020-09-30 22:27:10 +08:00
if ((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) {
(void)H5T_close_real(dt_dst);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
[svn-r18011] Description: Bring Coverity changes into the trunk: (also other minor cleanups) r17991: Fix Coverity items 175 and 176. Fixed memory leak on error in print_enum in H5LT.c. r17993: (r17992 was not a Coverity change) Close Coverity issue #206: inconsistently checking whether dt->shared was non-NULL after H5T_alloc() returned a valid 'dt' value (which should guarantee that dt->shared is valid). r17994: Fix Coverity item 149. Fixed file handle leak on error in H5FD_stdio_open. r17995: Fixed Coverity issues 154 to 161: Added H5MP_close routine to error handling in the event *mp has not been freed before error. r17996: Close Coverity issue #126: potentially leaking merged_spans on routine failure. r17997: Fix Coverity items 147 and 148. Fixed resource leaks on error in H5FDloc.c. r17998: Coverity issue 269-272: Added integer result variable to functions that could return negative. Assigned to unsigned after checking. Added H5E_BEGIN_TRY block around H5Tclose and removed H5E_THROW in the catch block. Checked buffer is NULL before free. Changed HGOTO_ERROR outside of the if block to H5E_THROW. r17999: Close Coverity issue #127: release temporary spans in more generic manner. (Also add error checking to previous fix) r18000: Resolved Coverity issues 211 and 212 in H5T.c. Added comments to ignore Coverity warning regarding not checking pointer for NULL, as we are using an assert which catches the issue. r18001: Fix Coverity item 146. Fixed resource leak on error in H5O_layout_copy. r18002: Fix Coverity items 143 and 145. Fixed resource leaks on error in H5D_compact_copy and H5D_contig_copy. r18003: Close Coverity issue #192: close file on error r18004: Fix Coverity issue #125: release temporary spans on error r18005: Resolved Coverity issues 5, 25, and 83 (in H5T.c): Separated embedded functions in order to check for NULL on return of H5I_object before passing into H5T_copy. Check to see if new_dt is NULL within error handling before dereferencing it. Ignore Coverity's dead code warnings as the checks that lead to the code are machine dependent. r18006: Coverity 63,70,73: Checked result of function before assigning to an unsigned variable. r18007: Coverity 78,79: added continue statement if H5Pget_filter2 returns negative. r18008: Fixed Coverity issue # 138: Added support in error handling to free dst pointer (if allocated) on error. r18009: Whitespace & coding style cleanup
2009-12-13 13:28:30 +08:00
} /* end if */
/* Set up the conversion functions */
2020-09-30 22:27:10 +08:00
if (NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
2020-09-30 22:27:10 +08:00
if (NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
/* Determine largest datatype size */
2020-09-30 22:27:10 +08:00
if (0 == (src_dt_size = H5T_get_size(dt_src)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
2020-09-30 22:27:10 +08:00
if (0 == (tmp_dt_size = H5T_get_size(dt_mem)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
max_dt_size = MAX(src_dt_size, tmp_dt_size);
2020-09-30 22:27:10 +08:00
if (0 == (tmp_dt_size = H5T_get_size(dt_dst)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
max_dt_size = MAX(max_dt_size, tmp_dt_size);
/* Set number of whole elements that fit in buffer */
2020-09-30 22:27:10 +08:00
if (0 == (nelmts = storage_src->size / src_dt_size))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large")
/* Set up number of bytes to copy, and initial buffer size */
buf_size = nelmts * max_dt_size;
/* Create dataspace for number of elements in buffer */
buf_dim = nelmts;
/* Create the space and set the initial extent */
2020-09-30 22:27:10 +08:00
if (NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
/* Register */
2020-09-30 22:27:10 +08:00
if ((buf_sid = H5I_register(H5I_DATASPACE, buf_space, FALSE)) < 0) {
H5S_close(buf_space);
HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
} /* end if */
/* Allocate memory for recclaim buf */
2020-09-30 22:27:10 +08:00
if (NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Allocate memory for copying the chunk */
2020-09-30 22:27:10 +08:00
if (NULL == (buf = H5FL_BLK_MALLOC(type_conv, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
H5MM_memcpy(buf, storage_src->buf, storage_src->size);
/* allocate temporary bkg buff for data conversion */
2020-09-30 22:27:10 +08:00
if (NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Convert from source file to memory */
2020-09-30 22:27:10 +08:00
if (H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
/* Copy into another buffer, to reclaim memory later */
H5MM_memcpy(reclaim_buf, buf, buf_size);
/* Set background buffer to all zeros */
HDmemset(bkg, 0, buf_size);
/* Convert from memory to destination file */
2020-09-30 22:27:10 +08:00
if (H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
H5MM_memcpy(storage_dst->buf, buf, storage_dst->size);
2020-09-30 22:27:10 +08:00
if (H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data")
} /* end if */
2020-09-30 22:27:10 +08:00
else if (H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) {
if (f_src != f_dst) {
/* Check for expanding references */
2020-09-30 22:27:10 +08:00
if (cpy_info->expand_ref) {
/* Copy objects referenced in source buffer to destination file and set destination elements
*/
if (H5O_copy_expand_ref(f_src, tid_src, dt_src, storage_src->buf, storage_src->size, f_dst,
storage_dst->buf, cpy_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute")
} /* end if */
else
/* Reset value to zero */
HDmemset(storage_dst->buf, 0, storage_src->size);
} /* end if */
else
/* Type conversion not necessary */
H5MM_memcpy(storage_dst->buf, storage_src->buf, storage_src->size);
} /* end if */
else
/* Type conversion not necessary */
H5MM_memcpy(storage_dst->buf, storage_src->buf, storage_src->size);
/* Mark destination buffer as dirty */
storage_dst->dirty = TRUE;
done:
2020-09-30 22:27:10 +08:00
if (buf_sid > 0 && H5I_dec_ref(buf_sid) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't decrement temporary dataspace ID")
2020-09-30 22:27:10 +08:00
if (tid_src > 0 && H5I_dec_ref(tid_src) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
2020-09-30 22:27:10 +08:00
if (tid_dst > 0 && H5I_dec_ref(tid_dst) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
2020-09-30 22:27:10 +08:00
if (tid_mem > 0 && H5I_dec_ref(tid_mem) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
2020-09-30 22:27:10 +08:00
if (buf)
buf = H5FL_BLK_FREE(type_conv, buf);
2020-09-30 22:27:10 +08:00
if (reclaim_buf)
reclaim_buf = H5FL_BLK_FREE(type_conv, reclaim_buf);
2020-09-30 22:27:10 +08:00
if (bkg)
bkg = H5FL_BLK_FREE(type_conv, bkg);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__compact_copy() */