diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-09-25 22:22:14 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-09-25 22:22:14 (GMT) |
commit | c77e39522b4ed0ac4a811dddeafbd7426014b27d (patch) | |
tree | 2f6e2a836df24bdb4a44bb9c168fce12bc2739ec /src | |
parent | c439d91f811d91df590996cff2d3162c541bb1cf (diff) | |
download | hdf5-c77e39522b4ed0ac4a811dddeafbd7426014b27d.zip hdf5-c77e39522b4ed0ac4a811dddeafbd7426014b27d.tar.gz hdf5-c77e39522b4ed0ac4a811dddeafbd7426014b27d.tar.bz2 |
[svn-r12680] Description:
Review, revise & checkin in Peter's latest round of object copy changes,
which add basic support for datasets & attributes with reference datatypes.
Tested on:
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 2 | ||||
-rw-r--r-- | src/H5Dcompact.c | 31 | ||||
-rw-r--r-- | src/H5Dcontig.c | 184 | ||||
-rw-r--r-- | src/H5Distore.c | 303 | ||||
-rw-r--r-- | src/H5Dpkg.h | 23 | ||||
-rw-r--r-- | src/H5F.c | 25 | ||||
-rw-r--r-- | src/H5G.c | 78 | ||||
-rw-r--r-- | src/H5Gpkg.h | 1 | ||||
-rw-r--r-- | src/H5Gprivate.h | 1 | ||||
-rw-r--r-- | src/H5Gpublic.h | 2 | ||||
-rw-r--r-- | src/H5HG.c | 62 | ||||
-rw-r--r-- | src/H5HGprivate.h | 2 | ||||
-rw-r--r-- | src/H5O.c | 329 | ||||
-rw-r--r-- | src/H5Oattr.c | 69 | ||||
-rw-r--r-- | src/H5Ocache.c | 30 | ||||
-rw-r--r-- | src/H5Odtype.c | 3 | ||||
-rw-r--r-- | src/H5Olayout.c | 13 | ||||
-rw-r--r-- | src/H5Oprivate.h | 5 | ||||
-rwxr-xr-x | src/H5Pocpl.c | 2 | ||||
-rw-r--r-- | src/H5R.c | 89 | ||||
-rw-r--r-- | src/H5Rpublic.h | 8 | ||||
-rw-r--r-- | src/H5Tconv.c | 2 | ||||
-rw-r--r-- | src/H5Tvlen.c | 2 |
23 files changed, 816 insertions, 450 deletions
@@ -524,7 +524,7 @@ H5_debug_mask(const char *s) } else if (HDisdigit(*s)) { int fd = (int)HDstrtol (s, &rest, 0); if ((stream=HDfdopen(fd, "w"))!=NULL) - (void)HDsetvbuf (stream, NULL, _IOLBF, 0); + (void)HDsetvbuf (stream, NULL, _IOLBF, (size_t)0); s = rest; } else { s++; diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index 842ad9c..2d17a57 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -140,6 +140,7 @@ H5D_compact_writevv(const H5D_io_info_t *io_info, if((ret_value=H5V_memcpyvv(io_info->dset->shared->layout.u.compact.buf,dset_max_nseq,dset_curr_seq,dset_size_arr,dset_offset_arr,buf,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->dset->shared->layout.u.compact.dirty = TRUE; done: @@ -160,8 +161,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_compact_copy(const H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *layout_dst, - H5T_t *dt_src, hid_t dxpl_id) +H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, + H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, hid_t dxpl_id) { hid_t tid_src = -1; /* Datatype ID for source datatype */ hid_t tid_dst = -1; /* Datatype ID for destination datatype */ @@ -176,14 +177,32 @@ H5D_compact_copy(const H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *la /* Check args */ HDassert(layout_src && H5D_COMPACT == layout_src->type); + HDassert(f_src); HDassert(f_dst); HDassert(layout_dst && H5D_COMPACT == layout_dst->type); /* If there's a source datatype, set up type conversion information */ - if (!dt_src) + if(!dt_src) /* Type conversion not necessary */ HDmemcpy(layout_dst->u.compact.buf, layout_src->u.compact.buf, layout_src->u.compact.size); - else { + else if(dt_src && (H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) && (f_src != f_dst)) { + /* Check for expanding references */ + if(cpy_info->expand_ref) { + size_t ref_count; + + /* Determine # of reference elements to copy */ + ref_count = layout_src->u.compact.size / H5T_get_size(dt_src); + + /* Copy objects referenced in source buffer to destination file and set destination elements */ + if(H5O_copy_expand_ref(f_src, layout_src->u.compact.buf, dxpl_id, f_dst, + layout_dst->u.compact.buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + } /* end if */ + else + /* Reset value to zero */ + HDmemset(layout_dst->u.compact.buf, 0, layout_src->u.compact.size); + } /* end if */ + else if(dt_src && (H5T_detect_class(dt_src, H5T_VLEN) > 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 */ @@ -203,7 +222,7 @@ H5D_compact_copy(const H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *la if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") /* create variable-length datatype at the destinaton file */ if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) @@ -278,6 +297,8 @@ H5D_compact_copy(const H5O_layout_t *layout_src, H5F_t *f_dst, H5O_layout_t *la if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ + else + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy dataset elements") done: if(buf_sid > 0) diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 544e092..d39c8c5 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -104,7 +104,7 @@ H5D_contig_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ ) /* Allocate space for the contiguous data */ if (HADDR_UNDEF==(layout->u.contig.addr=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, layout->u.contig.size))) - HGOTO_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space") + HGOTO_ERROR(H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space") done: FUNC_LEAVE_NOAPI(ret_value) @@ -212,7 +212,7 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id) if(dset->shared->fill.buf) { /* Allocate temporary buffer */ if ((buf=H5FL_BLK_MALLOC(non_zero_fill,bufsize))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer") H5V_array_fill(buf, dset->shared->fill.buf, elmt_size, ptsperbuf); @@ -232,7 +232,7 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id) else buf=H5FL_BLK_MALLOC(zero_fill,bufsize); if(buf==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill buffer") /* Indicate that a zero fill buffer was used */ non_zero_fill_f=0; @@ -996,8 +996,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, - H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *dt_src, hid_t dxpl_id) +H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, + H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, hid_t dxpl_id) { haddr_t addr_src; /* File offset in source dataset */ haddr_t addr_dst; /* File offset in destination dataset */ @@ -1023,7 +1023,8 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5S_t *buf_space = NULL; /* Dataspace describing buffer */ hid_t buf_sid = -1; /* ID for buffer dataspace */ hsize_t buf_dim; /* Dimension for buffer */ - hbool_t do_conv; /* Flag to indicate that type conversion should occur */ + hbool_t is_vlen = FALSE; /* Flag to indicate that VL type conversion should occur */ + hbool_t fix_ref = FALSE; /* Flag to indicate that ref values should be fixed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_contig_copy, FAIL) @@ -1045,71 +1046,83 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, /* If there's a source datatype, set up type conversion information */ if(dt_src) { - /* Create datatype ID for src datatype */ - if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") - - /* create a memory copy of the variable-length datatype */ - if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") - if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") - - /* create variable-length datatype at the destinaton file */ - if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") - if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") - if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") - - /* Set up the conversion functions */ - if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") - if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") - - /* Determine largest datatype size */ - if(0 == (src_dt_size = H5T_get_size(dt_src))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") - if(0 == (mem_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, mem_dt_size); - if(0 == (dst_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, dst_dt_size); - - /* Set maximum number of whole elements that fit in buffer */ - if(0 == (nelmts = buf_size / max_dt_size)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large") - - /* Set the number of bytes to transfer */ - src_nbytes = nelmts * src_dt_size; - dst_nbytes = nelmts * dst_dt_size; - mem_nbytes = nelmts * mem_dt_size; - - /* Adjust buffer size to be multiple of elements */ - 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 */ - if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") - - /* Atomize */ - if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) { - H5S_close(buf_space); - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") - } /* end if */ + if(H5T_detect_class(dt_src, H5T_VLEN) > 0) { + /* Create datatype ID for src datatype */ + if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") + + /* create a memory copy of the variable-length datatype */ + if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") + + /* create variable-length datatype at the destinaton file */ + if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") + if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") + + /* Set up the conversion functions */ + if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") + if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") + + /* Determine largest datatype size */ + if(0 == (src_dt_size = H5T_get_size(dt_src))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + if(0 == (mem_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, mem_dt_size); + if(0 == (dst_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, dst_dt_size); + + /* Set maximum number of whole elements that fit in buffer */ + if(0 == (nelmts = buf_size / max_dt_size)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large") + + /* Set the number of bytes to transfer */ + src_nbytes = nelmts * src_dt_size; + dst_nbytes = nelmts * dst_dt_size; + mem_nbytes = nelmts * mem_dt_size; + + /* Adjust buffer size to be multiple of elements */ + 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 */ + if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") + + /* Atomize */ + if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) { + H5S_close(buf_space); + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") + } /* end if */ - /* Set flag to do type conversion */ - do_conv = TRUE; + /* Set flag to do type conversion */ + is_vlen = TRUE; + } + /* Check for reference datatype */ + else if((H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) && (f_src != f_dst)) { + /* need to fix values of reference */ + fix_ref = TRUE; + + /* Set the number of bytes to read & write to the buffer size */ + src_nbytes = dst_nbytes = mem_nbytes = buf_size; + } /* end if */ + else + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy dataset elements") } /* end if */ else { /* Type conversion not necessary */ - do_conv = FALSE; + is_vlen = FALSE; /* Set the number of bytes to read & write to the buffer size */ src_nbytes = dst_nbytes = mem_nbytes = buf_size; @@ -1121,9 +1134,13 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") /* Need extra buffer for datatype conversions, to prevent stranding/leaking memory */ - if(do_conv) { + if(is_vlen || fix_ref) { if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + + /* allocate temporary bkg buff for data conversion */ + if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") } /* end if */ /* Loop over copying data */ @@ -1136,7 +1153,7 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, src_nbytes = (size_t)total_src_nbytes; /* Adjust dataspace describing buffer */ - if(do_conv) { + if(is_vlen) { /* Adjust destination & memory bytes to transfer */ nelmts = src_nbytes / src_dt_size; dst_nbytes = nelmts * dst_dt_size; @@ -1149,10 +1166,9 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, if(H5S_set_extent_real(buf_space, &buf_dim) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to change buffer dataspace size") } /* end if */ - else { + else /* Adjust destination & memory bytes to transfer */ dst_nbytes = mem_nbytes = src_nbytes; - } /* end else */ } /* end if */ /* Read raw data from source file */ @@ -1160,7 +1176,7 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read raw data") /* Perform datatype conversion, if necessary */ - if(do_conv) { + if(is_vlen) { /* Convert from source file to memory */ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") @@ -1168,9 +1184,8 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, /* Copy into another buffer, to reclaim memory later */ HDmemcpy(reclaim_buf, buf, mem_nbytes); - /* allocate temporary bkg buff for data conversion */ - if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + /* Set background buffer to all zeros */ + HDmemset(bkg, 0, buf_size); /* Convert from memory to destination file */ if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0) @@ -1180,6 +1195,25 @@ H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ + else if(fix_ref) { + /* Check for expanding references */ + if(cpy_info->expand_ref) { + size_t ref_count; + + /* Determine # of reference elements to copy */ + ref_count = src_nbytes / H5T_get_size(dt_src); + + /* Copy the reference elements */ + if(H5O_copy_expand_ref(f_src, buf, dxpl_id, f_dst, bkg, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + + /* After fix ref, copy the new reference elements to the buffer to write out */ + HDmemcpy(buf, bkg, buf_size); + } /* end if */ + else + /* Reset value to zero */ + HDmemset(buf, 0, src_nbytes); + } /* end if */ /* Write raw data to destination file */ if(H5F_block_write(f_dst, H5FD_MEM_DRAW, addr_dst, dst_nbytes, H5P_DATASET_XFER_DEFAULT, buf) < 0) diff --git a/src/H5Distore.c b/src/H5Distore.c index 26d332a..8518763 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -192,15 +192,17 @@ typedef struct H5D_istore_it_ud3_t { /* B-tree callback info for iteration to copy data */ typedef struct H5D_istore_it_ud4_t { H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */ - H5F_t *file_dst; /* Destination file for copy */ + H5F_t *file_src; /* Source file for copy */ haddr_t addr_dst; /* Address of dest. B-tree */ void *buf; /* Buffer to hold chunk data for read/write */ + void *bkg; /* Buffer for background information during type conversion */ size_t buf_size; /* Buffer size */ /* needed for converting variable-length data */ hid_t tid_src; /* Datatype ID for source datatype */ hid_t tid_dst; /* Datatype ID for destination datatype */ hid_t tid_mem; /* Datatype ID for memory datatype */ + H5T_t *dt_src; /* Source datatype */ H5T_path_t *tpath_src_mem; /* Datatype conversion path from source file to memory */ H5T_path_t *tpath_mem_dst; /* Datatype conversion path from memory to dest. file */ void *reclaim_buf; /* Buffer for reclaiming data */ @@ -210,6 +212,10 @@ typedef struct H5D_istore_it_ud4_t { /* needed for compressed variable-length data */ H5O_pline_t *pline; /* Filter pipeline */ + + /* needed for copy object pointed by refs */ + H5F_t *file_dst; /* Destination file for copy */ + H5O_copy_t *cpy_info; /* Copy options */ } H5D_istore_it_ud4_t; /* B-tree callback info for iteration to obtain chunk address and the index of the chunk for all chunks in the B-tree. */ @@ -915,7 +921,7 @@ H5D_istore_iter_chunkmap (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt rank = udata->common.mesg->u.chunk.ndims - 1; if(H5V_chunk_index(rank,lt_key->offset,udata->common.mesg->u.chunk.dim,udata->down_chunks,&chunk_index)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") udata->chunk_addr[chunk_index] = addr; @@ -982,16 +988,17 @@ H5D_istore_iter_dump (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt_key *------------------------------------------------------------------------- */ static int -H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t addr_src, - const void UNUSED *_rt_key, void *_udata) +H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, + haddr_t addr_src, const void UNUSED *_rt_key, void *_udata) { H5D_istore_it_ud4_t *udata = (H5D_istore_it_ud4_t *)_udata; const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key; H5D_istore_ud1_t udata_dst; /* User data about new destination chunk */ - void *bkg = NULL; /* Temporary buffer for copying data */ hbool_t is_vlen = FALSE; + hbool_t fix_ref = FALSE; /* General information about chunk copy */ + void *bkg = udata->bkg; void *buf = udata->buf; size_t buf_size = udata->buf_size; H5O_pline_t *pline = udata->pline; @@ -1007,17 +1014,23 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t a FUNC_ENTER_NOAPI_NOINIT(H5D_istore_iter_copy) /* Check parameter for type conversion */ - if (udata->tid_src > 0) - is_vlen = TRUE; + if(udata->dt_src) { + if(H5T_detect_class(udata->dt_src, H5T_VLEN) > 0) + is_vlen = TRUE; + else if((H5T_get_class(udata->dt_src, FALSE) == H5T_REFERENCE) && (udata->file_src != udata->file_dst)) + fix_ref = TRUE; + else + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy dataset elements") + } /* end if */ /* Check for filtered chunks */ - if (pline && pline->nused) { + if(pline && pline->nused) { is_compressed = TRUE; cb_struct.func = NULL; /* no callback function when failed */ } /* end if */ /* Resize the buf if it is too small to hold the data */ - if ( nbytes > buf_size) { + if(nbytes > buf_size) { /* Re-allocate memory for copying the chunk */ if(NULL == (udata->buf = H5MM_realloc(udata->buf, nbytes))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5B_ITER_ERROR, "memory allocation failed for raw data chunk") @@ -1030,8 +1043,8 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t a if(H5F_block_read(f_src, H5FD_MEM_DRAW, addr_src, nbytes, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, H5B_ITER_ERROR, "unable to read raw data chunk") - /* need to uncompress variable-length data */ - if (is_compressed && is_vlen) { + /* Need to uncompress variable-length & reference data elements */ + if(is_compressed && (is_vlen | fix_ref)) { unsigned filter_mask = lt_key->filter_mask; if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, cb_struct, &nbytes, &buf_size, &buf) < 0) @@ -1057,9 +1070,8 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t a /* Copy into another buffer, to reclaim memory later */ HDmemcpy(reclaim_buf, buf, reclaim_buf_size); - /* allocate temporary bkg buff for data conversion */ - if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5B_ITER_ERROR, "memory allocation failed") + /* Set background buffer to all zeros */ + HDmemset(bkg, 0, buf_size); /* Convert from memory to destination file */ if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0) @@ -1069,14 +1081,31 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t a if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, H5B_ITER_ERROR, "unable to reclaim variable-length data") } /* end if */ + else if(fix_ref) { + /* Check for expanding references */ + /* (background buffer has already been zeroed out, if not expanding) */ + if(udata->cpy_info->expand_ref) { + size_t ref_count; + + /* Determine # of reference elements to copy */ + ref_count = nbytes / H5T_get_size(udata->dt_src); + + /* Copy the reference elements */ + if(H5O_copy_expand_ref(f_src, buf, dxpl_id, udata->file_dst, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + } /* end if */ + + /* After fix ref, copy the new reference elements to the buffer to write out */ + HDmemcpy(buf, bkg, buf_size); + } /* end if */ /* Copy source chunk callback information for insertion */ HDmemset(&udata_dst, 0, sizeof(udata_dst)); HDmemcpy(&(udata_dst.common.key), lt_key, sizeof(H5D_istore_key_t)); udata_dst.common.mesg = udata->common.mesg; /* Share this pointer for a short while */ - /* need to compress variable-length data before writing to file*/ - if (is_compressed && is_vlen) { + /* Need to compress variable-length & reference data elements before writing to file */ + if(is_compressed && (is_vlen || fix_ref) ) { if(H5Z_pipeline(pline, 0, &(udata_dst.common.key.filter_mask), edc_read, cb_struct, &nbytes, &buf_size, &buf) < 0) HGOTO_ERROR(H5E_PLINE, H5E_READERROR, H5B_ITER_ERROR, "output pipeline failed") @@ -1095,9 +1124,6 @@ H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t a HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5B_ITER_ERROR, "unable to write raw data to file") done: - if(bkg) - H5FL_BLK_FREE(type_conv, bkg); - FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_istore_iter_copy() */ @@ -1128,12 +1154,12 @@ H5D_istore_init (const H5F_t *f, const H5D_t *dset) rdcc->nslots = H5F_RDCC_NELMTS(f); rdcc->slot = H5FL_SEQ_CALLOC (H5D_rdcc_ent_ptr_t,rdcc->nslots); if (NULL==rdcc->slot) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") } /* end if */ /* Allocate the shared structure */ if(H5D_istore_shared_create(f, &dset->shared->layout)<0) - HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_istore_init() */ @@ -1362,7 +1388,7 @@ H5D_istore_flush (H5D_t *dset, hid_t dxpl_id, unsigned flags) } /* end for */ if (nerrors) - HGOTO_ERROR (H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") + HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1415,7 +1441,7 @@ H5D_istore_dest (H5D_t *dset, hid_t dxpl_id) nerrors++; } if (nerrors) - HGOTO_ERROR (H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") + HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") if(rdcc->slot) H5FL_SEQ_FREE (H5D_rdcc_ent_ptr_t,rdcc->slot); @@ -1423,9 +1449,9 @@ H5D_istore_dest (H5D_t *dset, hid_t dxpl_id) /* Free the raw B-tree node buffer */ if(dset->shared->layout.u.chunk.btree_shared==NULL) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") if(H5RC_DEC(dset->shared->layout.u.chunk.btree_shared)<0) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1455,7 +1481,7 @@ H5D_istore_shared_create (const H5F_t *f, H5O_layout_t *layout) /* Allocate space for the shared structure */ if(NULL==(shared=H5FL_MALLOC(H5B_shared_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info") /* Set up the "global" information for this file's groups */ shared->type= H5B_ISTORE; @@ -1467,12 +1493,12 @@ H5D_istore_shared_create (const H5F_t *f, H5O_layout_t *layout) shared->sizeof_rnode = H5B_nodesize(f, shared, &shared->sizeof_keys); assert(shared->sizeof_rnode); if(NULL==(shared->page=H5FL_BLK_MALLOC(chunk_page,shared->sizeof_rnode))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") #ifdef H5_USING_PURIFY HDmemset(shared->page,0,shared->sizeof_rnode); #endif /* H5_USING_PURIFY */ if(NULL==(shared->nkey=H5FL_SEQ_MALLOC(size_t,(size_t)(2*H5F_KVALUE(f,H5B_ISTORE)+1)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") /* Initialize the offsets into the native key buffer */ for(u=0; u<(2*H5F_KVALUE(f,H5B_ISTORE)+1); u++) @@ -1480,7 +1506,7 @@ HDmemset(shared->page,0,shared->sizeof_rnode); /* Make shared B-tree info reference counted */ if(NULL==(layout->u.chunk.btree_shared=H5RC_create(shared,H5D_istore_shared_free))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1626,7 +1652,7 @@ H5D_istore_prune (const H5D_io_info_t *io_info, size_t size) } if (nerrors) - HGOTO_ERROR (H5E_IO, H5E_CANTFLUSH, FAIL, "unable to preempt one or more raw data cache entry") + HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to preempt one or more raw data cache entry") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1726,7 +1752,7 @@ H5D_istore_lock(const H5D_io_info_t *io_info, rdcc->nhits++; #endif if (NULL==(chunk=H5D_istore_chunk_alloc (chunk_size,pline))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") } else { H5D_istore_ud1_t tmp_udata; /*B-tree pass-through */ @@ -1778,7 +1804,7 @@ H5D_istore_lock(const H5D_io_info_t *io_info, /* Chunk size on disk isn't [likely] the same size as the final chunk * size in memory, so allocate memory big enough. */ if (NULL==(chunk = H5D_istore_chunk_alloc (chunk_size,pline))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") if (H5P_is_fill_value_defined(fill, &fill_status) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined") @@ -2077,7 +2103,7 @@ HDfprintf(stderr,"%s: buf=%p\n",FUNC,buf); /* Do I/O directly on chunk without reading it into the cache */ if ((ret_value=H5D_contig_readvv(&chk_io_info, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, buf))<0) - HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data to file") + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data to file") } /* end if */ else { uint8_t *chunk; /* Pointer to cached chunk in memory */ @@ -2257,9 +2283,9 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a /* Additional sanity checks when operating in parallel */ if(IS_H5FD_MPI(dset->oloc.file)) { if (chunk_addr==HADDR_UNDEF) - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk") if (dset->shared->dcpl_cache.pline.nused>0) - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "cannot write to chunked storage with filters in parallel") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot write to chunked storage with filters in parallel") } /* end if */ #endif /* H5_HAVE_PARALLEL */ @@ -2277,7 +2303,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a /* Do I/O directly on chunk without reading it into the cache */ if ((ret_value=H5D_contig_writevv(&chk_io_info, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, buf))<0) - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file") } /* end if */ else { uint8_t *chunk; /* Pointer to cached chunk in memory */ @@ -2317,7 +2343,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a #endif /* OLD_WAY */ if (NULL==(chunk=H5D_istore_lock(io_info, &udata, relax, &idx_hint))) - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk") /* Use the vectorized memory copy routine to do actual work */ if((naccessed=H5V_memcpyvv(chunk,chunk_max_nseq,chunk_curr_seq,chunk_len_arr,chunk_offset_arr,buf,mem_max_nseq,mem_curr_seq,mem_len_arr,mem_offset_arr))<0) @@ -2325,7 +2351,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a H5_CHECK_OVERFLOW(naccessed,ssize_t,size_t); if (H5D_istore_unlock(io_info, TRUE, idx_hint, chunk, (size_t)naccessed)<0) - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk") /* Set return value */ ret_value=naccessed; @@ -2582,17 +2608,17 @@ done: static void * H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline) { - void *ret_value=NULL; /* Return value */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_istore_chunk_alloc) - assert(size); - assert(pline); + HDassert(size); + HDassert(pline); - if(pline->nused>0) - ret_value=H5MM_malloc(size); + if(pline->nused > 0) + ret_value = H5MM_malloc(size); else - ret_value=H5FL_BLK_MALLOC(chunk,size); + ret_value = H5FL_BLK_MALLOC(chunk, size); FUNC_LEAVE_NOAPI(ret_value) } /* H5D_istore_chunk_alloc() */ @@ -2749,16 +2775,16 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite) * or if there are any pipeline filters defined, * set the "should fill" flag */ - if((!full_overwrite && (fill_time==H5D_FILL_TIME_ALLOC || - (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED))) - || pline.nused>0) - should_fill=1; + if((!full_overwrite && (fill_time == H5D_FILL_TIME_ALLOC || + (fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED))) + || pline.nused > 0) + should_fill = 1; /* Check if fill values should be written to blocks */ if(should_fill) { /* Allocate chunk buffer for processes to use when writing fill values */ - H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t); - if (NULL==(chunk = H5D_istore_chunk_alloc((size_t)chunk_size,&pline))) + H5_CHECK_OVERFLOW(chunk_size, hsize_t, size_t); + if(NULL == (chunk = H5D_istore_chunk_alloc((size_t)chunk_size, &pline))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for chunk") /* Fill the chunk with the proper values */ @@ -3249,7 +3275,7 @@ H5D_istore_initialize_by_extent(H5D_io_info_t *io_info) /* Get the "down" sizes for each dimension */ if(H5V_array_down(rank,chunks,down_chunks)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") /* Create a data space for a chunk & set the extent */ for(u = 0; u < rank; u++) @@ -3298,7 +3324,7 @@ H5D_istore_initialize_by_extent(H5D_io_info_t *io_info) /* Calculate the index of this chunk */ if(H5V_chunk_index(rank,chunk_offset,layout->u.chunk.dim,down_chunks,&store.chunk.index)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") store.chunk.offset=chunk_offset; if(NULL == (chunk = H5D_istore_lock(io_info, NULL, FALSE, &idx_hint))) @@ -3386,7 +3412,7 @@ H5D_istore_delete(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout) /* Allocate the shared structure */ if(H5D_istore_shared_create(f, &tmp_layout)<0) - HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") /* Delete entire B-tree */ if(H5B_delete(f, dxpl_id, H5B_ISTORE, tmp_layout.u.chunk.addr, &udata)<0) @@ -3394,9 +3420,9 @@ H5D_istore_delete(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout) /* Free the raw B-tree node buffer */ if(tmp_layout.u.chunk.btree_shared==NULL) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") if(H5RC_DEC(tmp_layout.u.chunk.btree_shared)<0) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") } /* end if */ done: @@ -3453,7 +3479,7 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id) /* Get the "down" sizes for each dimension */ if(H5V_array_down(rank,chunks,down_chunks)<0) - HGOTO_ERROR (H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") /* Fill the DXPL cache values for later use */ if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0) @@ -3468,7 +3494,7 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id) /* Calculate the index of this chunk */ if(H5V_chunk_index(rank,ent->offset,dset->shared->layout.u.chunk.dim,down_chunks,&idx)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Compute the index for the chunk entry */ old_idx=ent->idx; /* Save for later */ @@ -3486,7 +3512,7 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id) /* Remove the old entry from the cache */ if (H5D_istore_preempt(&io_info, old_ent, TRUE )<0) - HGOTO_ERROR (H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") + HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") } /* end if */ /* Insert this chunk into correct location in hash table */ @@ -3517,7 +3543,7 @@ done: */ herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, - H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_pline_t *pline, hid_t dxpl_id) + H5O_layout_t *layout_dst, H5T_t *dt_src, H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id) { H5D_istore_it_ud4_t udata; H5T_path_t *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */ @@ -3527,6 +3553,7 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, size_t buf_size; /* Size of copy buffer */ size_t reclaim_buf_size; /* Size of reclaim buffer */ void *buf = NULL; /* Buffer for copying data */ + void *bkg = NULL; /* Buffer for background during type conversion */ void *reclaim_buf = NULL; /* Buffer for reclaiming data */ H5S_t *buf_space = NULL; /* Dataspace describing buffer */ hid_t sid_buf = -1; /* ID for buffer dataspace */ @@ -3556,71 +3583,87 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, /* If there's a source datatype, set up type conversion information */ if(dt_src) { - H5T_t *dt_dst; /* Destination datatype */ - H5T_t *dt_mem; /* Memory datatype */ - size_t mem_dt_size; /* Memory datatype size */ - size_t tmp_dt_size; /* Temp. datatype size */ - size_t max_dt_size; /* Max atatype size */ - hsize_t buf_dim; /* Dimension for buffer */ - unsigned u; - - /* Create datatype ID for src datatype */ - if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") - - /* create a memory copy of the variable-length datatype */ - if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") - if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") - - /* create variable-length datatype at the destinaton file */ - if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") - if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") - if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") - - /* Set up the conversion functions */ - if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") - if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") - - /* Determine largest datatype size */ - if(0 == (max_dt_size = H5T_get_size(dt_src))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") - if(0 == (mem_dt_size = H5T_get_size(dt_mem))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") - max_dt_size = MAX(max_dt_size, mem_dt_size); - 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); - - /* Compute the number of elements per chunk */ - nelmts = 1; - for(u = 0; u < (layout_src->u.chunk.ndims - 1); u++) - nelmts *= layout_src->u.chunk.dim[u]; - - /* Create the space and set the initial extent */ - buf_dim = nelmts; - if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") - - /* Atomize */ - if((sid_buf = H5I_register(H5I_DATASPACE, buf_space)) < 0) { - H5S_close(buf_space); - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") - } /* end if */ + if(H5T_detect_class(dt_src, H5T_VLEN) > 0) { + H5T_t *dt_dst; /* Destination datatype */ + H5T_t *dt_mem; /* Memory datatype */ + size_t mem_dt_size; /* Memory datatype size */ + size_t tmp_dt_size; /* Temp. datatype size */ + size_t max_dt_size; /* Max atatype size */ + hsize_t buf_dim; /* Dimension for buffer */ + unsigned u; + + /* Create datatype ID for src datatype */ + if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") + + /* create a memory copy of the variable-length datatype */ + if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") + + /* create variable-length datatype at the destinaton file */ + if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") + if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") + + /* Set up the conversion functions */ + if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") + if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") + + /* Determine largest datatype size */ + if(0 == (max_dt_size = H5T_get_size(dt_src))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + if(0 == (mem_dt_size = H5T_get_size(dt_mem))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + max_dt_size = MAX(max_dt_size, mem_dt_size); + 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); + + /* Compute the number of elements per chunk */ + nelmts = 1; + for(u = 0; u < (layout_src->u.chunk.ndims - 1); u++) + nelmts *= layout_src->u.chunk.dim[u]; + + /* Create the space and set the initial extent */ + buf_dim = nelmts; + if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") + + /* Atomize */ + if((sid_buf = H5I_register(H5I_DATASPACE, buf_space)) < 0) { + H5S_close(buf_space); + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") + } /* end if */ - /* Set initial buffer sizes */ - buf_size = nelmts * max_dt_size; - reclaim_buf_size = nelmts * mem_dt_size; + /* Set initial buffer sizes */ + buf_size = nelmts * max_dt_size; + reclaim_buf_size = nelmts * mem_dt_size; + + /* Allocate memory for reclaim buf */ + if(NULL == (reclaim_buf = H5MM_malloc(reclaim_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk") + } /* end if */ + else { + buf_size = layout_src->u.chunk.size; + reclaim_buf_size = 0; + } /* end else */ - /* Allocate memory for reclaim buf */ - if(NULL == (reclaim_buf = H5MM_malloc(reclaim_buf_size))) + /* Allocate background memory for converting the chunk */ + if(NULL == (bkg = H5MM_malloc(buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk") + + /* Check for reference datatype and no expanding references & clear background buffer */ + if(!cpy_info->expand_ref && + ((H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) && (f_src != f_dst))) + /* Reset value to zero */ + HDmemset(bkg, 0, buf_size); } /* end if */ else { buf_size = layout_src->u.chunk.size; @@ -3634,13 +3677,15 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, /* Initialize the callback structure for the source */ HDmemset(&udata, 0, sizeof udata); udata.common.mesg = layout_src; - udata.file_dst = f_dst; + udata.file_src = f_src; udata.addr_dst = layout_dst->u.chunk.addr; udata.buf = buf; + udata.bkg = bkg; udata.buf_size = buf_size; udata.tid_src = tid_src; udata.tid_mem = tid_mem; udata.tid_dst = tid_dst; + udata.dt_src = dt_src; udata.tpath_src_mem = tpath_src_mem; udata.tpath_mem_dst = tpath_mem_dst; udata.reclaim_buf = reclaim_buf; @@ -3648,6 +3693,8 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, udata.buf_space = buf_space; udata.nelmts = nelmts; udata.pline = pline; + udata.file_dst = f_dst; + udata.cpy_info = cpy_info; /* copy the chunked data by iteration */ if(H5B_iterate(f_src, dxpl_id, H5B_ISTORE, H5D_istore_iter_copy, layout_src->u.chunk.addr, &udata) < 0) @@ -3670,9 +3717,11 @@ done: if(H5I_dec_ref(tid_mem) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") if(buf) - H5MM_xfree (buf); + H5MM_xfree(buf); + if(bkg) + H5MM_xfree(bkg); if(reclaim_buf) - H5MM_xfree (reclaim_buf); + H5MM_xfree(reclaim_buf); if(H5RC_DEC(layout_src->u.chunk.btree_shared) < 0) HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") @@ -3812,7 +3861,7 @@ H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int inden /* Allocate the shared structure */ if(H5D_istore_shared_create(f, &layout)<0) - HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info") /* Set up B-tree user data */ HDmemset(&udata, 0, sizeof udata); @@ -3822,9 +3871,9 @@ H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int inden /* Free the raw B-tree node buffer */ if(layout.u.chunk.btree_shared==NULL) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") if(H5RC_DEC(layout.u.chunk.btree_shared)<0) - HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") + HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 3022b12..b11252f 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -268,8 +268,8 @@ H5_DLL ssize_t H5D_contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[], const void *buf); -H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, - H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, hid_t dxpl_id); +H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst, + H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); /* Functions that operate on compact dataset storage */ H5_DLL ssize_t H5D_compact_readvv(const H5D_io_info_t *io_info, @@ -280,8 +280,8 @@ H5_DLL 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[], const void *buf); -H5_DLL herr_t H5D_compact_copy(const H5O_layout_t *layout_src, - H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, hid_t dxpl_id); +H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src, + H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); /* Functions that operate on indexed storage */ /* forward reference for collective-chunk IO use */ @@ -303,17 +303,18 @@ H5_DLL herr_t H5D_istore_chunkmap(const H5D_io_info_t *io_info, haddr_t chunk_ad H5_DLL herr_t H5D_istore_stats (H5D_t *dset, hbool_t headers); #endif /* H5D_ISTORE_DEBUG */ H5_DLL ssize_t H5D_istore_readvv(const H5D_io_info_t *io_info, - size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[], - size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[], - void *buf); + size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], + hsize_t chunk_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, + size_t mem_len_arr[], hsize_t mem_offset_arr[], void *buf); H5_DLL ssize_t H5D_istore_writevv(const H5D_io_info_t *io_info, - size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[], - size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[], - const void *buf); + size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], + hsize_t chunk_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, + size_t mem_len_arr[], hsize_t mem_offset_arr[], const void *buf); H5_DLL haddr_t H5D_istore_get_addr(const H5D_io_info_t *io_info, struct H5D_istore_ud1_t *_udata); H5_DLL herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, - H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_pline_t *pline, hid_t dxpl_id); + H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, + H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id); /* Functions that operate on external file list (efl) storage */ H5_DLL ssize_t H5D_efl_readvv(const H5D_io_info_t *io_info, @@ -221,8 +221,8 @@ H5F_init_interface(void) /* * Initialize the atom group for the file IDs. */ - if (H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE) - HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface") + if(H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface") /* ========== File Creation Property Class Initialization ============*/ assert(H5P_CLS_FILE_CREATE_g!=-1); @@ -2033,7 +2033,7 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") /* Check file creation property list */ if(H5P_DEFAULT == fcpl_id) @@ -2133,7 +2133,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") if ((flags & ~H5F_ACC_PUBLIC_FLAGS) || (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") if(H5P_DEFAULT == fapl_id) fapl_id = H5P_FILE_ACCESS_DEFAULT; else @@ -2618,7 +2618,7 @@ H5F_try_close(H5F_t *f) /* (Only try to flush the file if it was opened with write access) */ if(f->intent&H5F_ACC_RDWR) { /* Flush and destroy all caches */ - if (H5F_flush(f, H5AC_dxpl_id, H5F_SCOPE_LOCAL, + if(H5F_flush(f, H5AC_dxpl_id, H5F_SCOPE_LOCAL, H5F_FLUSH_INVALIDATE | H5F_FLUSH_CLOSING) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ @@ -2628,7 +2628,7 @@ H5F_try_close(H5F_t *f) * shared H5F_file_t struct. If the reference count for the H5F_file_t * struct reaches zero then destroy it also. */ - if (H5F_dest(f, H5AC_dxpl_id) < 0) + if(H5F_dest(f, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") done: @@ -2666,15 +2666,15 @@ H5Fclose(hid_t file_id) H5TRACE1("e","i",file_id); /* Check/fix arguments. */ - if (H5I_FILE != H5I_get_type(file_id)) + if(H5I_FILE != H5I_get_type(file_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") /* * Decrement reference count on atom. When it reaches zero the file will * be closed. */ - if (H5I_dec_ref (file_id)<0) - HGOTO_ERROR (H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + if(H5I_dec_ref (file_id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") done: FUNC_LEAVE_API(ret_value) @@ -2738,8 +2738,8 @@ done: HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") FUNC_LEAVE_API(ret_value) } - + /*------------------------------------------------------------------------- * Function: H5Fget_intent * @@ -2759,11 +2759,12 @@ herr_t H5Fget_intent(hid_t file_id, unsigned *intent_flags) { H5F_t * file = NULL; - herr_t ret_value=SUCCEED; + herr_t ret_value = SUCCEED; + FUNC_ENTER_API(H5Fget_intent, FAIL) H5TRACE2("e","i*Iu",file_id,intent_flags); - if (NULL==(file=H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* If no intent flags were passed in, exit quietly */ @@ -88,9 +88,9 @@ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5Lprivate.h" /* Links */ /* Local macros */ #define H5G_INIT_HEAP 8192 @@ -946,24 +946,51 @@ done: * Purpose: Copy an object (group or dataset) to destination location * within a file or cross files. PLIST_ID is a property list * which is used to pass user options and properties to the - * copy. + * copy. The name, dst_name, must not already be taken by some + * other object in the destination group. * - * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. + * H5Gcopy() will fail if the name of the destination object + * exists in the destination group. For example, + * H5Gcopy(fid_src, "/dset", fid_dst, "/dset", ...) + * will fail if "/dset" exists in the destination file + * + * OPTIONS THAT HAVE BEEN IMPLEMENTED. * H5G_COPY_SHALLOW_HIERARCHY_FLAG - * Recursively copy all objects below the group (default) - * Only immediate members. + * If this flag is specified, only immediate members of + * the group are copied. Otherwise (default), it will + * recursively copy all objects below the group * H5G_COPY_EXPAND_SOFT_LINK_FLAG - * Keep soft links as they are (default) - * Expand them into new objects - * H5G_COPY_EXPAND_EXT_LINK_FLAG - * Keep external links as they are (default) - * Expand them into new objects - * H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG - * Update only the values of object references (default) - * Copy objects that are pointed by references + * If this flag is specified, it will copy the objects + * pointed by the soft links. Otherwise (default), it + * will copy the soft link as they are * H5G_COPY_WITHOUT_ATTR_FLAG - * Copy object along with all its attributes (default) - * Copy object without copying attributes + * If this flag is specified, it will copy object without + * copying attributes. Otherwise (default), it will + * copy object along with all its attributes + * H5G_COPY_EXPAND_REFERENCE_FLAG + * 1) Copy object between two different files: + * When this flag is specified, it will copy objects that + * are pointed by the references and update the values of + * references in the destination file. Otherwise (default) + * the values of references in the destination will set to + * zero + * The current implementation does not handle references + * inside of other datatype structure. For example, if + * a member of compound datatype is reference, H5Gcopy() + * will copy that field as it is. It will not set the + * value to zero as default is used nor copy the object + * pointed by that field the flag is set + * 2) Copy object within the same file: + * This flag does not have any effect to the H5Gcopy(). + * Datasets or attributes of references are copied as they + * are, i.e. values of references of the destination object + * are the same as the values of the source object + * + * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. + * H5G_COPY_EXPAND_EXT_LINK_FLAG + * If this flag is specified, it will expand the external links + * into new objects, Otherwise (default), it will keep external + * links as they are (default) * * PROPERTIES THAT MAY APPLY TO COPY IN FUTURE * Change data layout such as chunk size @@ -979,7 +1006,7 @@ done: * const char *src_name IN: Name of the source object to be copied * hid_t dst_loc_id IN: Destination file or group identifier * const char *dst_name IN: Name of the destination object - * hid_t ocpypl_id IN: Properties which apply to the copy + * hid_t ocpypl_id IN: Properties which apply to the copy * hid_t lcpl_id IN: Properties which apply to the new hard link * * @@ -1020,6 +1047,24 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, if(!dst_name || !*dst_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + /* check if destination name already exists */ + { + H5G_name_t tmp_path; + H5O_loc_t tmp_oloc; + H5G_loc_t tmp_loc; + + /* Set up group location */ + tmp_loc.oloc = &tmp_oloc; + tmp_loc.path = &tmp_path; + H5G_loc_reset(&tmp_loc); + + /* Check if object already exists in destination */ + if(H5G_loc_find(&dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_dxpl_id) >= 0) { + H5G_name_free(&tmp_path); + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "destination object already exists") + } /* end if */ + } + /* Set up opened group location to fill in */ src_loc.oloc = &src_oloc; src_loc.path = &src_path; @@ -2336,7 +2381,6 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, H5G_loc_t new_loc; /* Group location of object copied */ hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */ unsigned cpy_option = 0; /* Copy options */ - hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_copy, FAIL); diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index aa7d582..164cf31 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -277,7 +277,6 @@ H5_DLLVAR const H5AC_class_t H5AC_SNODE[1]; * Utility functions */ H5_DLL char * H5G_normalize(const char *name); -H5_DLL H5G_t *H5G_rootof(H5F_t *f); H5_DLL const char * H5G_component(const char *name, size_t *size_p); H5_DLL herr_t H5G_traverse_term_interface(void); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index acef4a3..d03f400 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -125,6 +125,7 @@ typedef struct H5G_shared_t H5G_shared_t; */ H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc); H5_DLL struct H5O_loc_t *H5G_oloc(H5G_t *grp); +H5_DLL H5G_t *H5G_rootof(H5F_t *f); H5_DLL H5G_name_t * H5G_nameof(H5G_t *grp); H5_DLL H5F_t *H5G_fileof(H5G_t *grp); H5_DLL herr_t H5G_free(H5G_t *grp); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 52420e1..45e6f64 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -81,7 +81,7 @@ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, #define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */ #define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */ #define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */ -#define H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */ +#define H5G_COPY_EXPAND_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */ #define H5G_COPY_WITHOUT_ATTR_FLAG (0x0020u) /* Copy object without copying attributes */ #define H5G_COPY_ALL (0x003Fu) /* All object copying flags (for internal checking) */ @@ -1081,57 +1081,63 @@ done: *------------------------------------------------------------------------- */ void * -H5HG_read (H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/) +H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object/*out*/, + size_t *buf_size) { H5HG_heap_t *heap = NULL; - int i; size_t size; uint8_t *p = NULL; void *ret_value; - FUNC_ENTER_NOAPI(H5HG_read, NULL); + FUNC_ENTER_NOAPI(H5HG_read, NULL) /* Check args */ - assert (f); - assert (hobj); + HDassert(f); + HDassert(hobj); /* Load the heap */ - if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap"); + if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_GHEAP, hobj->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap") - assert (hobj->idx<heap->nused); - assert (heap->obj[hobj->idx].begin); + HDassert(hobj->idx < heap->nused); + HDassert(heap->obj[hobj->idx].begin); size = heap->obj[hobj->idx].size; - p = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR (f); - if (!object && NULL==(object = H5MM_malloc (size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDmemcpy (object, p, size); + p = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR(f); + /* Allocate a buffer for the object read in, if the user didn't give one */ + if(!object && NULL == (object = H5MM_malloc(size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDmemcpy(object, p, size); /* * Advance the heap in the CWFS list. We might have done this already * with the H5AC_protect(), but it won't hurt to do it twice. */ - if (heap->obj[0].begin) { - for (i=0; i<f->shared->ncwfs; i++) { - if (f->shared->cwfs[i]==heap) { - if (i) { - f->shared->cwfs[i] = f->shared->cwfs[i-1]; - f->shared->cwfs[i-1] = heap; - } + if(heap->obj[0].begin) { + int i; + + for(i = 0; i < f->shared->ncwfs; i++) + if(f->shared->cwfs[i] == heap) { + if(i) { + f->shared->cwfs[i] = f->shared->cwfs[i - 1]; + f->shared->cwfs[i - 1] = heap; + } /* end if */ break; - } - } - } + } /* end if */ + } /* end if */ + + /* If the caller would like to know the heap object's size, set that */ + if(buf_size) + *buf_size = size; /* Set return value */ - ret_value=object; + ret_value = object; done: - if (heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET)<0) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header"); + if(heap && H5AC_unprotect(f, dxpl_id, H5AC_GHEAP, hobj->addr, heap, H5AC__NO_FLAGS_SET)<0) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release object header") - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HG_read() */ /*------------------------------------------------------------------------- diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 2cfa773..c4c2d54 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -42,7 +42,7 @@ typedef struct H5HG_heap_t H5HG_heap_t; H5_DLL herr_t H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5HG_t *hobj/*out*/); -H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object); +H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object, size_t *buf_size/*out*/); H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust); H5_DLL herr_t H5HG_remove(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj); @@ -32,8 +32,10 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free lists */ -#include "H5MFprivate.h" /* File memory management */ +#include "H5HGprivate.h" /* Global Heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ +#include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ @@ -74,10 +76,16 @@ typedef struct { hbool_t adj_link; /* Whether to adjust links when removing messages */ } H5O_iter_ud1_t; -/* Typedef for "internal" iteration operations */ -typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx, +/* Typedef for "internal library" iteration operations */ +typedef herr_t (*H5O_lib_operator_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr, void *operator_data/*in,out*/); +/* Some syntactic sugar to make the compiler happy with two different kinds of iterator callbacks */ +typedef union { + H5O_operator_t app_op; /* Application callback for each message */ + H5O_lib_operator_t lib_op; /* Library internal callback for each message */ +} H5O_mesg_operator_t; + /* * This table contains a list of object types, descriptions, and the * functions that determine if some object is a particular type. The table @@ -221,7 +229,7 @@ static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *typ const void *mesg, unsigned flags, unsigned update_flags, unsigned * oh_flags_ptr); static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, - H5AC_protect_t prot, hbool_t internal, void *op, void *op_data, hid_t dxpl_id); + H5AC_protect_t prot, hbool_t internal, H5O_mesg_operator_t op, void *op_data, hid_t dxpl_id); static H5G_obj_t H5O_obj_type_real(H5O_t *oh); static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh); static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src, @@ -229,6 +237,8 @@ static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, v static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5O_copy_t *cpy_info); static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data); +static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, + H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); /*------------------------------------------------------------------------- @@ -293,8 +303,7 @@ done: } /* end if */ FUNC_LEAVE_API(ret_value) -} - +} /* end H5Oopen() */ /*------------------------------------------------------------------------- @@ -371,9 +380,9 @@ done: } /* end if */ FUNC_LEAVE_API(ret_value) -} - +} /* end H5Oopen_by_addr() */ + /*------------------------------------------------------------------------- * Function: H5Oclose * @@ -403,23 +412,23 @@ H5Oclose(hid_t object_id) /* Get the type of the object and open it in the correct way */ switch(H5I_get_type(object_id)) { - case(H5I_GROUP): - case(H5I_DATATYPE): - case(H5I_DATASET): - if( H5I_object(object_id) == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object"); - if (H5I_dec_ref(object_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object"); - break; + case(H5I_GROUP): + case(H5I_DATATYPE): + case(H5I_DATASET): + if(H5I_object(object_id) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") + if(H5I_dec_ref(object_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object") + break; - default: - HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)"); - break; - } + default: + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)") + break; + } /* end switch */ done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Oclose() */ /*------------------------------------------------------------------------- @@ -447,6 +456,7 @@ H5Oincr_refcount(hid_t object_id) { H5O_loc_t *oloc; int ret_value; + FUNC_ENTER_API(H5Oincr_refcount, FAIL) H5TRACE1("Is","i",object_id); @@ -458,7 +468,7 @@ H5Oincr_refcount(hid_t object_id) done: FUNC_LEAVE_API(ret_value) -} +} /* end H5O_incr_refcount() */ /*------------------------------------------------------------------------- @@ -481,7 +491,8 @@ done: * *------------------------------------------------------------------------- */ -int H5Odecr_refcount(hid_t object_id) +int +H5Odecr_refcount(hid_t object_id) { H5O_loc_t *oloc; int ret_value; @@ -496,7 +507,7 @@ int H5Odecr_refcount(hid_t object_id) done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Odecr_refcount() */ /*------------------------------------------------------------------------- @@ -1098,28 +1109,25 @@ done: * Programmer: Robb Matzke * Thursday, May 21, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ static void * -H5O_copy_real (const H5O_msg_class_t *type, const void *mesg, void *dst) +H5O_copy_real(const H5O_msg_class_t *type, const void *mesg, void *dst) { void *ret_value = NULL; - FUNC_ENTER_NOAPI_NOINIT(H5O_copy_real); + FUNC_ENTER_NOAPI_NOINIT(H5O_copy_real) /* check args */ - assert (type); - assert (type->copy); + HDassert(type); + HDassert(type->copy); - if (mesg) { - if (NULL==(ret_value=(type->copy)(mesg, dst, 0))) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy object header message"); - } + if(mesg) + if(NULL == (ret_value = (type->copy)(mesg, dst, 0))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy object header message") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_copy_real() */ @@ -1157,7 +1165,7 @@ H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id) HDassert(loc->file); HDassert(H5F_addr_defined(loc->addr)); if(adjust != 0 && 0 == (loc->file->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") /* get header */ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, @@ -1287,7 +1295,7 @@ H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type, hid_t dxpl_id) /* Load the object header */ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Loop over all messages, counting the ones of the type looked for */ for(u = acc = 0; u < oh->nmesgs; u++) @@ -1514,7 +1522,7 @@ H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, v * returning. */ if(NULL==(ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0))) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space") } /* end else */ done: @@ -1710,7 +1718,7 @@ H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, int overwrite, HDassert(0 == (flags & ~H5O_FLAG_BITS)); if(0 == (loc->file->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file") if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") @@ -1744,7 +1752,7 @@ H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, int overwrite, } else if(oh->mesg[idx].flags & H5O_FLAG_CONSTANT) { HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message") } else if(oh->mesg[idx].flags & H5O_FLAG_SHARED) { - HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message") + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message") } /* Write the information to the message */ @@ -1797,7 +1805,7 @@ H5O_protect(H5O_loc_t *loc, hid_t dxpl_id) HDassert(H5F_addr_defined(loc->addr)); if(0 == (loc->file->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file") + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file") if(NULL == (ret_value = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header") @@ -1980,7 +1988,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t HDmemset(sh_mesg,0,sizeof(H5O_shared_t)); if (NULL==orig_type->get_share) - HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable"); + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable"); if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/) < 0) { /* * If the message isn't shared then turn off the shared bit @@ -2001,7 +2009,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t /* Compute the size needed to store the message on disk */ if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large"); /* Allocate space in the object headed for the message */ if ((ret_value = H5O_alloc(f, dxpl_id, oh, orig_type, size, oh_flags_ptr)) == UFAIL) @@ -2009,7 +2017,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t /* Increment any links in message */ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared object link count"); + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared object link count"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -2485,9 +2493,10 @@ done: */ static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, - H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id) + H5O_operator_t app_op, void *op_data, hbool_t adj_link, hid_t dxpl_id) { H5O_iter_ud1_t udata; /* User data for iterator */ + H5O_mesg_operator_t op; /* Wrapper for operator */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_remove_real) @@ -2498,19 +2507,20 @@ H5O_remove_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, HDassert(type); if (0==(loc->file->intent & H5F_ACC_RDWR)) - HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file") + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file") /* Set up iterator operator data */ udata.f = loc->file; udata.dxpl_id = dxpl_id; udata.sequence = sequence; udata.nfailed = 0; - udata.op = op; + udata.op = app_op; udata.op_data = op_data; udata.adj_link = adj_link; /* Iterate over the messages, deleting appropriate one(s) */ - if(H5O_iterate_real(loc, type, H5AC_WRITE, TRUE, (void *)H5O_remove_cb, &udata, dxpl_id) < 0) + op.lib_op = H5O_remove_cb; + if(H5O_iterate_real(loc, type, H5AC_WRITE, TRUE, op, &udata, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over messages") /* Fail if we tried to remove any constant messages */ @@ -3622,11 +3632,11 @@ H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_msg_class_t *type, const void *mes /* Encode the message put it in the global heap */ if ((size = (type->raw_size)(f, mesg))>0) { if (NULL==(buf = H5MM_malloc (size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); if ((type->encode)(f, buf, mesg) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message"); if (H5HG_insert (f, dxpl_id, size, buf, hobj) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "unable to store message in global heap"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to store message in global heap"); } done: @@ -3670,7 +3680,7 @@ H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg) /* Compute the raw data size for the mesg */ if ((ret_value = (type->raw_size)(f, mesg))==0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") done: FUNC_LEAVE_NOAPI(ret_value) @@ -3709,7 +3719,7 @@ H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg) /* Compute the raw data size for the mesg */ if((ret_value = (type->raw_size)(f, mesg)) == 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") /* Adjust size for alignment, if necessary */ ret_value = H5O_ALIGN(ret_value); @@ -3760,7 +3770,7 @@ H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share) /* Compute the raw data size for the mesg */ if((ret_value = (type->get_share)(f, mesg, share)) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information") done: FUNC_LEAVE_NOAPI(ret_value) @@ -4005,7 +4015,7 @@ H5O_encode(H5F_t *f, unsigned char *buf, void *obj, unsigned type_id) /* Encode */ if ((type->encode)(f, buf, obj) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -4045,7 +4055,7 @@ H5O_decode(H5F_t *f, const unsigned char *buf, unsigned type_id) /* decode */ if((ret_value = (type->decode)(f, 0, buf))==NULL) - HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -4084,11 +4094,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op, +H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t app_op, void *op_data, hid_t dxpl_id) { const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ - herr_t ret_value; /* Return value */ + H5O_mesg_operator_t op; /* Wrapper for operator */ + herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_iterate, FAIL) @@ -4101,7 +4112,8 @@ H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op, HDassert(type); /* Call the "real" iterate routine */ - if((ret_value = H5O_iterate_real(loc, type, H5AC_READ, FALSE, (void *)op, op_data, dxpl_id)) < 0) + op.app_op = app_op; + if((ret_value = H5O_iterate_real(loc, type, H5AC_READ, FALSE, op, op_data, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages") done: @@ -4144,7 +4156,7 @@ done: */ static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect_t prot, - hbool_t internal, void *op, void *op_data, hid_t dxpl_id) + hbool_t internal, H5O_mesg_operator_t op, void *op_data, hid_t dxpl_id) { H5O_t *oh = NULL; /* Pointer to actual object header */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Start iteration with no flags set on object header */ @@ -4160,7 +4172,7 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect HDassert(loc->file); HDassert(H5F_addr_defined(loc->addr)); HDassert(type); - HDassert(op); + HDassert(op.app_op); /* Protect the object header to iterate over */ if (NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, prot))) @@ -4178,12 +4190,12 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect /* Check for making an "internal" (i.e. within the H5O package) callback */ if(internal) { /* Call the "internal" iterator callback */ - if((ret_value = ((H5O_operator_int_t)op)(idx_msg, sequence, &oh_flags, op_data)) != 0) + if((ret_value = (op.lib_op)(idx_msg, sequence, &oh_flags, op_data)) != 0) break; } /* end if */ else { /* Call the iterator callback */ - if((ret_value = ((H5O_operator_t)op)(idx_msg->native, sequence, op_data)) != 0) + if((ret_value = (op.app_op)(idx_msg->native, sequence, op_data)) != 0) break; } /* end else */ @@ -4635,7 +4647,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Create memory image for the new chunk */ if(NULL == (oh_dst->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, chunk_size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the chunk image from source to destination in memory */ /* (This copies over all the messages which don't require special @@ -4913,6 +4925,9 @@ H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* When an object is copied for the first time, increment it's link */ inc_link = TRUE; + + /* indicate that a new object is created */ + ret_value++; } /* end if */ else { /* Object has already been copied, set it's address in destination file */ @@ -5013,8 +5028,8 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, cpy_info.expand_soft_link = TRUE; if((cpy_option & H5G_COPY_EXPAND_EXT_LINK_FLAG) > 0) cpy_info.expand_ext_link = TRUE; - if((cpy_option & H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG) > 0) - cpy_info.expand_obj_ref = TRUE; + if((cpy_option & H5G_COPY_EXPAND_REFERENCE_FLAG) > 0) + cpy_info.expand_ref = TRUE; if((cpy_option & H5G_COPY_WITHOUT_ATTR_FLAG) > 0) cpy_info.copy_without_attr = TRUE; @@ -5071,7 +5086,7 @@ H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE * /* Call the debug method in the class */ if ((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth)) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message"); + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -5156,7 +5171,7 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i /* debug each message */ if (NULL==(sequence = H5MM_calloc(NELMTS(H5O_msg_class_g)*sizeof(int)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); for (i=0, mesg_total=0; i < oh->nmesgs; i++) { mesg_total += H5O_SIZEOF_MSGHDR(f) + oh->mesg[i].raw_size; HDfprintf(stream, "%*sMessage %d...\n", indent, "", i); @@ -5252,6 +5267,184 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_copy_obj_by_ref + * + * Purpose: Copy the object pointed by _src_ref. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Aug 7 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5O_copy_obj_by_ref, FAIL) + + HDassert(src_oloc); + HDassert(dst_oloc); + + /* Perform the copy, or look up existing copy */ + if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Check if a new valid object is copied to the destination */ + if(H5F_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) { + char tmp_obj_name[80]; + H5G_name_t new_path; + H5O_loc_t new_oloc; + H5G_loc_t new_loc; + + /* Set up group location for new object */ + new_loc.oloc = &new_oloc; + new_loc.path = &new_path; + H5G_loc_reset(&new_loc); + new_oloc.file = dst_oloc->file; + new_oloc.addr = dst_oloc->addr; + + /* Pick a default name for the new object */ + sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long_long)dst_oloc->addr); + + /* Create a link to the newly copied object */ + if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") + + H5G_loc_free(&new_loc); + } /* if (H5F_addr_defined(dst_oloc.addr)) */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_obj_by_ref() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_expand_ref + * + * Purpose: Copy the object pointed by _src_ref. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Aug 7 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, + H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, + H5O_copy_t *cpy_info) +{ + H5O_loc_t dst_oloc; /* Copied object object location */ + H5O_loc_t src_oloc; /* Temporary object location for source object */ + H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5O_copy_expand_ref, FAIL) + + /* Sanity checks */ + HDassert(file_src); + HDassert(_src_ref); + HDassert(file_dst); + HDassert(_dst_ref); + HDassert(ref_count); + HDassert(cpy_info); + + /* Initialize object locations */ + H5O_loc_reset(&src_oloc); + H5O_loc_reset(&dst_oloc); + src_oloc.file = file_src; + dst_oloc.file = file_dst; + + /* Set up the root group in the destination file */ + if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Copy object references */ + if(H5R_OBJECT == ref_type) { + hobj_ref_t *src_ref = (hobj_ref_t *)_src_ref; + hobj_ref_t *dst_ref = (hobj_ref_t *)_dst_ref; + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + /* Set up for the object copy for the reference */ + src_oloc.addr = src_ref[i]; + dst_oloc.addr = HADDR_UNDEF; + + /* Attempt to copy object from source to destination file */ + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Set the object reference info for the destination file */ + dst_ref[i] = dst_oloc.addr; + } /* end for */ + } /* end if */ + /* Copy region references */ + else if(H5R_DATASET_REGION == ref_type) { + hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; + hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; + uint8_t *buf; /* Buffer to store serialized selection in */ + uint8_t *p; /* Pointer to OID to store */ + H5HG_t hobjid; /* Heap object ID */ + size_t buf_size; /* Length of object in heap */ + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + /* Get the heap ID for the dataset region */ + p = (uint8_t *)(&src_ref[i]); + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(hobjid.addr)); + INT32DECODE(p, hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf = H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + + /* Get the object oid for the dataset */ + p = (uint8_t *)buf; + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); + dst_oloc.addr = HADDR_UNDEF; + + /* copy the object pointed by the ref to the destination */ + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + } /* end if */ + + /* Serialize object ID */ + p = (uint8_t *)buf; + H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); + + /* Save the serialized buffer to the destination */ + if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") + } /* end if */ + + /* Set the dataset region reference info for the destination file */ + p = (uint8_t *)(&dst_ref[i]); + H5F_addr_encode(dst_oloc.file, &p, hobjid.addr); + INT32ENCODE(p, hobjid.idx); + + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + } /* end for */ + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_expand_ref() */ + + +/*------------------------------------------------------------------------- * Function: H5O_debug * * Purpose: Prints debugging info about an object header. diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 84bb09d..1ab461d 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -132,12 +132,12 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) assert(p); if (NULL==(attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Version number */ version = *p++; if (version<H5O_ATTR_VERSION_1 || version>H5O_ATTR_VERSION_3) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message") /* Get the flags byte if we have a later version of the attribute */ if(version>H5O_ATTR_VERSION_1) @@ -162,7 +162,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) /* Decode and store the name */ if (NULL==(attr->name=H5MM_strdup((const char *)p))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(version < H5O_ATTR_VERSION_2) p += H5O_ALIGN(name_len); /* advance the memory pointer */ else @@ -174,18 +174,18 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) /* Get the shared information */ if (NULL == (shared = (H5O_MSG_SHARED->decode) (f, dxpl_id, p))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message") /* Get the actual datatype information */ if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_MSG_DTYPE, NULL))==NULL) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype") /* Free the shared information */ H5O_free_real(H5O_MSG_SHARED, shared); } /* end if */ else { if((attr->dt=(H5O_MSG_DTYPE->decode)(f,dxpl_id,p))==NULL) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype") } /* end else */ if(version < H5O_ATTR_VERSION_2) p += H5O_ALIGN(attr->dt_size); @@ -194,10 +194,10 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) /* decode the attribute dataspace */ if (NULL==(attr->ds = H5FL_CALLOC(H5S_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if((extent=(H5O_MSG_SDSPACE->decode)(f,dxpl_id,p))==NULL) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace") /* Copy the extent information */ HDmemcpy(&(attr->ds->extent),extent, sizeof(H5S_extent_t)); @@ -207,7 +207,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) /* Default to entire dataspace being selected */ if(H5S_select_all(attr->ds,0)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection") if(version < H5O_ATTR_VERSION_2) p += H5O_ALIGN(attr->ds_size); @@ -220,7 +220,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) /* Go get the data */ if(attr->data_size) { if (NULL==(attr->data = H5FL_BLK_MALLOC(attr_buf, attr->data_size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemcpy(attr->data,p,attr->data_size); } @@ -342,16 +342,16 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) /* Get shared message information from datatype */ if ((H5O_MSG_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype") /* Encode shared message information for datatype */ if((H5O_MSG_SHARED->encode)(f,p,&sh_mesg)<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype") } /* end if */ else { /* Encode datatype information */ if((H5O_MSG_DTYPE->encode)(f,p,attr->dt)<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype") } /* end else */ if(version < H5O_ATTR_VERSION_2) { HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size); @@ -362,7 +362,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) /* encode the attribute dataspace */ if((H5O_MSG_SDSPACE->encode)(f,p,&(attr->ds->extent))<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace") if(version < H5O_ATTR_VERSION_2) { HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); p += H5O_ALIGN(attr->ds_size); @@ -409,7 +409,7 @@ H5O_attr_copy(const void *_src, void *_dst, unsigned update_flags) /* copy */ if (NULL == (ret_value = H5A_copy(_dst,src,update_flags))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "can't copy attribute"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "can't copy attribute") done: FUNC_LEAVE_NOAPI(ret_value); @@ -589,7 +589,7 @@ H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_l /* Decrement the reference count on the shared datatype, if requested */ if(adj_link) if(H5T_link(attr->dt, -1, dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") } /* end if */ done: @@ -628,7 +628,7 @@ H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) if(H5T_committed(attr->dt)) { /* Increment the reference count on the shared datatype */ if(H5T_link(attr->dt,1,dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count"); + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") } /* end if */ done: @@ -685,13 +685,14 @@ H5O_attr_pre_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *typ * November 1, 2005 * * Modifications: Peter Cao - * December 17, 2005 - * Datatype conversion for variable length datatype + * December 17, 2005: datatype conversion for variable length datatype + * August 1, 2006: fix reference datatype + * * *------------------------------------------------------------------------- */ static void * -H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, +H5O_attr_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata) { H5A_t *attr_src = (H5A_t *)native_src; @@ -808,7 +809,7 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, if(NULL == (dt_mem = H5T_copy(attr_src->dt, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy") if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register memory datatype") /* create variable-length datatype at the destinaton file */ if((tid_dst = H5I_register(H5I_DATATYPE, attr_dst->dt)) < 0) @@ -874,12 +875,32 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data") - } /* type conversion */ + } /* end if */ + else if((H5T_get_class(attr_src->dt, FALSE) == H5T_REFERENCE) && (file_src != file_dst)) { + /* copy object pointed by reference. The current implementation does not deal with + nested reference such as reference in a compound structure */ + + /* Check for expanding references */ + if(cpy_info->expand_ref) { + size_t ref_count; + + /* Determine # of reference elements to copy */ + ref_count = attr_dst->data_size / attr_dst->dt_size; + + /* Copy objects referenced in source buffer to destination file and set destination elements */ + if(H5O_copy_expand_ref(file_src, attr_src->data, dxpl_id, + file_dst, attr_dst->data, ref_count, H5T_get_ref_type(attr_src->dt), cpy_info) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy reference attribute") + } /* end if */ + else + /* Reset value to zero */ + HDmemset(attr_dst->data, 0, attr_dst->data_size); + } /* end if */ else { HDassert(attr_dst->data_size == attr_src->data_size); HDmemcpy(attr_dst->data, attr_src->data, attr_src->data_size); } /* end else */ - } /* end if */ + } /* end if(attr_src->data) */ /* Indicate that the fill values aren't to be written out */ attr_dst->initialized = TRUE; @@ -980,7 +1001,7 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in /* Get shared message information from datatype */ if ((H5O_MSG_DTYPE->get_share)(f, mesg->dt, &sh_mesg/*out*/)<0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't retrieve shared message information"); + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't retrieve shared message information") debug=H5O_MSG_SHARED->debug; dt_mesg=&sh_mesg; diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 728ac6e..3ef502b 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -442,40 +442,40 @@ done: herr_t H5O_dest(H5F_t UNUSED *f, H5O_t *oh) { - unsigned i; + unsigned u; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest) /* check args */ - assert(oh); + HDassert(oh); /* Verify that node is clean */ - assert (oh->cache_info.is_dirty==FALSE); + HDassert(oh->cache_info.is_dirty == FALSE); /* destroy chunks */ - for (i = 0; i < oh->nchunks; i++) { + for(u = 0; u < oh->nchunks; u++) { /* Verify that chunk is clean */ - assert (oh->chunk[i].dirty==0); + HDassert(oh->chunk[u].dirty == 0); - oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image); - } + oh->chunk[u].image = H5FL_BLK_FREE(chunk_image, oh->chunk[u].image); + } /* end for */ if(oh->chunk) - oh->chunk = H5FL_SEQ_FREE(H5O_chunk_t,oh->chunk); + oh->chunk = H5FL_SEQ_FREE(H5O_chunk_t, oh->chunk); /* destroy messages */ - for (i = 0; i < oh->nmesgs; i++) { + for(u = 0; u < oh->nmesgs; u++) { /* Verify that message is clean */ - assert (oh->mesg[i].dirty==0); + HDassert(oh->mesg[u].dirty == 0); - H5O_free_mesg(&oh->mesg[i]); - } + H5O_free_mesg(&oh->mesg[u]); + } /* end for */ if(oh->mesg) - oh->mesg = H5FL_SEQ_FREE(H5O_mesg_t,oh->mesg); + oh->mesg = H5FL_SEQ_FREE(H5O_mesg_t, oh->mesg); /* destroy object header */ H5FL_FREE(H5O_t,oh); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_dest() */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index b5b441a..afe6e27 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -1236,7 +1236,8 @@ H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, * of the datatype if it's a vlen datatype) */ if(udata) { - if(H5T_detect_class(dt_src, H5T_VLEN) > 0) { + if((H5T_detect_class(dt_src, H5T_VLEN) > 0) || + (H5T_get_class(dt_src, FALSE) == H5T_REFERENCE)) { /* Create a memory copy of the variable-length datatype */ if(NULL == (udata->src_dtype = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") diff --git a/src/H5Olayout.c b/src/H5Olayout.c index ff7f085..21c2820 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -622,7 +622,7 @@ done: */ static void * H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, - H5O_copy_t UNUSED *cpy_info, void *_udata) + H5O_copy_t *cpy_info, void *_udata) { H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src; @@ -650,20 +650,20 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxp HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset") /* copy compact raw data */ - if(H5D_compact_copy(layout_src, file_dst, layout_dst, udata->src_dtype, dxpl_id) < 0) + if(H5D_compact_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, dxpl_id) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage") layout_dst->u.compact.dirty = TRUE; /* Freed by copy routine */ udata->src_dtype = NULL; - } + } /* end if */ break; case H5D_CONTIGUOUS: if(H5F_addr_defined(layout_src->u.contig.addr)) { /* create contig layout */ - if(H5D_contig_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, dxpl_id) < 0) + if(H5D_contig_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, dxpl_id) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy contiguous storage") /* Freed by copy routine */ @@ -677,8 +677,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxp layout_dst->u.chunk.addr = HADDR_UNDEF; /* create chunked layout */ - if(H5D_istore_copy(file_src, layout_src, file_dst, layout_dst, - udata->src_dtype, udata->src_pline, dxpl_id) < 0) + if(H5D_istore_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, udata->src_pline, dxpl_id) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage") /* Freed by copy routine */ @@ -691,7 +690,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxp } /* end switch */ /* Set return value */ - ret_value=layout_dst; + ret_value = layout_dst; done: if(!ret_value) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 4a6a0c5..10b6c31 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -74,7 +74,7 @@ typedef struct H5O_copy_t { hbool_t copy_shallow; /* Flag to perform shallow hierarchy copy */ hbool_t expand_soft_link; /* Flag to expand soft links */ hbool_t expand_ext_link; /* Flag to expand external links */ - hbool_t expand_obj_ref; /* Flag to expand object references */ + hbool_t expand_ref; /* Flag to expand object references */ hbool_t copy_without_attr; /* Flag to not copy attributes */ int curr_depth; /* Current depth in hierarchy copied */ int max_depth; /* Maximum depth in hierarchy to copy */ @@ -371,6 +371,9 @@ H5_DLL herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*o H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth); H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); +H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, + H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, + H5O_copy_t *cpy_info); H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth); diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index 23000f1..717ed38 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -37,7 +37,7 @@ * H5G_COPY_SHALLOW_HIERARCHY_FLAG -- Copy only immediate members * H5G_COPY_EXPAND_SOFT_LINK_FLAG -- Expand soft links into new objects/ * H5G_COPY_EXPAND_EXT_LINK_FLAG -- Expand external links into new objects - * H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG -- Copy objects that are pointed by references + * H5G_COPY_EXPAND_REFERENCE_FLAG -- Copy objects that are pointed by references * H5G_COPY_WITHOUT_ATTR_FLAG -- Copy object without copying attributes * * Return: Non-negative on success/Negative on failure @@ -35,9 +35,9 @@ /* Static functions */ static herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id); -static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref); -static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref); -static H5G_obj_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref); +static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref); +static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref); +static H5G_obj_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref); /*-------------------------------------------------------------------------- @@ -334,12 +334,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static hid_t -H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref) +H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref) { H5O_loc_t oloc; /* Object location */ H5G_name_t path; /* Path of object */ H5G_loc_t loc; /* Group location */ - uint8_t *p; /* Pointer to OID to store */ + const uint8_t *p; /* Pointer to OID to store */ int oid_type; /* type of object being dereferenced */ hid_t ret_value; @@ -355,31 +355,27 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref) switch(ref_type) { case H5R_OBJECT: - { - hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Only object references currently supported */ - - oloc.addr = *ref; - } /* end case */ - break; + oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + break; case H5R_DATASET_REGION: { - hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + const hdset_reg_ref_t *ref = (const hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ H5HG_t hobjid; /* Heap object ID */ uint8_t *buf; /* Buffer to store serialized selection in */ /* Get the heap ID for the dataset region */ - p = (uint8_t *)ref; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr)); + p = (const uint8_t *)ref; + H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); INT32DECODE(p, hobjid.idx); /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL) + if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") /* Get the object oid for the dataset */ - p = (uint8_t *)buf; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr)); + p = buf; + H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Free the buffer allocated in H5HG_read() */ H5MM_xfree(buf); @@ -486,7 +482,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5Rdereference(hid_t id, H5R_type_t ref_type, void *_ref) +H5Rdereference(hid_t id, H5R_type_t ref_type, const void *_ref) { H5G_loc_t loc; /* Group location */ H5F_t *file = NULL; /* File object */ @@ -537,13 +533,13 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static H5S_t * -H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref) +H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref) { H5O_loc_t oloc; /* Object location */ - uint8_t *p; /* Pointer to OID to store */ - hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ + const uint8_t *p; /* Pointer to OID to store */ + const hdset_reg_ref_t *ref = (const hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + H5HG_t hobjid; /* Heap object ID */ + uint8_t *buf = NULL; /* Buffer to store serialized selection in */ H5S_t *ret_value; FUNC_ENTER_NOAPI_NOINIT(H5R_get_region) @@ -556,17 +552,17 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref) oloc.file = file; /* Get the heap ID for the dataset region */ - p = (uint8_t *)ref; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr)); - INT32DECODE(p,hobjid.idx); + p = (const uint8_t *)ref; + H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); + INT32DECODE(p, hobjid.idx); /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL) + if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information") /* Get the object oid for the dataset */ - p = (uint8_t *)buf; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr)); + p = buf; + H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Open and copy the dataset's dataspace */ if((ret_value = H5S_read(&oloc, dxpl_id)) == NULL) @@ -576,10 +572,11 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref) if(H5S_select_deserialize(ret_value, p) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") +done: /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); + if(buf) + H5MM_xfree(buf); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5R_get_region() */ @@ -608,7 +605,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5Rget_region(hid_t id, H5R_type_t ref_type, void *ref) +H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) { H5G_loc_t loc; /* Object's group location */ H5S_t *space = NULL; /* Dataspace object */ @@ -661,10 +658,10 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static H5G_obj_t -H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref) +H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref) { H5O_loc_t oloc; /* Object location */ - uint8_t *p; /* Pointer to OID to store */ + const uint8_t *p; /* Pointer to OID to store */ H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5R_get_obj_type) @@ -678,32 +675,28 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref) switch(ref_type) { case H5R_OBJECT: - { - hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Only object references currently supported */ - /* Get the object oid */ - oloc.addr = *ref; - } /* end case */ - break; + oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + break; case H5R_DATASET_REGION: { - hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + const hdset_reg_ref_t *ref = (const hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ H5HG_t hobjid; /* Heap object ID */ uint8_t *buf; /* Buffer to store serialized selection in */ /* Get the heap ID for the dataset region */ - p = (uint8_t *)ref; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr)); + p = (const uint8_t *)ref; + H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); INT32DECODE(p, hobjid.idx); /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL) + if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5G_UNKNOWN, "Unable to read dataset region information") /* Get the object oid for the dataset */ - p = (uint8_t *)buf; - H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr)); + p = buf; + H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Free the buffer allocated in H5HG_read() */ H5MM_xfree(buf); @@ -725,7 +718,7 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5G_UNKNOWN, "dereferencing deleted object") /* Get the OID type */ - ret_value = H5O_obj_type(&oloc,dxpl_id); + ret_value = H5O_obj_type(&oloc, dxpl_id); done: FUNC_LEAVE_NOAPI(ret_value) @@ -756,7 +749,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ H5G_obj_t -H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *ref) +H5Rget_obj_type(hid_t id, H5R_type_t ref_type, const void *ref) { H5G_loc_t loc; /* Object location */ H5G_obj_t ret_value; diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index efffb8c..fdc1d27 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -60,7 +60,7 @@ typedef haddr_t hobj_ref_t; /* Needs to be large enough to store largest haddr_t typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE];/* Buffer to store heap ID and index */ /* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) plus an int */ -/* Publicly visible datastructures */ +/* Publicly visible data structures */ #ifdef __cplusplus extern "C" { @@ -69,9 +69,9 @@ extern "C" { /* Functions in H5R.c */ H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); -H5_DLL hid_t H5Rdereference(hid_t dataset, H5R_type_t ref_type, void *ref); -H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, void *ref); -H5_DLL H5G_obj_t H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *_ref); +H5_DLL hid_t H5Rdereference(hid_t dataset, H5R_type_t ref_type, const void *ref); +H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); +H5_DLL H5G_obj_t H5Rget_obj_type(hid_t id, H5R_type_t ref_type, const void *_ref); #ifdef __cplusplus } diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 1cb229a..50c73fb 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -2875,7 +2875,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } H5F_addr_decode(dst->shared->u.vlen.f, (const uint8_t **)&tmp, &(bg_hobjid.addr)); INT32DECODE(tmp, bg_hobjid.idx); - if(H5HG_read(dst->shared->u.vlen.f,dxpl_id,&bg_hobjid,tmp_buf)==NULL) + if(H5HG_read(dst->shared->u.vlen.f,dxpl_id,&bg_hobjid,tmp_buf, NULL)==NULL) HGOTO_ERROR (H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer"); } /* end if */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 29e4ec8..5a8bd18 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -830,7 +830,7 @@ H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t UNUSED /* 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)==NULL) HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read VL information") } /* end if */ |