From 6ffdd4f2d6940de217152fd251ee748622a3241b Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 27 Sep 2019 12:39:31 -0500 Subject: Merge pull request #1934 in HDFFV/hdf5 from ~VCHOI/my_third_fork:bugfix/HDFFV-10585-investigate-slowness-of-regular to develop * commit '7924eee0e5ee0745b784c635042b8633886fb799': (1) Address the feedback from the PR review (2) Add release notes Fix for HDFFV-10585 investigate hyperslab slowness: 1) Improve hyperslab performance when doing I/O from 1-d disjoint file dataspace to 1-d contiguous memory dataspace. 2) Move coding in H5D__chunk_io_init() that is constructing the chunk mappings to a separate routine. --- release_docs/RELEASE.txt | 13 +++ src/H5Dchunk.c | 204 ++++++++++++++++++++++++++++++++++++++--------- test/tselect.c | 162 +++++++++++++++++++++++++++++++++++++ 3 files changed, 343 insertions(+), 36 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 9c91a0b..ba9af1b 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -362,6 +362,19 @@ Bug Fixes since HDF5-1.10.3 release Library ------- + - Fixed the slowness of regular hyperslab selection in a chunked dataset + + It was reported that the selection of every 10th element from a 20G + chunked dataset was extremely slow and sometimes could hang the system. + The problem was due to the iteration and the building of the span tree + for all the selected elements in file space. + + As the selected elements are going to a 1-d contiguous single block + memory space, the problem was fixed by building regular hyperslab selections + in memory space for the selected elements in file space. + + (VC - 2019/09/26, HDFFV-10585) + - Fixed a bug caused by bad tag value when condensing object header messages diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index e3bbd59..ed82b3b 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -254,6 +254,8 @@ static herr_t H5D__chunk_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id); static herr_t H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm); +static herr_t H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, H5D_chunk_map_t *fm); static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm); @@ -297,6 +299,9 @@ static herr_t H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info); static herr_t H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info); + +static herr_t H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm); + static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm); static herr_t H5D__chunk_file_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords, void *fm); @@ -1095,7 +1100,6 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf H5D_chunk_map_t *fm) { const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */ - const H5T_t *mem_type = type_info->mem_type; /* Local pointer to memory datatype */ H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */ hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */ htri_t file_space_normalized = FALSE; /* File dataspace was normalized */ @@ -1156,13 +1160,54 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf fm->file_space = file_space; fm->mem_space = mem_space; + if(H5D__chunk_io_init_selections(io_info, type_info, fm) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file and memory chunk selections") + +done: + /* Reset the global dataspace info */ + fm->file_space = NULL; + fm->mem_space = NULL; + + if(file_space_normalized == TRUE) + if(H5S_hyper_denormalize_offset((H5S_t *)file_space, old_offset) < 0) /* (Casting away const OK -QAK) */ + HDONE_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't denormalize selection") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__chunk_io_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_io_init_selections + * + * Purpose: Initialize the chunk mappings + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, March 20, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm) +{ + const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */ + const H5T_t *mem_type = type_info->mem_type; /* Local pointer to memory datatype */ + H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */ + H5T_t *file_type = NULL; /* Temporary copy of file datatype for iteration */ + hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ + char bogus; /* "bogus" buffer to pass to selection iterator */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Special case for only one element in selection */ /* (usually appending a record) */ - if(nelmts == 1 + if(fm->nelmts == 1 #ifdef H5_HAVE_PARALLEL && !(io_info->using_mpi_vfd) #endif /* H5_HAVE_PARALLEL */ - && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(file_space)) { + && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(fm->file_space)) { /* Initialize skip list for chunk selections */ fm->sel_chunks = NULL; fm->use_single = TRUE; @@ -1170,7 +1215,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf /* Initialize single chunk dataspace */ if(NULL == dataset->shared->cache.chunk.single_space) { /* Make a copy of the dataspace for the dataset */ - if((dataset->shared->cache.chunk.single_space = H5S_copy(file_space, TRUE, FALSE)) == NULL) + if((dataset->shared->cache.chunk.single_space = H5S_copy(fm->file_space, TRUE, FALSE)) == NULL) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space") /* Resize chunk's dataspace dimensions to size of chunk */ @@ -1212,9 +1257,9 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf fm->use_single = FALSE; /* Get type of selection on disk & in memory */ - if((fm->fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE) + if((fm->fsel_type = H5S_GET_SELECT_TYPE(fm->file_space)) < H5S_SEL_NONE) HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") - if((fm->msel_type = H5S_GET_SELECT_TYPE(mem_space)) < H5S_SEL_NONE) + if((fm->msel_type = H5S_GET_SELECT_TYPE(fm->mem_space)) < H5S_SEL_NONE) HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") /* If the selection is NONE or POINTS, set the flag to FALSE */ @@ -1223,22 +1268,22 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf else sel_hyper_flag = TRUE; - /* Check if file selection is a not a hyperslab selection */ - if(sel_hyper_flag) { - /* Build the file selection for each chunk */ - if(H5S_SEL_ALL == fm->fsel_type) { - if(H5D__create_chunk_file_map_all(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + /* Check if file selection is a not a hyperslab selection */ + if(sel_hyper_flag) { + /* Build the file selection for each chunk */ + if(H5S_SEL_ALL == fm->fsel_type) { + if(H5D__create_chunk_file_map_all(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + } /* end if */ + else { + /* Sanity check */ + HDassert(fm->fsel_type == H5S_SEL_HYPERSLABS); + + if(H5D__create_chunk_file_map_hyper(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + } /* end else */ } /* end if */ else { - /* Sanity check */ - HDassert(fm->fsel_type == H5S_SEL_HYPERSLABS); - - if(H5D__create_chunk_file_map_hyper(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - } /* end else */ - } /* end if */ - else { H5S_sel_iter_op_t iter_op; /* Operator for iteration */ H5D_chunk_file_iter_ud_t udata; /* User data for iteration */ @@ -1256,7 +1301,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf iter_op.u.lib_op = H5D__chunk_file_cb; /* Spaces might not be the same shape, iterate over the file selection directly */ - if(H5S_select_iterate(&bogus, file_type, file_space, &iter_op, &udata) < 0) + if(H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") /* Reset "last chunk" info */ @@ -1265,7 +1310,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf } /* end else */ /* Build the memory selection for each chunk */ - if(sel_hyper_flag && H5S_SELECT_SHAPE_SAME(file_space, mem_space) == TRUE) { + if(sel_hyper_flag && H5S_SELECT_SHAPE_SAME(fm->file_space, fm->mem_space) == TRUE) { /* Reset chunk template information */ fm->mchunk_tmpl = NULL; @@ -1275,12 +1320,19 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf if(H5D__create_chunk_mem_map_hyper(fm) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") } /* end if */ - else { + else if(sel_hyper_flag && + fm->f_ndims == 1 && fm->m_ndims == 1 && + H5S_SELECT_IS_REGULAR(fm->mem_space) && H5S_SELECT_IS_SINGLE(fm->mem_space)) { + + if(H5D__create_chunk_mem_map_1d(fm) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + + } else { H5S_sel_iter_op_t iter_op; /* Operator for iteration */ size_t elmt_size; /* Memory datatype size */ /* Make a copy of equivalent memory space */ - if((tmp_mspace = H5S_copy(mem_space, TRUE, FALSE)) == NULL) + if((tmp_mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") /* De-select the mem space copy */ @@ -1291,14 +1343,14 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf fm->mchunk_tmpl = tmp_mspace; /* Create temporary datatypes for selection iteration */ - if(!file_type) - if(NULL == (file_type = H5T_copy(dataset->shared->type, H5T_COPY_ALL))) + if(!file_type) + if(NULL == (file_type = H5T_copy(dataset->shared->type, H5T_COPY_ALL))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype") /* Create selection iterator for memory selection */ if(0 == (elmt_size = H5T_get_size(mem_type))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid") - if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size, 0) < 0) + if(H5S_select_iter_init(&(fm->mem_iter), fm->mem_space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -1306,7 +1358,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf iter_op.u.lib_op = H5D__chunk_mem_cb; /* Spaces aren't the same shape, iterate over the memory selection directly */ - if(H5S_select_iterate(&bogus, file_type, file_space, &iter_op, fm) < 0) + if(H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, fm) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") } /* end else */ } /* end else */ @@ -1323,20 +1375,13 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping") } /* end if */ - /* Reset the global dataspace info */ - fm->file_space = NULL; - fm->mem_space = NULL; - if(iter_init && H5S_SELECT_ITER_RELEASE(&(fm->mem_iter)) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") if(file_type && (H5T_close_real(file_type) < 0)) HDONE_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Can't free temporary datatype") - if(file_space_normalized == TRUE) - if(H5S_hyper_denormalize_offset((H5S_t *)file_space, old_offset) < 0) /* (Casting away const OK -QAK) */ - HDONE_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't denormalize selection") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_io_init() */ +} /* end H5D__chunk_io_init_selections() */ /*------------------------------------------------------------------------- @@ -2075,6 +2120,93 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__create_chunk_mem_map_hyper() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__create_mem_map_1d + * + * Purpose: Create all chunk selections for 1-dimensional regular memory space + * that has only one single block in the selection + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Sept 18, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm) +{ + H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ + H5SL_node_t *curr_node; /* Current node in skip list */ + hsize_t file_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ + hsize_t file_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ + hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ + hsize_t mem_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ + hssize_t adjust[H5S_MAX_RANK]; /* Adjustment to make to all file chunks */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(fm->f_ndims>0); + + /* Check for all I/O going to a single chunk */ + if(H5SL_count(fm->sel_chunks)==1) { + /* Get the node */ + curr_node = H5SL_first(fm->sel_chunks); + + /* Get pointer to chunk's information */ + chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); + HDassert(chunk_info); + + /* Just point at the memory dataspace & selection */ + /* (Casting away const OK -QAK) */ + chunk_info->mspace = (H5S_t *)fm->mem_space; + + /* Indicate that the chunk's memory space is shared */ + chunk_info->mspace_shared = TRUE; + } /* end if */ + else { + HDassert(fm->m_ndims == 1); + hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ + hsize_t mem_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ + + if(H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") + + /* Iterate over each chunk in the chunk list */ + curr_node = H5SL_first(fm->sel_chunks); + while(curr_node) { + hssize_t schunk_points; /* Number of elements in chunk selection */ + hsize_t tmp_count = 1; + + /* Get pointer to chunk's information */ + chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); + HDassert(chunk_info); + + /* Copy the memory dataspace */ + if((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") + + schunk_points = H5S_GET_SELECT_NPOINTS(chunk_info->fspace); + + if(H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, mem_sel_start, NULL, &tmp_count, &schunk_points) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection") + + mem_sel_start[0] += schunk_points; + + /* Get the next chunk node in the skip list */ + curr_node = H5SL_next(curr_node); + } /* end while */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__create_chunk_mem_map_1d() */ + /*------------------------------------------------------------------------- * Function: H5D__chunk_file_cb diff --git a/test/tselect.c b/test/tselect.c index 9cfa922..91da4c4 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -177,6 +177,13 @@ #define SEL_ITER_MAX_SEQ 256 +/* Defines for test_hyper_io_1d() */ +#define DNAME "DSET_1D" +#define RANK 1 +#define NUMCHUNKS 3 +#define CHUNKSZ 20 +#define NUM_ELEMENTS NUMCHUNKS * CHUNKSZ + /* Location comparison function */ static int compare_size_t(const void *s1, const void *s2); @@ -15316,7 +15323,158 @@ test_select_intersect_block(void) CHECK(ret, FAIL, "H5Sclose"); } /* test_select_intersect_block() */ + +/**************************************************************** +** +** test_hyper_io_1d(): +** Test to verify all the selected 10th element in the 1-d file +** dataspace is read correctly into the 1-d contiguous memory space. +** This is modeled after the test scenario described in HDFFV-10585 +** that demonstrated the hyperslab slowness. A fix to speed up +** performance is in place to handle the special case for 1-d disjoint +** file dataspace into 1-d single block contiguous memory space. +** +****************************************************************/ +static void +test_hyper_io_1d(void) +{ + hid_t fid; /* File ID */ + hid_t did; /* Dataset ID */ + hid_t sid, mid; /* Dataspace IDs */ + hid_t dcpl; /* Dataset creation property list ID */ + hsize_t dims[1], maxdims[1], dimsm[1]; /* Dataset dimension sizes */ + hsize_t chunk_dims[1]; /* Chunk dimension size */ + hsize_t offset[1]; /* Starting offset for hyperslab */ + hsize_t stride[1]; /* Distance between blocks in the hyperslab selection */ + hsize_t count[1]; /* # of blocks in the the hyperslab selection */ + hsize_t block[1]; /* Size of block in the hyperslab selection */ + unsigned int wdata[CHUNKSZ]; /* Data to be written */ + unsigned int rdata[NUM_ELEMENTS/10]; /* Data to be read */ + herr_t ret; /* Generic return value */ + unsigned i; /* Local index variable */ + + /* Output message about test being performed */ + MESSAGE(6, ("Testing Hyperslab I/O for 1-d single block memory space\n")); + + for (i = 0; i < CHUNKSZ; i++) + wdata[i] = i; + + /* Create the file file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); + /* Create file dataspace */ + dims[0] = CHUNKSZ; + maxdims[0] = H5S_UNLIMITED; + sid = H5Screate_simple(RANK, dims, maxdims); + CHECK(sid, H5I_INVALID_HID, "H5Pcreate"); + + /* Create memory dataspace */ + dimsm[0] = CHUNKSZ; + mid = H5Screate_simple(RANK, dimsm, NULL); + CHECK(mid, H5I_INVALID_HID, "H5Pcreate"); + + /* Set up to create a chunked dataset */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, H5I_INVALID_HID, "H5Pcreate"); + + chunk_dims[0] = CHUNKSZ; + ret = H5Pset_chunk(dcpl, RANK, chunk_dims); + CHECK(ret, FAIL, "H5Pset_chunk"); + + /* Create a chunked dataset */ + did = H5Dcreate2(fid, DNAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); + + /* Set up hyperslab selection for file dataspace */ + offset[0] = 0; + stride[0] = 1; + count[0] = 1; + block[0] = CHUNKSZ; + + /* Write to each chunk in the dataset */ + for (i = 0; i < NUMCHUNKS; i++) { + /* Set the hyperslab selection */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Write to the dataset */ + ret = H5Dwrite(did, H5T_NATIVE_INT, mid, sid, H5P_DEFAULT, wdata); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Extend the dataset's dataspace */ + if(i < (NUMCHUNKS - 1)) { + offset[0] = offset[0] + CHUNKSZ; + dims[0] = dims[0] + CHUNKSZ; + ret = H5Dset_extent(did, dims); + CHECK(ret, FAIL, "H5Dset_extent"); + + /* Get the dataset's current dataspace */ + sid = H5Dget_space(did); + CHECK(sid, H5I_INVALID_HID, "H5Dget_space"); + } + } + + /* Closing */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(mid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Open the file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fopen"); + + /* Open the dataset */ + did = H5Dopen(fid, DNAME, H5P_DEFAULT); + CHECK(did, H5I_INVALID_HID, "H5Dopen"); + + /* Set up to read every 10th element in file dataspace */ + offset[0] = 1; + stride[0] = 10; + count[0] = NUM_ELEMENTS/10; + block[0] = 1; + + /* Get the dataset's dataspace */ + sid = H5Dget_space(did); + CHECK(sid, H5I_INVALID_HID, "H5Pcreate"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Set up contiguous memory dataspace for the selected elements */ + dimsm[0] = count[0]; + mid = H5Screate_simple(RANK, dimsm, NULL); + CHECK(mid, H5I_INVALID_HID, "H5Screate"); + + /* Read all the selected 10th elements in the dataset into "rdata" */ + ret = H5Dread(did, H5T_NATIVE_INT, mid, sid, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify data read is correct */ + for(i = 0; i < 6; i += 2) { + VERIFY(rdata[i], 1, "H5Dread\n"); + VERIFY(rdata[i+1], 11, "H5Dread\n"); + } + + /* Closing */ + ret = H5Sclose(mid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + +} /* test_hyper_io_1d() */ + + /**************************************************************** ** ** test_select(): Main H5S selection testing routine. @@ -15499,6 +15657,10 @@ test_select(void) /* Test selection intersection with block */ test_select_intersect_block(); + + /* Test reading of 1-d disjoint file space to 1-d single block memory space */ + test_hyper_io_1d(); + } /* test_select() */ -- cgit v0.12 From bffa18b684de83359f4ad25e11f4ad0b15f34040 Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Sat, 28 Sep 2019 14:33:37 -0500 Subject: Merge pull request #1957 in HDFFV/hdf5 from ~LRKNOX/hdf5_lrk:develop to develop * commit '3fb711e0ff2516cba7a0cb34f2d8ca38241b06a7': Number of arguments requires H5Dopen2. --- test/tselect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tselect.c b/test/tselect.c index 91da4c4..27bc36b 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -15432,7 +15432,7 @@ test_hyper_io_1d(void) CHECK(fid, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ - did = H5Dopen(fid, DNAME, H5P_DEFAULT); + did = H5Dopen2(fid, DNAME, H5P_DEFAULT); CHECK(did, H5I_INVALID_HID, "H5Dopen"); /* Set up to read every 10th element in file dataspace */ -- cgit v0.12 From ff490b4a69029fa75a39258bbab67784e9743de9 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 21 Aug 2019 13:14:06 -0500 Subject: Add 'blob' callbacks to VOL, along with a native implementation to store them in the global heap, and changed the VL datatype conversion code to use blobs. Move encode/decode of sequence lengths into VL datatype callbacks, from native VOL blob routines. --- MANIFEST | 1 + src/CMakeLists.txt | 1 + src/H5Dio.c | 36 +- src/H5Fint.c | 17 +- src/H5Fpkg.h | 4 +- src/H5Fprivate.h | 12 +- src/H5Fquery.c | 25 ++ src/H5Odtype.c | 30 +- src/H5Tconv.c | 74 +++-- src/H5Tpkg.h | 39 ++- src/H5Tvlen.c | 757 +++++++++++++++++++++++-------------------- src/H5VLcallback.c | 119 +++++++ src/H5VLconnector.h | 22 +- src/H5VLconnector_passthru.h | 6 +- src/H5VLint.c | 29 +- src/H5VLnative.c | 10 +- src/H5VLnative.h | 3 + src/H5VLnative_blob.c | 260 +++++++++++++++ src/H5VLnative_private.h | 29 +- src/H5VLpassthru.c | 14 +- src/H5VLprivate.h | 8 + src/Makefile.am | 5 +- 22 files changed, 1033 insertions(+), 468 deletions(-) create mode 100644 src/H5VLnative_blob.c diff --git a/MANIFEST b/MANIFEST index 723bae7..5e7caff 100644 --- a/MANIFEST +++ b/MANIFEST @@ -925,6 +925,7 @@ ./src/H5VLnative.c ./src/H5VLnative.h ./src/H5VLnative_attr.c +./src/H5VLnative_blob.c ./src/H5VLnative_dataset.c ./src/H5VLnative_datatype.c ./src/H5VLnative_file.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6df8af3..b50fa71 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -649,6 +649,7 @@ set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VLint.c ${HDF5_SRC_DIR}/H5VLnative.c ${HDF5_SRC_DIR}/H5VLnative_attr.c + ${HDF5_SRC_DIR}/H5VLnative_blob.c ${HDF5_SRC_DIR}/H5VLnative_dataset.c ${HDF5_SRC_DIR}/H5VLnative_datatype.c ${HDF5_SRC_DIR}/H5VLnative_file.c diff --git a/src/H5Dio.c b/src/H5Dio.c index 1e6e70d..5160de8 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -478,33 +478,33 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") /* H5S_select_shape_same() has been modified to accept topologically identical - * selections with different rank as having the same shape (if the most - * rapidly changing coordinates match up), but the I/O code still has + * selections with different rank as having the same shape (if the most + * rapidly changing coordinates match up), but the I/O code still has * difficulties with the notion. * - * To solve this, we check to see if H5S_select_shape_same() returns true, - * and if the ranks of the mem and file spaces are different. If the are, - * construct a new mem space that is equivalent to the old mem space, and + * To solve this, we check to see if H5S_select_shape_same() returns true, + * and if the ranks of the mem and file spaces are different. If the are, + * construct a new mem space that is equivalent to the old mem space, and * use that instead. * - * Note that in general, this requires us to touch up the memory buffer as + * Note that in general, this requires us to touch up the memory buffer as * well. */ if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ /* Attempt to construct projected dataspace for memory dataspace */ if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.dst_type_size) < 0) + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.dst_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") HDassert(projected_mem_space); HDassert(adj_buf); /* Switch to using projected memory dataspace & adjusted buffer */ mem_space = projected_mem_space; - buf = adj_buf; + buf = (void *)adj_buf; /* Casting away 'const' OK -QAK */ } /* end if */ @@ -712,27 +712,27 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(!(H5S_has_extent(mem_space))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") - /* H5S_select_shape_same() has been modified to accept topologically - * identical selections with different rank as having the same shape - * (if the most rapidly changing coordinates match up), but the I/O + /* H5S_select_shape_same() has been modified to accept topologically + * identical selections with different rank as having the same shape + * (if the most rapidly changing coordinates match up), but the I/O * code still has difficulties with the notion. * - * To solve this, we check to see if H5S_select_shape_same() returns - * true, and if the ranks of the mem and file spaces are different. - * If the are, construct a new mem space that is equivalent to the + * To solve this, we check to see if H5S_select_shape_same() returns + * true, and if the ranks of the mem and file spaces are different. + * If the are, construct a new mem space that is equivalent to the * old mem space, and use that instead. * - * Note that in general, this requires us to touch up the memory buffer + * Note that in general, this requires us to touch up the memory buffer * as well. */ if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ /* Attempt to construct projected dataspace for memory dataspace */ if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.src_type_size) < 0) + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.src_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") HDassert(projected_mem_space); HDassert(adj_buf); diff --git a/src/H5Fint.c b/src/H5Fint.c index 5e2cf26..2ebcd94 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -139,18 +139,14 @@ H5F__set_vol_conn(H5F_t *file) /* Sanity check */ HDassert(0 != connector_prop.connector_id); - /* Copy connector info, if it exists */ - if(connector_prop.connector_info) { - H5VL_class_t *connector; /* Pointer to connector */ + /* Retrieve the connector for the ID */ + if(NULL == (file->shared->vol_cls = (H5VL_class_t *)H5I_object(connector_prop.connector_id))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Retrieve the connector for the ID */ - if(NULL == (connector = (H5VL_class_t *)H5I_object(connector_prop.connector_id))) - HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a VOL connector ID") - - /* Allocate and copy connector info */ - if(H5VL_copy_connector_info(connector, &new_connector_info, connector_prop.connector_info) < 0) + /* Allocate and copy connector info, if it exists */ + if(connector_prop.connector_info) + if(H5VL_copy_connector_info(file->shared->vol_cls, &new_connector_info, connector_prop.connector_info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "connector info copy failed") - } /* end if */ /* Cache the connector ID & info for the container */ file->shared->vol_id = connector_prop.connector_id; @@ -1377,6 +1373,7 @@ H5F__dest(H5F_t *f, hbool_t flush) if(H5I_dec_ref(f->shared->vol_id) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close VOL connector ID") + f->shared->vol_cls = NULL; /* Close the file */ if(H5FD_close(f->shared->lf) < 0) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 6cd2d3c..6a5c62f 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -29,9 +29,6 @@ /* Get package's private header */ #include "H5Fprivate.h" -/* Other public headers needed by this file */ -#include "H5VLpublic.h" /* Virtual Object Layer */ - /* Other private headers needed by this file */ #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ @@ -313,6 +310,7 @@ struct H5F_shared_t { /* Cached VOL connector ID & info */ hid_t vol_id; /* ID of VOL connector for the container */ + const H5VL_class_t *vol_cls; /* Pointer to VOL connector class for the container */ void *vol_info; /* Copy of VOL connector info for container */ /* File space allocation information */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 8c70663..e15025b 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -25,14 +25,15 @@ typedef struct H5F_t H5F_t; #include "H5Fpublic.h" /* Public headers needed by this file */ -#include "H5FDpublic.h" /* File drivers */ +#include "H5FDpublic.h" /* File drivers */ +#include "H5VLpublic.h" /* Virtual Object Layer */ /* Private headers needed by this file */ -#include "H5MMprivate.h" /* Memory management */ +#include "H5MMprivate.h" /* Memory management */ #ifdef H5_HAVE_PARALLEL -#include "H5Pprivate.h" /* Property lists */ +#include "H5Pprivate.h" /* Property lists */ #endif /* H5_HAVE_PARALLEL */ -#include "H5VMprivate.h" /* Vectors and arrays */ +#include "H5VMprivate.h" /* Vectors and arrays */ /**************************/ @@ -335,6 +336,7 @@ typedef struct H5F_t H5F_t; #define H5F_NULL_FSM_ADDR(F) ((F)->shared->null_fsm_addr) #define H5F_GET_MIN_DSET_OHDR(F) ((F)->shared->crt_dset_min_ohdr_flag) #define H5F_SET_MIN_DSET_OHDR(F, V) ((F)->shared->crt_dset_min_ohdr_flag = (V)) +#define H5F_VOL_CLS(F) ((F)->shared->vol_cls) #else /* H5F_MODULE */ #define H5F_LOW_BOUND(F) (H5F_get_low_bound(F)) #define H5F_HIGH_BOUND(F) (H5F_get_high_bound(F)) @@ -395,6 +397,7 @@ typedef struct H5F_t H5F_t; #define H5F_NULL_FSM_ADDR(F) (H5F_get_null_fsm_addr(F)) #define H5F_GET_MIN_DSET_OHDR(F) (H5F_get_min_dset_ohdr(F)) #define H5F_SET_MIN_DSET_OHDR(F, V) (H5F_set_min_dset_ohdr((F), (V))) +#define H5F_VOL_CLS(F) (H5F_get_vol_cls(F)) #endif /* H5F_MODULE */ @@ -755,6 +758,7 @@ H5_DLL hbool_t H5F_get_point_of_no_return(const H5F_t *f); H5_DLL hbool_t H5F_get_null_fsm_addr(const H5F_t *f); H5_DLL hbool_t H5F_get_min_dset_ohdr(const H5F_t *f); H5_DLL herr_t H5F_set_min_dset_ohdr(H5F_t *f, hbool_t minimize); +H5_DLL const H5VL_class_t *H5F_get_vol_cls(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index f36f348..69b042d 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1279,3 +1279,28 @@ H5F_get_null_fsm_addr(const H5F_t *f) FUNC_LEAVE_NOAPI(f->shared->null_fsm_addr) } /* end H5F_get_null_fsm_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_vol_cls + * + * Purpose: Get the VOL class for the file + * + * Return: VOL class pointer for file, can't fail + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +const H5VL_class_t * +H5F_get_vol_cls(const H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->vol_cls) +} /* end H5F_get_vol_cls */ + diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 8f301af..0523e7c 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -129,7 +129,7 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ *------------------------------------------------------------------------- */ static htri_t -H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt) +H5O_dtype_decode_helper(unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt) { unsigned flags, version; unsigned i; @@ -331,7 +331,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Decode the field's datatype information */ - if((can_upgrade = H5O_dtype_decode_helper(f, ioflags, pp, temp_type)) < 0) { + if((can_upgrade = H5O_dtype_decode_helper(ioflags, pp, temp_type)) < 0) { for(j = 0; j <= i; j++) H5MM_xfree(dt->shared->u.compnd.memb[j].name); H5MM_xfree(dt->shared->u.compnd.memb); @@ -457,7 +457,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p dt->shared->u.enumer.nmembs = dt->shared->u.enumer.nalloc = flags & 0xffff; if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype") /* Check if the parent of this enum has a version greater than the @@ -499,7 +499,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Decode base type of VL information */ if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type") /* Check if the parent of this vlen has a version greater than the @@ -511,7 +511,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Mark location this type as undefined for now. The caller function should * decide the location. */ - if(H5T_set_loc(dt, f, H5T_LOC_BADLOC) < 0) + if(H5T_set_loc(dt, NULL, H5T_LOC_BADLOC) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") break; @@ -540,7 +540,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Decode base type of array */ if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode array parent type") /* Check if the parent of this array has a version greater than the @@ -596,7 +596,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) +H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt) { unsigned flags = 0; uint8_t *hdr = (uint8_t *)*pp; @@ -956,7 +956,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Subtype */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->u.compnd.memb[i].type) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->u.compnd.memb[i].type) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode member type") } /* end for */ } @@ -976,7 +976,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) flags = dt->shared->u.enumer.nmembs & 0xffff; /* Parent type */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode parent datatype") /* Names, each a multiple of eight bytes */ @@ -1012,7 +1012,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Encode base type of VL information */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type") break; @@ -1050,7 +1050,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Encode base type of array's information */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type") break; @@ -1091,7 +1091,7 @@ done: function using malloc() and is returned to the caller. --------------------------------------------------------------------------*/ static void * -H5O_dtype_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, +H5O_dtype_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned *ioflags/*in,out*/, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) { H5T_t *dt = NULL; @@ -1107,7 +1107,7 @@ H5O_dtype_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Perform actual decode of message */ - if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0) + if(H5O_dtype_decode_helper(ioflags, &p, dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type") /* Set return value */ @@ -1136,7 +1136,7 @@ done: message in the "raw" disk form. --------------------------------------------------------------------------*/ static herr_t -H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg) +H5O_dtype_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *mesg) { const H5T_t *dt = (const H5T_t *) mesg; herr_t ret_value = SUCCEED; /* Return value */ @@ -1149,7 +1149,7 @@ H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg) HDassert(dt); /* encode */ - if(H5O_dtype_encode_helper(f, &p, dt) < 0) + if(H5O_dtype_encode_helper(&p, dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode type") done: diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 48c3282..723b9f2 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -30,7 +30,6 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5HGprivate.h" /* Global Heaps */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ @@ -3020,17 +3019,16 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, hbool_t noop_conv = FALSE; /* Flag to indicate a noop conversion */ hbool_t write_to_file = FALSE; /* Flag to indicate writing to file */ htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatyp */ + size_t bg_seq_len = 0; /* The number of elements in the background sequence */ hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */ H5T_t *src = NULL; /*source datatype */ H5T_t *dst = NULL; /*destination datatype */ - H5HG_t bg_hobjid, parent_hobjid; uint8_t *s = NULL; /*source buffer */ uint8_t *d = NULL; /*destination buffer */ uint8_t *b = NULL; /*background buffer */ ssize_t s_stride, d_stride; /*src and dst strides */ ssize_t b_stride; /*bkg stride */ size_t safe; /*how many elements are safe to process in each pass */ - size_t bg_seq_len = 0; size_t src_base_size, dst_base_size;/*source & destination base size*/ void *conv_buf = NULL; /*temporary conversion buffer */ size_t conv_buf_size = 0; /*size of conversion buffer in bytes */ @@ -3055,13 +3053,13 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_VLEN != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") - if(H5T_VLEN != dst->shared->type) + if(H5T_VLEN != dst->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") if(H5T_VLEN_STRING == src->shared->u.vlen.type && H5T_VLEN_STRING == dst->shared->u.vlen.type) { if((H5T_CSET_ASCII == src->shared->u.vlen.cset && H5T_CSET_UTF8 == dst->shared->u.vlen.cset) - || (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) + || (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "The library doesn't convert between strings of ASCII and UTF") - } + } /* end if */ /* Variable-length types don't need a background buffer */ cdata->need_bkg = H5T_BKG_NO; @@ -3179,25 +3177,27 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end else */ for(elmtno = 0; elmtno < safe; elmtno++) { + hbool_t is_nil; /* Whether sequence is "nil" */ + /* Check for "nil" source sequence */ - if((*(src->shared->u.vlen.isnull))(src->shared->u.vlen.f, s)) { + if((*(src->shared->u.vlen.cls->isnull))(src->shared->u.vlen.f, s, &is_nil) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check if VL data is 'nil'") + else if(is_nil) { /* Write "nil" sequence to destination location */ - if((*(dst->shared->u.vlen.setnull))(dst->shared->u.vlen.f, d, b) < 0) + if((*(dst->shared->u.vlen.cls->setnull))(dst->shared->u.vlen.f, d, b) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'") - } /* end if */ + } /* end else-if */ else { - ssize_t sseq_len; /* (signed) The number of elements in the current sequence*/ - size_t seq_len; /* The number of elements in the current sequence*/ + size_t seq_len; /* The number of elements in the current sequence */ /* Get length of element sequences */ - if((sseq_len = (*(src->shared->u.vlen.getlen))(s)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length") - seq_len = (size_t)sseq_len; + if((*(src->shared->u.vlen.cls->getlen))(src->shared->u.vlen.f, s, &seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length") /* If we are reading from memory and there is no conversion, just get the pointer to sequence */ if(write_to_file && noop_conv) { /* Get direct pointer to sequence */ - if(NULL == (conv_buf = (*(src->shared->u.vlen.getptr))(s))) + if(NULL == (conv_buf = (*(src->shared->u.vlen.cls->getptr))(s))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer") } /* end if */ else { @@ -3213,17 +3213,17 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, conv_buf_size = ((1 / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * H5T_VLEN_MIN_CONF_BUF_SIZE; if(NULL == (conv_buf = H5FL_BLK_CALLOC(vlen_seq, conv_buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") - } + } /* end if */ else if(conv_buf_size < MAX(src_size, dst_size)) { /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */ conv_buf_size = ((MAX(src_size, dst_size) / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * H5T_VLEN_MIN_CONF_BUF_SIZE; if(NULL == (conv_buf = H5FL_BLK_REALLOC(vlen_seq, conv_buf, conv_buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") HDmemset(conv_buf, 0, conv_buf_size); - } /* end if */ + } /* end else-if */ /* Read in VL sequence */ - if((*(src->shared->u.vlen.read))(src->shared->u.vlen.f, s, conv_buf, src_size) < 0) + if((*(src->shared->u.vlen.cls->read))(src->shared->u.vlen.f, s, conv_buf, src_size) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data") } /* end else */ @@ -3241,9 +3241,14 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* If we are writing and there is a nested VL type, read * the sequence into the background buffer */ if(nested) { - const uint8_t *tmp = b; + /* Sanity check */ + HDassert(write_to_file); + + /* Get length of background element sequence */ + if((*(dst->shared->u.vlen.cls->getlen))(dst->shared->u.vlen.f, b, &bg_seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length") - UINT32DECODE(tmp, bg_seq_len); + /* Read sequence if length > 0 */ if(bg_seq_len > 0) { if(tmp_buf_size < (bg_seq_len * MAX(src_base_size, dst_base_size))) { tmp_buf_size = (bg_seq_len * MAX(src_base_size, dst_base_size)); @@ -3251,10 +3256,10 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") HDmemset(tmp_buf, 0, tmp_buf_size); } /* end if */ - H5F_addr_decode(dst->shared->u.vlen.f, &tmp, &(bg_hobjid.addr)); - UINT32DECODE(tmp, bg_hobjid.idx); - if(NULL == H5HG_read(dst->shared->u.vlen.f, &bg_hobjid, tmp_buf, NULL)) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer") + + /* Read in background VL sequence */ + if((*(dst->shared->u.vlen.cls->read))(dst->shared->u.vlen.f, b, tmp_buf, bg_seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data") } /* end if */ /* If the sequence gets shorter, pad out the original sequence with zeros */ @@ -3268,26 +3273,23 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end if */ /* Write sequence to destination location */ - if((*(dst->shared->u.vlen.write))(dst->shared->u.vlen.f, &vl_alloc_info, d, conv_buf, b, seq_len, dst_base_size) < 0) + if((*(dst->shared->u.vlen.cls->write))(dst->shared->u.vlen.f, &vl_alloc_info, d, conv_buf, b, seq_len, dst_base_size) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data") if(!noop_conv) { /* For nested VL case, free leftover heap objects from the deeper level if the length of new data elements is shorter than the old data elements.*/ if(nested && seq_len < bg_seq_len) { - size_t parent_seq_len; const uint8_t *tmp; size_t u; - /* TMP_P is reset each time in the loop because DST_BASE_SIZE may include some data in addition to VL info. - SLU */ - for(u = seq_len; u < bg_seq_len; u++) { - tmp = (uint8_t *)tmp_buf + u * dst_base_size; - UINT32DECODE(tmp, parent_seq_len); - if(parent_seq_len > 0) { - H5F_addr_decode(dst->shared->u.vlen.f, &tmp, &(parent_hobjid.addr)); - UINT32DECODE(tmp, parent_hobjid.idx); - if(H5HG_remove(dst->shared->u.vlen.f, &parent_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } /* end if */ + /* Sanity check */ + HDassert(write_to_file); + + tmp = (uint8_t *)tmp_buf + seq_len * dst_base_size; + for(u = seq_len; u < bg_seq_len; u++, tmp += dst_base_size) { + /* Delete sequence in destination location */ + if((*(dst->shared->u.vlen.cls->del))(dst->shared->u.vlen.f, tmp) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove heap object") } /* end for */ } /* end if */ } /* end if */ diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 7798e37..281026c 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -243,14 +243,6 @@ typedef struct H5T_enum_t { char **name; /*array of symbol names */ } H5T_enum_t; -/* VL function pointers */ -typedef ssize_t (*H5T_vlen_getlenfunc_t)(const void *vl_addr); -typedef void * (*H5T_vlen_getptrfunc_t)(void *vl_addr); -typedef htri_t (*H5T_vlen_isnullfunc_t)(const H5F_t *f, void *vl_addr); -typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, void *_vl, void *buf, size_t len); -typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size); -typedef herr_t (*H5T_vlen_setnullfunc_t)(H5F_t *f, void *_vl, void *_bg); - /* VL types */ typedef enum { H5T_VLEN_BADTYPE = -1, /* invalid VL Type */ @@ -259,20 +251,35 @@ typedef enum { H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */ } H5T_vlen_type_t; +/* VL function pointers */ +typedef herr_t (*H5T_vlen_getlen_func_t)(H5F_t *f, const void *vl_addr, size_t *len); +typedef void * (*H5T_vlen_getptr_func_t)(void *vl_addr); +typedef herr_t (*H5T_vlen_isnull_func_t)(const H5F_t *f, void *vl_addr, hbool_t *isnull); +typedef herr_t (*H5T_vlen_setnull_func_t)(H5F_t *f, void *_vl, void *_bg); +typedef herr_t (*H5T_vlen_read_func_t)(H5F_t *f, void *_vl, void *buf, size_t len); +typedef herr_t (*H5T_vlen_write_func_t)(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size); +typedef herr_t (*H5T_vlen_delete_func_t)(H5F_t *f, const void *_vl); + +/* VL datatype callbacks */ +typedef struct H5T_vlen_class_t { + H5T_vlen_getlen_func_t getlen; /* Function to get VL sequence size (in element units, not bytes) */ + H5T_vlen_getptr_func_t getptr; /* Function to get VL sequence pointer */ + H5T_vlen_isnull_func_t isnull; /* Function to check if VL value is NIL */ + H5T_vlen_setnull_func_t setnull;/* Function to set a VL value to NIL */ + H5T_vlen_read_func_t read; /* Function to read VL sequence into buffer */ + H5T_vlen_write_func_t write; /* Function to write VL sequence from buffer */ + H5T_vlen_delete_func_t del; /* Function to delete VL sequence */ +} H5T_vlen_class_t; + /* A VL datatype */ typedef struct H5T_vlen_t { H5T_vlen_type_t type; /* Type of VL data in buffer */ H5T_loc_t loc; /* Location of VL data in buffer */ - H5T_cset_t cset; /* For VL string. character set */ - H5T_str_t pad; /* For VL string. space or null padding of + H5T_cset_t cset; /* For VL string: character set */ + H5T_str_t pad; /* For VL string: space or null padding of * extra bytes */ H5F_t *f; /* File ID (if VL data is on disk) */ - H5T_vlen_getptrfunc_t getptr; /* Function to get VL sequence pointer */ - H5T_vlen_getlenfunc_t getlen; /* Function to get VL sequence size (in element units, not bytes) */ - H5T_vlen_isnullfunc_t isnull; /* Function to check if VL value is NIL */ - H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */ - H5T_vlen_writefunc_t write; /* Function to write VL sequence from buffer */ - H5T_vlen_setnullfunc_t setnull; /* Function to set a VL value to NIL */ + const H5T_vlen_class_t *cls; /* Pointer to VL class callbacks */ } H5T_vlen_t; /* An opaque datatype */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index bafb47f..e14bd27 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -16,41 +16,121 @@ * datatypes in the H5T interface. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Tmodule.h" /* This source code file is part of the H5T module */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ -/* Local functions */ -static herr_t H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info); -static ssize_t H5T_vlen_seq_mem_getlen(const void *_vl); -static void * H5T_vlen_seq_mem_getptr(void *_vl); -static htri_t H5T_vlen_seq_mem_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_seq_mem_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_seq_mem_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_seq_mem_setnull(H5F_t *f, void *_vl, void *_bg); -static ssize_t H5T_vlen_str_mem_getlen(const void *_vl); -static void * H5T_vlen_str_mem_getptr(void *_vl); -static htri_t H5T_vlen_str_mem_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_str_mem_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_str_mem_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_str_mem_setnull(H5F_t *f, void *_vl, void *_bg); -static ssize_t H5T_vlen_disk_getlen(const void *_vl); -static void * H5T_vlen_disk_getptr(void *_vl); -static htri_t H5T_vlen_disk_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_disk_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg); - -/* Local variables */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info); + +/* Memory-based VL sequence callbacks */ +static herr_t H5T__vlen_mem_seq_getlen(H5F_t *f, const void *_vl, size_t *len); +static void * H5T__vlen_mem_seq_getptr(void *_vl); +static herr_t H5T__vlen_mem_seq_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_mem_seq_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_mem_seq_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_mem_seq_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); + +/* Memory-based VL string callbacks */ +static herr_t H5T__vlen_mem_str_getlen(H5F_t *f, const void *_vl, size_t *len); +static void * H5T__vlen_mem_str_getptr(void *_vl); +static herr_t H5T__vlen_mem_str_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_mem_str_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_mem_str_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_mem_str_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); + +/* Disk-based VL sequence (and string) callbacks */ +static herr_t H5T__vlen_disk_getlen(H5F_t *f, const void *_vl, size_t *len); +static herr_t H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_disk_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); +static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl); + + +/*********************/ +/* Public Variables */ +/*********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Class for VL seqences in memory */ +static const H5T_vlen_class_t H5T_vlen_mem_seq_g = { + H5T__vlen_mem_seq_getlen, /* 'getlen' */ + H5T__vlen_mem_seq_getptr, /* 'getptr' */ + H5T__vlen_mem_seq_isnull, /* 'isnull' */ + H5T__vlen_mem_seq_setnull, /* 'setnull' */ + H5T__vlen_mem_seq_read, /* 'read' */ + H5T__vlen_mem_seq_write, /* 'write' */ + NULL /* 'delete' */ +}; + +/* Class for VL strings in memory */ +static const H5T_vlen_class_t H5T_vlen_mem_str_g = { + H5T__vlen_mem_str_getlen, /* 'getlen' */ + H5T__vlen_mem_str_getptr, /* 'getptr' */ + H5T__vlen_mem_str_isnull, /* 'isnull' */ + H5T__vlen_mem_str_setnull, /* 'setnull' */ + H5T__vlen_mem_str_read, /* 'read' */ + H5T__vlen_mem_str_write, /* 'write' */ + NULL /* 'delete' */ +}; + +/* Class for both VL strings and seqences in file */ +static const H5T_vlen_class_t H5T_vlen_disk_g = { + H5T__vlen_disk_getlen, /* 'getlen' */ + NULL, /* 'getptr' */ + H5T__vlen_disk_isnull, /* 'isnull' */ + H5T__vlen_disk_setnull, /* 'setnull' */ + H5T__vlen_disk_read, /* 'read' */ + H5T__vlen_disk_write, /* 'write' */ + H5T__vlen_disk_delete /* 'delete' */ +}; @@ -194,32 +274,21 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) dt->shared->u.vlen.loc = H5T_LOC_MEMORY; if(dt->shared->u.vlen.type == H5T_VLEN_SEQUENCE) { - /* size in memory, disk size is different */ + /* Size in memory, disk size is different */ dt->shared->size = sizeof(hvl_t); /* Set up the function pointers to access the VL sequence in memory */ - dt->shared->u.vlen.getlen = H5T_vlen_seq_mem_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_seq_mem_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_seq_mem_isnull; - dt->shared->u.vlen.read = H5T_vlen_seq_mem_read; - dt->shared->u.vlen.write = H5T_vlen_seq_mem_write; - dt->shared->u.vlen.setnull = H5T_vlen_seq_mem_setnull; - } + dt->shared->u.vlen.cls = &H5T_vlen_mem_seq_g; + } /* end if */ else if(dt->shared->u.vlen.type == H5T_VLEN_STRING) { - /* size in memory, disk size is different */ + /* Size in memory, disk size is different */ dt->shared->size = sizeof(char *); /* Set up the function pointers to access the VL string in memory */ - dt->shared->u.vlen.getlen = H5T_vlen_str_mem_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_str_mem_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_str_mem_isnull; - dt->shared->u.vlen.read = H5T_vlen_str_mem_read; - dt->shared->u.vlen.write = H5T_vlen_str_mem_write; - dt->shared->u.vlen.setnull = H5T_vlen_str_mem_setnull; - } - else { + dt->shared->u.vlen.cls = &H5T_vlen_mem_str_g; + } /* end else-if */ + else HDassert(0 && "Invalid VL type"); - } /* Reset file ID (since this VL is in memory) */ dt->shared->u.vlen.f = NULL; @@ -234,18 +303,13 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* * Size of element on disk is 4 bytes for the length, plus the size * of an address in this file, plus 4 bytes for the size of a heap - * ID. Memory size is different + * ID. Memory size is different. */ dt->shared->size = 4 + (size_t)H5F_SIZEOF_ADDR(f) + 4; /* Set up the function pointers to access the VL information on disk */ /* VL sequences and VL strings are stored identically on disk, so use the same functions */ - dt->shared->u.vlen.getlen = H5T_vlen_disk_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_disk_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_disk_isnull; - dt->shared->u.vlen.read = H5T_vlen_disk_read; - dt->shared->u.vlen.write = H5T_vlen_disk_write; - dt->shared->u.vlen.setnull = H5T_vlen_disk_setnull; + dt->shared->u.vlen.cls = &H5T_vlen_disk_g; /* Set file ID (since this VL is on disk) */ dt->shared->u.vlen.f = f; @@ -255,6 +319,13 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined * location for VL type and leaves it for the caller to decide. */ + dt->shared->u.vlen.loc = H5T_LOC_BADLOC; + + /* Reset the function pointers to access the VL information */ + dt->shared->u.vlen.cls = NULL; + + /* Reset file pointer */ + dt->shared->u.vlen.f = NULL; break; case H5T_LOC_MAXLOC: @@ -269,11 +340,11 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__vlen_set_loc() */ +} /* end H5T__vlen_set_loc() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_getlen + * Function: H5T__vlen_mem_seq_getlen * * Purpose: Retrieves the length of a memory based VL element. * @@ -284,33 +355,35 @@ done: * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_seq_mem_getlen(const void *_vl) +static herr_t +H5T__vlen_mem_seq_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters, return result */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(vl); + /* Check parameter */ + HDassert(_vl); + HDassert(len); - FUNC_LEAVE_NOAPI((ssize_t)vl->len) +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + *len = vl->len; #else - HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); - FUNC_LEAVE_NOAPI((ssize_t)vl.len) + *len = vl.len; #endif -} /* end H5T_vlen_seq_mem_getlen() */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_getptr + * Function: H5T__vlen_mem_seq_getptr * * Purpose: Retrieves the pointer for a memory based VL element. * @@ -322,15 +395,15 @@ H5T_vlen_seq_mem_getlen(const void *_vl) *------------------------------------------------------------------------- */ static void * -H5T_vlen_seq_mem_getptr(void *_vl) +H5T__vlen_mem_seq_getptr(void *_vl) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters, return result */ #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -343,48 +416,82 @@ H5T_vlen_seq_mem_getptr(void *_vl) FUNC_LEAVE_NOAPI(vl.p) #endif -} /* end H5T_vlen_seq_mem_getptr() */ +} /* end H5T__vlen_mem_seq_getptr() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_isnull + * Function: H5T__vlen_mem_seq_isnull * * Purpose: Checks if a memory sequence is the "null" sequence * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_seq_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) +static herr_t +H5T__vlen_mem_seq_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl, hbool_t *isnull) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters, return result */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(vl); + /* Check parameters */ + HDassert(_vl); - FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE) +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + *isnull = ((vl->len == 0 || vl->p == NULL) ? TRUE : FALSE); #else - HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); - FUNC_LEAVE_NOAPI((vl.len==0 || vl.p==NULL) ? TRUE : FALSE) + *isnull = ((vl.len == 0 || vl.p == NULL) ? TRUE : FALSE); #endif -} /* end H5T_vlen_seq_mem_isnull() */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_isnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_read + * Function: H5T__vlen_mem_seq_setnull + * + * Purpose: Sets a VL info object in memory to the "nil" value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__vlen_mem_seq_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) +{ + hvl_t vl; /* Temporary hvl_t to use during operation */ + + FUNC_ENTER_STATIC_NOERR + + /* check parameters */ + HDassert(_vl); + + /* Set the "nil" hvl_t */ + vl.len = 0; + vl.p = NULL; + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + H5MM_memcpy(_vl, &vl, sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_setnull() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__vlen_mem_seq_read * * Purpose: "Reads" the memory based VL sequence into a buffer * @@ -396,36 +503,36 @@ H5T_vlen_seq_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) +H5T__vlen_mem_seq_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters, copy data */ HDassert(buf); #ifdef H5_NO_ALIGNMENT_RESTRICTIONS HDassert(vl && vl->p); - H5MM_memcpy(buf,vl->p,len); + H5MM_memcpy(buf, vl->p, len); #else HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); HDassert(vl.p); - H5MM_memcpy(buf,vl.p,len); + H5MM_memcpy(buf, vl.p, len); #endif FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_seq_mem_read() */ +} /* end H5T__vlen_mem_seq_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_write + * Function: H5T__vlen_mem_seq_write * * Purpose: "Writes" the memory based VL sequence from a buffer * @@ -437,104 +544,104 @@ H5T_vlen_seq_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) +H5T__vlen_mem_seq_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) { hvl_t vl; /* Temporary hvl_t to use during operation */ - size_t len; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(_vl); HDassert(buf); - if(seq_len!=0) { - len=seq_len*base_size; + if(seq_len) { + size_t len = seq_len * base_size; /* Sequence size */ /* Use the user's memory allocation routine is one is defined */ - if(vl_alloc_info->alloc_func!=NULL) { - if(NULL==(vl.p=(vl_alloc_info->alloc_func)(len,vl_alloc_info->alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") + if(vl_alloc_info->alloc_func != NULL) { + if(NULL == (vl.p = (vl_alloc_info->alloc_func)(len, vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "application memory allocation routine failed for VL data") } /* end if */ - else { /* Default to system malloc */ + else /* Default to system malloc */ if(NULL == (vl.p = HDmalloc(len))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end else */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed for VL data") /* Copy the data into the newly allocated buffer */ - H5MM_memcpy(vl.p,buf,len); - + H5MM_memcpy(vl.p, buf, len); } /* end if */ else - vl.p=NULL; + vl.p = NULL; /* Set the sequence length */ - vl.len=seq_len; + vl.len = seq_len; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); + H5MM_memcpy(_vl, &vl, sizeof(hvl_t)); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_seq_mem_write() */ +} /* end H5T__vlen_mem_seq_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_setnull + * Function: H5T__vlen_mem_str_getlen * - * Purpose: Sets a VL info object in memory to the "nil" value + * Purpose: Retrieves the length of a memory based VL string. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Saturday, November 8, 2003 + * Wednesday, June 2, 1999 * *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) +H5T__vlen_mem_str_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *len) { - hvl_t vl; /* Temporary hvl_t to use during operation */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const char *s = *(const char * const *)_vl; /* Pointer to the user's string information */ +#else + const char *s = NULL; /* Pointer to the user's string information */ +#endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters */ HDassert(_vl); - /* Set the "nil" hvl_t */ - vl.len=0; - vl.p=NULL; +#ifndef H5_NO_ALIGNMENT_RESTRICTIONS + H5MM_memcpy(&s, _vl, sizeof(char *)); +#endif - /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); + *len = HDstrlen(s); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_seq_mem_setnull() */ +} /* end H5T__vlen_mem_str_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_getlen + * Function: H5T__vlen_mem_str_getptr * - * Purpose: Retrieves the length of a memory based VL string. + * Purpose: Retrieves the pointer for a memory based VL string. * - * Return: Non-negative on success/Negative on failure + * Return: Non-NULL on success/NULL on failure * * Programmer: Quincey Koziol - * Wednesday, June 2, 1999 + * Saturday, June 12, 2004 * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_str_mem_getlen(const void *_vl) +static void * +H5T__vlen_mem_str_getptr(void *_vl) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const char *s=*(const char * const *)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else - const char *s = NULL; /* Pointer to the user's string information */ + char *s = NULL; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters */ #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -544,78 +651,71 @@ H5T_vlen_str_mem_getlen(const void *_vl) H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(s)) -} /* end H5T_vlen_str_mem_getlen() */ + FUNC_LEAVE_NOAPI(s) +} /* end H5T__vlen_mem_str_getptr() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_getptr + * Function: H5T__vlen_mem_str_isnull * - * Purpose: Retrieves the pointer for a memory based VL string. + * Purpose: Checks if a memory string is a NULL pointer * - * Return: Non-NULL on success/NULL on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Saturday, June 12, 2004 + * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static void * -H5T_vlen_str_mem_getptr(void *_vl) +static herr_t +H5T__vlen_mem_str_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl, hbool_t *isnull) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else char *s = NULL; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(s); -#else - HDassert(_vl); +#ifndef H5_NO_ALIGNMENT_RESTRICTIONS H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - FUNC_LEAVE_NOAPI(s) -} /* end H5T_vlen_str_mem_getptr() */ + *isnull = (s == NULL ? TRUE : FALSE); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_str_isnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_isnull + * Function: H5T__vlen_mem_str_setnull * - * Purpose: Checks if a memory string is a NULL pointer + * Purpose: Sets a VL info object in memory to the "null" value * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_str_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) +static herr_t +H5T__vlen_mem_str_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) { -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ -#else - char *s = NULL; /* Pointer to the user's string information */ -#endif + char *t = NULL; /* Pointer to temporary buffer allocated */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR -#ifndef H5_NO_ALIGNMENT_RESTRICTIONS - H5MM_memcpy(&s, _vl, sizeof(char *)); -#endif + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + H5MM_memcpy(_vl, &t, sizeof(char *)); - FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE) -} /* end H5T_vlen_str_mem_isnull() */ + FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ +} /* end H5T__vlen_mem_str_setnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_read + * Function: H5T__vlen_mem_str_read * * Purpose: "Reads" the memory based VL string into a buffer * @@ -627,17 +727,17 @@ H5T_vlen_str_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) +H5T__vlen_mem_str_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else char *s; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - if(len>0) { + if(len > 0) { /* check parameters */ HDassert(buf); #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -647,15 +747,15 @@ H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - H5MM_memcpy(buf,s,len); + H5MM_memcpy(buf, s, len); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_str_mem_read() */ +} /* end H5T__vlen_mem_str_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_write + * Function: H5T__vlen_mem_str_write * * Purpose: "Writes" the memory based VL string from a buffer * @@ -667,68 +767,42 @@ H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_str_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, +H5T__vlen_mem_str_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) { char *t; /* Pointer to temporary buffer allocated */ size_t len; /* Maximum length of the string to copy */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(buf); /* Use the user's memory allocation routine if one is defined */ - if(vl_alloc_info->alloc_func!=NULL) { - if(NULL==(t = (char *)(vl_alloc_info->alloc_func)((seq_len+1)*base_size,vl_alloc_info->alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end if */ - else { /* Default to system malloc */ + if(vl_alloc_info->alloc_func != NULL) { + if(NULL == (t = (char *)(vl_alloc_info->alloc_func)((seq_len + 1) * base_size, vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "application memory allocation routine failed for VL data") + } /* end if */ + else /* Default to system malloc */ if(NULL == (t = (char *)HDmalloc((seq_len + 1) * base_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end else */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed for VL data") - len=(seq_len*base_size); - H5MM_memcpy(t,buf,len); - t[len]='\0'; + /* 'write' the string into the buffer, with memcpy() */ + len = (seq_len * base_size); + H5MM_memcpy(t, buf, len); + t[len] = '\0'; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&t,sizeof(char *)); + H5MM_memcpy(_vl, &t, sizeof(char *)); done: FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ -} /* end H5T_vlen_str_mem_write() */ +} /* end H5T__vlen_mem_str_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_setnull - * - * Purpose: Sets a VL info object in memory to the "null" value - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Saturday, November 8, 2003 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5T_vlen_str_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) -{ - char *t=NULL; /* Pointer to temporary buffer allocated */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&t,sizeof(char *)); - - FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ -} /* end H5T_vlen_str_mem_setnull() */ - - -/*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_getlen + * Function: H5T__vlen_disk_getlen * * Purpose: Retrieves the length of a disk based VL element. * @@ -739,82 +813,108 @@ H5T_vlen_str_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_disk_getlen(const void *_vl) +static herr_t +H5T__vlen_disk_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *seq_len) { - const uint8_t *vl=(const uint8_t *)_vl; /* Pointer to the disk VL information */ - size_t seq_len = 0; /* Sequence length */ + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ + HDassert(f); HDassert(vl); + HDassert(seq_len); - UINT32DECODE(vl, seq_len); + /* Get length of sequence (different from blob size) */ + UINT32DECODE(vl, *seq_len); - FUNC_LEAVE_NOAPI((ssize_t)seq_len) -} /* end H5T_vlen_disk_getlen() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__vlen_disk_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_getptr + * Function: H5T__vlen_disk_isnull * - * Purpose: Retrieves the pointer to a disk based VL element. + * Purpose: Checks if a disk VL info object is the "nil" object * - * Return: Non-NULL on success/NULL on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Saturday, June 12, 2004 + * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static void * -H5T_vlen_disk_getptr(void H5_ATTR_UNUSED *vl) +static herr_t +H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - /* check parameters */ + FUNC_ENTER_STATIC + + /* Check parameters */ + HDassert(f); HDassert(vl); + HDassert(isnull); + + /* Skip the sequence's length */ + vl += 4; - FUNC_LEAVE_NOAPI(NULL) -} /* end H5T_vlen_disk_getptr() */ + /* Check if blob ID is "nil" */ + if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_ISNULL, f, isnull) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__vlen_disk_isnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_isnull + * Function: H5T__vlen_disk_setnull * - * Purpose: Checks if a disk VL info object is the "nil" object + * Purpose: Sets a VL info object on disk to the "nil" value * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_disk_isnull(const H5F_t *f, void *_vl) +static herr_t +H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the disk VL information */ - haddr_t addr; /* Sequence's heap address */ + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC /* check parameters */ + HDassert(f); HDassert(vl); - /* Skip the sequence's length */ - vl += 4; + /* Free heap object for old data */ + if(bg != NULL) + /* Delete sequence in destination location */ + if(H5T__vlen_disk_delete(f, bg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove background heap object") - /* Get the heap address */ - H5F_addr_decode(f, (const uint8_t **)&vl, &addr); + /* Set the length of the sequence */ + UINT32ENCODE(vl, 0); - FUNC_LEAVE_NOAPI(addr == 0 ? TRUE : FALSE) -} /* end H5T_vlen_disk_isnull() */ + /* Set blob ID to "nil" */ + if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_SETNULL, f) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__vlen_disk_setnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_read + * Function: H5T__vlen_disk_read * * Purpose: Reads the disk based VL element into a buffer * @@ -826,40 +926,32 @@ H5T_vlen_disk_isnull(const H5F_t *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) +H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) { - uint8_t *vl=(uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - H5HG_t hobjid; - herr_t ret_value=SUCCEED; /* Return value */ + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ + HDassert(f); HDassert(vl); HDassert(buf); - HDassert(f); /* Skip the length of the sequence */ vl += 4; - /* Get the heap information */ - H5F_addr_decode(f, (const uint8_t **)&vl, &(hobjid.addr)); - UINT32DECODE(vl, hobjid.idx); - - /* Check if this sequence actually has any data */ - if(hobjid.addr > 0) { - /* Read the VL information from disk */ - if(NULL == H5HG_read(f, &hobjid, buf, NULL)) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read VL information") - } + /* Retrieve blob */ + if(H5VL_blob_get(H5F_VOL_CLS(f), vl, f, buf) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_read() */ +} /* end H5T__vlen_disk_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_write + * Function: H5T__vlen_disk_write * * Purpose: Writes the disk based VL element from a buffer * @@ -871,122 +963,85 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, +H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size) { - uint8_t *vl = (uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ - uint8_t *bg = (uint8_t *)_bg; /*Pointer to the old data hvl_t */ - H5HG_t hobjid; /* New VL sequence's heap ID */ - size_t len; /* Size of new sequence on disk (in bytes) */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(vl); HDassert(seq_len == 0 || buf); HDassert(f); - /* Free heap object for old data. */ - if(bg!=NULL) { - H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ - - /* Skip the length of the sequence and heap object ID from background data. */ - bg += 4; - - /* Get heap information */ - H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); - UINT32DECODE(bg, bg_hobjid.idx); - - /* Free heap object for old data */ - if(bg_hobjid.addr > 0) { - /* Free heap object */ - if(H5HG_remove(f, &bg_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } - } /* end if */ + /* Free heap object for old data, if non-NULL */ + if(bg != NULL) + if(H5T__vlen_disk_delete(f, bg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove background heap object") /* Set the length of the sequence */ UINT32ENCODE(vl, seq_len); - /* Write the VL information to disk (allocates space also) */ - len = (seq_len*base_size); - if(H5HG_insert(f, len, buf, &hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write VL information") - - /* Encode the heap information */ - H5F_addr_encode(f, &vl, hobjid.addr); - UINT32ENCODE(vl, hobjid.idx); + /* Store blob */ + if(H5VL_blob_put(H5F_VOL_CLS(f), buf, (seq_len * base_size), f, vl) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_write() */ +} /* end H5T__vlen_disk_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_setnull + * Function: H5T__vlen_disk_delete * - * Purpose: Sets a VL info object on disk to the "nil" value + * Purpose: Deletes a disk-based VL element * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Saturday, November 8, 2003 + * Friday, August 15, 2019 * *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg) +H5T__vlen_disk_delete(H5F_t *f, const void *_vl) { - uint8_t *vl = (uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ - uint8_t *bg = (uint8_t *)_bg; /*Pointer to the old data hvl_t */ - uint32_t seq_len = 0; /* Sequence length */ - herr_t ret_value = SUCCEED; /* Return value */ + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ HDassert(f); - HDassert(vl); - - /* Free heap object for old data. */ - if(bg != NULL) { - H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ - /* Skip the length of the sequence and heap object ID from background data. */ - bg += 4; + /* Free heap object for old data */ + if(vl != NULL) { + size_t seq_len; /* VL sequence's length */ - /* Get heap information */ - H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); - UINT32DECODE(bg, bg_hobjid.idx); + /* Get length of sequence */ + UINT32DECODE(vl, seq_len); - /* Free heap object for old data */ - if(bg_hobjid.addr > 0) { - /* Free heap object */ - if(H5HG_remove(f, &bg_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } /* end if */ + /* Delete object, if length > 0 */ + if(seq_len > 0) + if(H5VL_blob_specific(H5F_VOL_CLS(f), (void *)vl, H5VL_BLOB_DELETE, f) < 0) /* Casting away 'const' OK -QAK */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ - /* Set the length of the sequence */ - UINT32ENCODE(vl, seq_len); - - /* Encode the "nil" heap pointer information */ - H5F_addr_encode(f, &vl, (haddr_t)0); - UINT32ENCODE(vl, 0); - done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_setnull() */ +} /* end H5T__vlen_disk_delete() */ /*-------------------------------------------------------------------------- NAME - H5T_vlen_reclaim_recurse + H5T__vlen_reclaim_recurse PURPOSE Internal recursive routine to free VL datatypes USAGE - herr_t H5T_vlen_reclaim_recurse(elem,dt) + herr_t H5T__vlen_reclaim_recurse(elem,dt) void *elem; IN/OUT: Pointer to the dataset element H5T_t *dt; IN: Datatype of dataset element @@ -1002,13 +1057,14 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info) +H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info) { unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC + /* Sanity checks */ HDassert(elem); HDassert(dt); @@ -1022,8 +1078,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset member and recurse on it */ for(u = 0; u < dt->shared->u.array.nelem; u++) { off = ((uint8_t *)elem) + u * (dt->shared->parent->shared->size); - if(H5T_vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free array element") + if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free array element") } /* end for */ } /* end if */ break; @@ -1037,8 +1093,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset member and recurse on it */ off = ((uint8_t *)elem) + dt->shared->u.compnd.memb[u].offset; - if(H5T_vlen_reclaim_recurse(off, dt->shared->u.compnd.memb[u].type, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field") + if(H5T__vlen_reclaim_recurse(off, dt->shared->u.compnd.memb[u].type, free_func, free_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free compound field") } /* end if */ } /* end for */ break; @@ -1057,8 +1113,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset of each array element and recurse on it */ while(vl->len > 0) { off = ((uint8_t *)vl->p) + (vl->len - 1) * dt->shared->parent->shared->size; - if(H5T_vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free VL element") + if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free VL element") vl->len--; } /* end while */ } /* end if */ @@ -1102,7 +1158,7 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_reclaim_recurse() */ +} /* end H5T__vlen_reclaim_recurse() */ /*-------------------------------------------------------------------------- @@ -1139,6 +1195,7 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned H5_ATTR_UNUSED ndim, FUNC_ENTER_NOAPI(FAIL) + /* Sanity check */ HDassert(elem); HDassert(vl_alloc_info); HDassert(H5I_DATATYPE == H5I_get_type(type_id)); @@ -1148,20 +1205,20 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned H5_ATTR_UNUSED ndim, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Pull the free function and free info pointer out of the op_data and call the recurse datatype free function */ - if(H5T_vlen_reclaim_recurse(elem, dt, vl_alloc_info->free_func, vl_alloc_info->free_info) < 0) + if(H5T__vlen_reclaim_recurse(elem, dt, vl_alloc_info->free_func, vl_alloc_info->free_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_reclaim() */ +} /* end H5T_vlen_reclaim() */ /*------------------------------------------------------------------------- * Function: H5T_vlen_reclaim_elmt * * Purpose: Alternative method to reclaim any VL data for a buffer element. - * - * Use this function when the datatype is already available, but + * + * Use this function when the datatype is already available, but * the allocation info is needed from the context before jumping * into recursion. * @@ -1188,10 +1245,10 @@ H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") /* Recurse on buffer to free dynamic fields */ - if(H5T_vlen_reclaim_recurse(elem, dt, vl_alloc_info.free_func, vl_alloc_info.free_info) < 0) + if(H5T__vlen_reclaim_recurse(elem, dt, vl_alloc_info.free_func, vl_alloc_info.free_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5T_vlen_reclaim_elmt */ +} /* H5T_vlen_reclaim_elmt() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 0131f0e..43739a6 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -6564,6 +6564,125 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_blob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, August 21, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, void *ctx, void *id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cls); + HDassert(size == 0 || blob); + HDassert(id); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.put) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method") + + /* Call the corresponding VOL callback */ + if((cls->blob_cls.put)(blob, size, ctx, id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 16, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, void *buf) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cls); + HDassert(id); + HDassert(buf); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method") + + /* Call the corresponding VOL callback */ + if((cls->blob_cls.get)(id, ctx, buf) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_specific(const H5VL_class_t *cls, void *id, + H5VL_blob_specific_t specific_type, ...) +{ + va_list arguments; /* Argument list passed from the API call */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cls); + HDassert(id); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.specific) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") + + /* Call the corresponding VOL callback */ + HDva_start(arguments, specific_type); + arg_started = TRUE; + if((cls->blob_cls.specific)(id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") + +done: + /* End access to the va_list, if we started it */ + if(arg_started) + HDva_end(arguments); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_get() */ + + +/*------------------------------------------------------------------------- * Function: H5VL__optional * * Purpose: Optional operation specific to connectors. diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 98bc521..c554dab 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -169,6 +169,14 @@ typedef enum H5VL_request_specific_t { H5VL_REQUEST_WAITALL /* Wait until all requests complete */ } H5VL_request_specific_t; +/* types for 'blob' SPECIFIC callback */ +typedef enum H5VL_blob_specific_t { + H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ + H5VL_BLOB_GETSIZE, /* Get size of blob */ + H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ + H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ +} H5VL_blob_specific_t; + /* types for different ways that objects are located in an HDF5 container */ typedef enum H5VL_loc_type_t { H5VL_OBJECT_BY_SELF, @@ -201,7 +209,7 @@ struct H5VL_loc_by_ref { hid_t lapl_id; }; -/* Structure to hold parameters for object locations. +/* Structure to hold parameters for object locations. * either: BY_ADDR, BY_ID, BY_NAME, BY_IDX, BY_REF * * Note: Leave loc_by_addr as the first union member so we @@ -355,6 +363,14 @@ typedef struct H5VL_request_class_t { herr_t (*free)(void *req); } H5VL_request_class_t; +/* 'blob' routines */ +typedef struct H5VL_blob_class_t { + herr_t (*put)(void *blob, size_t size, void *ctx, void *id); + herr_t (*get)(const void *id, void *ctx, void *blob); + herr_t (*specific)(void *id, H5VL_blob_specific_t specific_type, va_list arguments); + herr_t (*optional)(void *id, va_list arguments); +} H5VL_blob_class_t; + /* * VOL connector identifiers. Values 0 through 255 are for connectors defined * by the HDF5 library. Values 256 through 511 are available for testing new @@ -386,8 +402,9 @@ typedef struct H5VL_class_t { H5VL_link_class_t link_cls; /* Link (H5L*) class callbacks */ H5VL_object_class_t object_cls; /* Object (H5O*) class callbacks */ - /* Services */ + /* Infrastructure / Services */ H5VL_request_class_t request_cls; /* Asynchronous request class callbacks */ + H5VL_blob_class_t blob_cls; /* 'blob' callbacks */ /* Catch-all */ herr_t (*optional)(void *obj, hid_t dxpl_id, void **req, va_list arguments); /* Optional callback */ @@ -398,6 +415,7 @@ typedef struct H5VL_class_t { /* Public Variables */ /********************/ + /*********************/ /* Public Prototypes */ /*********************/ diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 9a2bd52..65c9117 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -13,7 +13,7 @@ /* * This file contains public declarations for authoring VOL connectors * which act as "passthrough" connectors that forward their API calls to - * an underlying connector. + * an underlying connector. * * An example of this might be a logging connector, which creates log messages * and then passes the call on to an underlying VOL connector. @@ -158,6 +158,10 @@ H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_s H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); +/* Public wrappers for generic 'optional' callback */ +H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, hid_t dxpl_id, + void **req, va_list arguments); + #ifdef __cplusplus } #endif diff --git a/src/H5VLint.c b/src/H5VLint.c index f9262f4..09acb2a 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -543,6 +543,7 @@ static H5VL_object_t * H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj) { H5VL_object_t *new_vol_obj = NULL; /* Pointer to new VOL object */ + hbool_t conn_rc_incr = FALSE; /* Whether the VOL connector refcount has been incremented */ H5VL_object_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -569,6 +570,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t /* Bump the reference count on the VOL connector */ H5VL__conn_inc_rc(vol_connector); + conn_rc_incr = TRUE; /* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */ if(H5I_DATATYPE == type) { @@ -579,6 +581,12 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t ret_value = (H5VL_object_t *)new_vol_obj; done: + /* Cleanup on error */ + if(NULL == ret_value) { + if(conn_rc_incr && H5VL__conn_dec_rc(vol_connector) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector") + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__new_vol_obj() */ @@ -759,16 +767,17 @@ done: * get the connector information instead of it being passed in. * * Return: Success: A valid HDF5 ID - * Failure: H5I_INVALID_HID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) { - H5VL_class_t *cls = NULL; - H5VL_t *connector = NULL; /* VOL connector struct */ - hid_t ret_value = H5I_INVALID_HID; + H5VL_class_t *cls = NULL; /* VOL connector class */ + H5VL_t *connector = NULL; /* VOL connector struct */ + hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ + hid_t ret_value = H5I_INVALID_HID;/* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -783,12 +792,24 @@ H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool connector->id = connector_id; if(H5I_inc_ref(connector->id, FALSE) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + conn_id_incr = TRUE; /* Get an ID for the VOL object */ if((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: + /* Clean up on error */ + if(ret_value < 0) { + /* Decrement VOL connector ID ref count on error */ + if(conn_id_incr && H5I_dec_ref(connector_id) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement ref count on VOL connector") + + /* Free VOL connector struct */ + if(NULL != connector) + connector = H5FL_FREE(H5VL_t, connector); + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_register_using_vol_id() */ diff --git a/src/H5VLnative.c b/src/H5VLnative.c index 7848c5d..c705aad 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -11,8 +11,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Purpose: The native VOL connector where access is to a single HDF5 file - * using HDF5 VFDs. + * Purpose: The native VOL connector where access is to a single HDF5 file + * using HDF5 VFDs. */ #include "H5private.h" /* Generic Functions */ @@ -120,6 +120,12 @@ static H5VL_class_t H5VL_native_cls_g = { NULL, /* optional */ NULL /* free */ }, + { /* blob_cls */ + H5VL__native_blob_put, /* put */ + H5VL__native_blob_get, /* get */ + H5VL__native_blob_specific, /* specific */ + H5VL__native_blob_optional /* optional */ + }, NULL /* optional */ }; diff --git a/src/H5VLnative.h b/src/H5VLnative.h index a8d5720..ba45848 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -17,6 +17,9 @@ #ifndef _H5VLnative_H #define _H5VLnative_H +/* Private headers needed by this file */ +#include "H5VLprivate.h" /* Virtual Object Layer */ + /* Identifier for the native VOL connector */ #define H5VL_NATIVE (H5VL_native_register()) diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c new file mode 100644 index 0000000..6f2fbe6 --- /dev/null +++ b/src/H5VLnative_blob.c @@ -0,0 +1,260 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Blob callbacks for the native VOL connector + */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5VLnative_private.h" /* Native VOL connector */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_put + * + * Purpose: Handles the blob 'put' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_put(void *blob, size_t size, void *_ctx, void *_id) +{ + uint8_t *id = (uint8_t *)_id; /* Pointer to blob ID */ + H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5HG_t hobjid; /* New VL sequence's heap ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check parameters */ + HDassert(id); + HDassert(size == 0 || blob); + HDassert(f); + + /* Write the VL information to disk (allocates space also) */ + if(H5HG_insert(f, size, blob, &hobjid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write blob information") + + /* Encode the heap information */ + H5F_addr_encode(f, &id, hobjid.addr); + UINT32ENCODE(id, hobjid.idx); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_get + * + * Purpose: Handles the blob 'get' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_get(const void *_id, void *_ctx, void *buf) +{ + const uint8_t *id = (const uint8_t *)_id; /* Pointer to the disk blob ID */ + H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5HG_t hobjid; /* Global heap ID for sequence */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(id); + HDassert(f); + HDassert(buf); + + /* Get the heap information */ + H5F_addr_decode(f, &id, &hobjid.addr); + UINT32DECODE(id, hobjid.idx); + + /* Check if this sequence actually has any data */ + if(hobjid.addr > 0) + /* Read the VL information from disk */ + if(NULL == H5HG_read(f, &hobjid, buf, NULL)) + HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read VL information") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_specific + * + * Purpose: Handles the blob 'specific' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, + va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + switch(specific_type) { + case H5VL_BLOB_GETSIZE: + { + const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ + H5F_t *f = HDva_arg(arguments, H5F_t *); + size_t *size = HDva_arg(arguments, size_t *); + H5HG_t hobjid; /* blob's heap ID */ + + /* Get heap information */ + H5F_addr_decode(f, &id, &(hobjid.addr)); + UINT32DECODE(id, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) { + if(H5HG_get_obj_size(f, &hobjid, size) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") + } /* end if */ + else + *size = 0; /* Return '0' size for 'nil' blob ID */ + + break; + } + + case H5VL_BLOB_ISNULL: + { + const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ + H5F_t *f = HDva_arg(arguments, H5F_t *); + hbool_t *isnull = HDva_arg(arguments, hbool_t *); + haddr_t addr; /* Sequence's heap address */ + + /* Get the heap address */ + H5F_addr_decode(f, &id, &addr); + + /* Check if heap address is 'nil' */ + *isnull = (addr == 0 ? TRUE : FALSE); + + break; + } + + case H5VL_BLOB_SETNULL: + { + uint8_t *id = (uint8_t *)_id; /* Pointer to the blob ID */ + H5F_t *f = HDva_arg(arguments, H5F_t *); + + /* Encode the "nil" heap pointer information */ + H5F_addr_encode(f, &id, (haddr_t)0); + UINT32ENCODE(id, 0); + + break; + } + + case H5VL_BLOB_DELETE: + { + const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ + H5F_t *f = HDva_arg(arguments, H5F_t *); + H5HG_t hobjid; /* VL sequence's heap ID */ + + /* Get heap information */ + H5F_addr_decode(f, &id, &hobjid.addr); + UINT32DECODE(id, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) + if(H5HG_remove(f, &hobjid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_optional + * + * Purpose: Handles the blob 'optional' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_optional(void *id, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_optional() */ + diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index 714b73c..df3865b 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -17,13 +17,34 @@ #ifndef _H5VLnative_private_H #define _H5VLnative_private_H +/* Private headers needed by this file */ #include "H5VLnative.h" /* Native VOL connector */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + #ifdef __cplusplus extern "C" { #endif -/* Atrribute callbacks */ +/* Attribute callbacks */ H5_DLL void *H5VL__native_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req); void *H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req); @@ -80,6 +101,12 @@ H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_t get_type, H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); +/* Blob callbacks */ +H5_DLL herr_t H5VL__native_blob_put(void *blob, size_t size, void *ctx, void *id); +H5_DLL herr_t H5VL__native_blob_get(const void *id, void *ctx, void *buf); +H5_DLL herr_t H5VL__native_blob_specific(void *id, H5VL_blob_specific_t specific_type, va_list arguments); +H5_DLL herr_t H5VL__native_blob_optional(void *id, va_list arguments); + #ifdef __cplusplus } #endif diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 24070fa..48ef510 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -196,14 +196,14 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_info_cmp, /* compare */ H5VL_pass_through_info_free, /* free */ H5VL_pass_through_info_to_str, /* to_str */ - H5VL_pass_through_str_to_info, /* from_str */ + H5VL_pass_through_str_to_info /* from_str */ }, { /* wrap_cls */ H5VL_pass_through_get_object, /* get_object */ H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */ H5VL_pass_through_wrap_object, /* wrap_object */ H5VL_pass_through_unwrap_object, /* unwrap_object */ - H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */ + H5VL_pass_through_free_wrap_ctx /* free_wrap_ctx */ }, { /* attribute_cls */ H5VL_pass_through_attr_create, /* create */ @@ -255,14 +255,14 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_link_move, /* move */ H5VL_pass_through_link_get, /* get */ H5VL_pass_through_link_specific, /* specific */ - H5VL_pass_through_link_optional, /* optional */ + H5VL_pass_through_link_optional /* optional */ }, { /* object_cls */ H5VL_pass_through_object_open, /* open */ H5VL_pass_through_object_copy, /* copy */ H5VL_pass_through_object_get, /* get */ H5VL_pass_through_object_specific, /* specific */ - H5VL_pass_through_object_optional, /* optional */ + H5VL_pass_through_object_optional /* optional */ }, { /* request_cls */ H5VL_pass_through_request_wait, /* wait */ @@ -272,6 +272,12 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_request_optional, /* optional */ H5VL_pass_through_request_free /* free */ }, + { /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, NULL /* optional */ }; diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 1752b0c..4aeabfa 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -193,6 +193,14 @@ H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_s H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, ...); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); +/* Blob functions */ +H5_DLL herr_t H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, + void *ctx, void *id); +H5_DLL herr_t H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, + void *blob); +H5_DLL herr_t H5VL_blob_specific(const H5VL_class_t *cls, void *id, + H5VL_blob_specific_t specific_type, ...); + /* Generic functions */ H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, hid_t dxpl_id,void **req, ...); diff --git a/src/Makefile.am b/src/Makefile.am index ccee69b..24dfe74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,8 +116,9 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Torder.c \ H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TS.c \ H5VL.c H5VLcallback.c H5VLint.c H5VLnative.c \ - H5VLnative_attr.c H5VLnative_dataset.c H5VLnative_datatype.c \ - H5VLnative_file.c H5VLnative_group.c H5VLnative_link.c H5VLnative_object.c \ + H5VLnative_attr.c H5VLnative_blob.c H5VLnative_dataset.c \ + H5VLnative_datatype.c H5VLnative_file.c H5VLnative_group.c \ + H5VLnative_link.c H5VLnative_object.c \ H5VLpassthru.c \ H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c \ -- cgit v0.12 From 1b766420f1c5064b0ad2f126c6d62cba8373564f Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Thu, 19 Sep 2019 14:55:03 -0500 Subject: Fix H5VL_blob_get to return size of blob Fix const in blob API Add H5HG_HEAP_ID_SIZE macro to return native blob size Add maximum size for blobs Fix blob API callbacks to pass VOL file object Add public wrappers for blob VOL API Implement passthrough blob callbacks Update H5Tvlen after callback changes Update trace information for H5VL blob routines Fix public header inclusion in native and passthru headers --- bin/trace | 1 + src/H5HGprivate.h | 4 + src/H5Tvlen.c | 69 +++++++++-- src/H5VLcallback.c | 288 ++++++++++++++++++++++++++++++++++++++----- src/H5VLconnector.h | 10 +- src/H5VLconnector_passthru.h | 5 + src/H5VLnative.c | 2 +- src/H5VLnative.h | 4 +- src/H5VLnative_blob.c | 71 ++++------- src/H5VLnative_private.h | 7 +- src/H5VLpassthru.c | 92 +++++++++++++- src/H5VLpassthru.h | 3 + src/H5VLprivate.h | 9 +- src/H5trace.c | 29 +++++ 14 files changed, 490 insertions(+), 104 deletions(-) diff --git a/bin/trace b/bin/trace index 54b6f8f..fe0443d 100755 --- a/bin/trace +++ b/bin/trace @@ -99,6 +99,7 @@ $Source = ""; "unsigned long long" => "UL", "H5VL_attr_get_t" => "Va", "H5VL_attr_specific_t" => "Vb", + "H5VL_blob_specific_t" => "VB", "H5VL_class_value_t" => "VC", "H5VL_dataset_get_t" => "Vc", "H5VL_dataset_specific_t" => "Vd", diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 1c609e2..4841847 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -49,6 +49,10 @@ typedef struct H5HG_heap_t H5HG_heap_t; #define H5HG_FREE_SIZE(H) (H5HG_get_free_size(H)) #endif /* H5HG_MODULE */ +/* Size of encoded global heap ID */ +/* (size of file address + 32-bit integer) */ +#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + H5_SIZEOF_UINT32_T) + /* Main global heap routines */ H5_DLL herr_t H5HG_insert(H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index e14bd27..939a26d 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -21,7 +21,7 @@ /****************/ #include "H5Tmodule.h" /* This source code file is part of the H5T module */ - +#define H5F_FRIEND /*suppress error about including H5Fpkg */ /***********/ /* Headers */ @@ -30,6 +30,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ +#include "H5Fpkg.h" /* File */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Tpkg.h" /* Datatypes */ @@ -849,7 +850,9 @@ done: static herr_t H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) { - const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -862,11 +865,19 @@ H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) /* Skip the sequence's length */ vl += 4; + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id((H5F_t *)f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Check if blob ID is "nil" */ - if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_ISNULL, f, isnull) < 0) + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_ISNULL, isnull) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_isnull() */ @@ -886,6 +897,8 @@ done: static herr_t H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) { + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ @@ -904,11 +917,19 @@ H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) /* Set the length of the sequence */ UINT32ENCODE(vl, 0); + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set blob ID to "nil" */ - if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_SETNULL, f) < 0) + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_SETNULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_setnull() */ @@ -928,6 +949,8 @@ done: static herr_t H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) { + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ @@ -941,11 +964,19 @@ H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) /* Skip the length of the sequence */ vl += 4; + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Retrieve blob */ - if(H5VL_blob_get(H5F_VOL_CLS(f), vl, f, buf) < 0) + if(H5VL_blob_get(vol_obj, vl, buf, NULL, NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_read() */ @@ -966,6 +997,8 @@ static herr_t H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size) { + H5VL_object_t *vol_obj = NULL; /* Object info */ + hid_t file_id = H5I_INVALID_HID; uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */ herr_t ret_value = SUCCEED; /* Return value */ @@ -985,11 +1018,19 @@ H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_al /* Set the length of the sequence */ UINT32ENCODE(vl, seq_len); + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Store blob */ - if(H5VL_blob_put(H5F_VOL_CLS(f), buf, (seq_len * base_size), f, vl) < 0) + if(H5VL_blob_put(vol_obj, buf, (seq_len * base_size), vl, NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_write() */ @@ -1010,6 +1051,7 @@ static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl) { const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + hid_t file_id = H5I_INVALID_HID; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1025,12 +1067,23 @@ H5T__vlen_disk_delete(H5F_t *f, const void *_vl) UINT32DECODE(vl, seq_len); /* Delete object, if length > 0 */ - if(seq_len > 0) - if(H5VL_blob_specific(H5F_VOL_CLS(f), (void *)vl, H5VL_BLOB_DELETE, f) < 0) /* Casting away 'const' OK -QAK */ + if(seq_len > 0) { + H5VL_object_t *vol_obj = NULL; /* Object info */ + + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + if(H5VL_blob_specific(vol_obj, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") + } } /* end if */ done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_delete() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 43739a6..5400356 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -177,7 +177,12 @@ static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, va_list arguments); static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls); - +static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, + const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, + const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, + void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); /*********************/ /* Package Variables */ @@ -6564,81 +6569,230 @@ done: /*------------------------------------------------------------------------- - * Function: H5VL_blob_put + * Function: H5VL__blob_put * * Purpose: Put a blob through the VOL * * Return: SUCCEED / FAIL * - * Programmer: Quincey Koziol - * Wednesday, August 21, 2019 - * *------------------------------------------------------------------------- */ -herr_t -H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, void *ctx, void *id) +static herr_t +H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, + void *blob_id, void *ctx) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(size == 0 || blob); - HDassert(id); + HDassert(size == 0 || buf); + HDassert(blob_id); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.put) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method") /* Call the corresponding VOL callback */ - if((cls->blob_cls.put)(blob, size, ctx, id) < 0) + if((cls->blob_cls.put)(obj, buf, size, blob_id, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_blob_put() */ +} /* end H5VL__blob_put() */ /*------------------------------------------------------------------------- - * Function: H5VL_blob_get + * Function: H5VL_blob_put * - * Purpose: Get a blob through the VOL + * Purpose: Put a blob through the VOL * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol - * Friday, August 16, 2019 + * Wednesday, August 21, 2019 * *------------------------------------------------------------------------- */ herr_t -H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, void *buf) +H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, + void *blob_id, void *ctx) { + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(vol_obj); + HDassert(size == 0 || buf); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*xz*x*x", obj, connector_id, buf, size, blob_id, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(obj, cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, + void *buf, size_t *size, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(id); - HDassert(buf); + HDassert(blob_id); + HDassert(size || buf); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.get) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method") /* Call the corresponding VOL callback */ - if((cls->blob_cls.get)(id, ctx, buf) < 0) + if((cls->blob_cls.get)(obj, blob_id, buf, size, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed") done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + HDassert(size || buf); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_get() */ /*------------------------------------------------------------------------- - * Function: H5VL_blob_specific + * Function: H5VLblob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*x*x*z*x", obj, connector_id, blob_id, buf, size, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(obj, cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_specific * * Purpose: Specific operation on blobs through the VOL * @@ -6649,28 +6803,66 @@ done: * *------------------------------------------------------------------------- */ -herr_t -H5VL_blob_specific(const H5VL_class_t *cls, void *id, - H5VL_blob_specific_t specific_type, ...) +static herr_t +H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(id); + HDassert(blob_id); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.specific) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") /* Call the corresponding VOL callback */ + if((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, + H5VL_blob_specific_t specific_type, ...) +{ + va_list arguments; /* Argument list passed from the API call */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ HDva_start(arguments, specific_type); arg_started = TRUE; - if((cls->blob_cls.specific)(id, specific_type, arguments) < 0) + if((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, arguments)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: @@ -6678,8 +6870,46 @@ done: if(arg_started) HDva_end(arguments); + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_blob_get() */ +} /* end H5VL_blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_specific() */ /*------------------------------------------------------------------------- diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index c554dab..1221d88 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -37,6 +37,8 @@ #define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ #define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +/* The maximum size allowed for blobs */ +#define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ /*******************/ /* Public Typedefs */ @@ -365,10 +367,10 @@ typedef struct H5VL_request_class_t { /* 'blob' routines */ typedef struct H5VL_blob_class_t { - herr_t (*put)(void *blob, size_t size, void *ctx, void *id); - herr_t (*get)(const void *id, void *ctx, void *blob); - herr_t (*specific)(void *id, H5VL_blob_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *id, va_list arguments); + herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); + herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); + herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + herr_t (*optional)(void *obj, void *blob_id, va_list arguments); } H5VL_blob_class_t; /* diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 65c9117..d0d73d2 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -158,6 +158,11 @@ H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_s H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); +/* Public wrappers for blob callbacks */ +H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + /* Public wrappers for generic 'optional' callback */ H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments); diff --git a/src/H5VLnative.c b/src/H5VLnative.c index c705aad..78eaee4 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -124,7 +124,7 @@ static H5VL_class_t H5VL_native_cls_g = { H5VL__native_blob_put, /* put */ H5VL__native_blob_get, /* get */ H5VL__native_blob_specific, /* specific */ - H5VL__native_blob_optional /* optional */ + NULL /* optional */ }, NULL /* optional */ }; diff --git a/src/H5VLnative.h b/src/H5VLnative.h index ba45848..ec0ecbc 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -17,8 +17,8 @@ #ifndef _H5VLnative_H #define _H5VLnative_H -/* Private headers needed by this file */ -#include "H5VLprivate.h" /* Virtual Object Layer */ +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ /* Identifier for the native VOL connector */ #define H5VL_NATIVE (H5VL_native_register()) diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c index 6f2fbe6..b16b407 100644 --- a/src/H5VLnative_blob.c +++ b/src/H5VLnative_blob.c @@ -68,22 +68,23 @@ *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_put(void *blob, size_t size, void *_ctx, void *_id) +H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, + void H5_ATTR_UNUSED *ctx) { - uint8_t *id = (uint8_t *)_id; /* Pointer to blob ID */ - H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + uint8_t *id = (uint8_t *)blob_id; /* Pointer to blob ID */ H5HG_t hobjid; /* New VL sequence's heap ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check parameters */ - HDassert(id); - HDassert(size == 0 || blob); HDassert(f); + HDassert(size == 0 || buf); + HDassert(id); /* Write the VL information to disk (allocates space also) */ - if(H5HG_insert(f, size, blob, &hobjid) < 0) + if(H5HG_insert(f, size, (void *)buf, &hobjid) < 0) HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write blob information") /* Encode the heap information */ @@ -108,18 +109,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_get(const void *_id, void *_ctx, void *buf) +H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, + void H5_ATTR_UNUSED *ctx) { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the disk blob ID */ - H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the disk blob ID */ H5HG_t hobjid; /* Global heap ID for sequence */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Sanity check */ - HDassert(id); HDassert(f); + HDassert(id); HDassert(buf); /* Get the heap information */ @@ -129,7 +131,7 @@ H5VL__native_blob_get(const void *_id, void *_ctx, void *buf) /* Check if this sequence actually has any data */ if(hobjid.addr > 0) /* Read the VL information from disk */ - if(NULL == H5HG_read(f, &hobjid, buf, NULL)) + if(NULL == H5HG_read(f, &hobjid, buf, size)) HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read VL information") done: @@ -150,18 +152,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL__native_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) { + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE + /* Sanity check */ + HDassert(f); + HDassert(blob_id); + switch(specific_type) { case H5VL_BLOB_GETSIZE: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ size_t *size = HDva_arg(arguments, size_t *); H5HG_t hobjid; /* blob's heap ID */ @@ -182,8 +188,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_ISNULL: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ hbool_t *isnull = HDva_arg(arguments, hbool_t *); haddr_t addr; /* Sequence's heap address */ @@ -198,9 +203,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_SETNULL: { - uint8_t *id = (uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); - + uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */ /* Encode the "nil" heap pointer information */ H5F_addr_encode(f, &id, (haddr_t)0); UINT32ENCODE(id, 0); @@ -210,8 +213,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_DELETE: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ H5HG_t hobjid; /* VL sequence's heap ID */ /* Get heap information */ @@ -233,28 +235,3 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_blob_specific() */ - - -/*------------------------------------------------------------------------- - * Function: H5VL__native_blob_optional - * - * Purpose: Handles the blob 'optional' callback - * - * Return: SUCCEED / FAIL - * - * Programmer: Quincey Koziol - * Friday, August 15, 2019 - * - *------------------------------------------------------------------------- - */ -herr_t -H5VL__native_blob_optional(void *id, va_list arguments) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__native_blob_optional() */ - diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index df3865b..5ed0b1f 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -102,10 +102,9 @@ H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); /* Blob callbacks */ -H5_DLL herr_t H5VL__native_blob_put(void *blob, size_t size, void *ctx, void *id); -H5_DLL herr_t H5VL__native_blob_get(const void *id, void *ctx, void *buf); -H5_DLL herr_t H5VL__native_blob_specific(void *id, H5VL_blob_specific_t specific_type, va_list arguments); -H5_DLL herr_t H5VL__native_blob_optional(void *id, va_list arguments); +H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); #ifdef __cplusplus } diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 48ef510..85c2211 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -178,6 +178,12 @@ static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specifi static herr_t H5VL_pass_through_request_optional(void *req, va_list arguments); static herr_t H5VL_pass_through_request_free(void *req); +/* Blob callbacks */ +static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + + /*******************/ /* Local variables */ /*******************/ @@ -273,9 +279,9 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_request_free /* free */ }, { /* blob_cls */ - NULL, /* put */ - NULL, /* get */ - NULL, /* specific */ + H5VL_pass_through_blob_put, /* put */ + H5VL_pass_through_blob_get, /* get */ + H5VL_pass_through_blob_specific, /* specific */ NULL /* optional */ }, NULL /* optional */ @@ -2840,3 +2846,83 @@ H5VL_pass_through_request_free(void *obj) return ret_value; } /* end H5VL_pass_through_request_free() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_put + * + * Purpose: Handles the blob 'put' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Put\n"); +#endif + + ret_value = H5VLblob_put(o->under_object, o->under_vol_id, buf, size, + blob_id, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_get + * + * Purpose: Handles the blob 'get' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Get\n"); +#endif + + ret_value = H5VLblob_get(o->under_object, o->under_vol_id, blob_id, buf, + size, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_specific + * + * Purpose: Handles the blob 'specific' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Specific\n"); +#endif + + ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, + specific_type, arguments); + + return ret_value; +} /* end H5VL_pass_through_blob_specific() */ diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h index e640636..d145bcd 100644 --- a/src/H5VLpassthru.h +++ b/src/H5VLpassthru.h @@ -17,6 +17,9 @@ #ifndef _H5VLpassthru_H #define _H5VLpassthru_H +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ + /* Identifier for the pass-through VOL connector */ #define H5VL_PASSTHRU (H5VL_pass_through_register()) diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 4aeabfa..2889524 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -194,12 +194,9 @@ H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, ...); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); /* Blob functions */ -H5_DLL herr_t H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, - void *ctx, void *id); -H5_DLL herr_t H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, - void *blob); -H5_DLL herr_t H5VL_blob_specific(const H5VL_class_t *cls, void *id, - H5VL_blob_specific_t specific_type, ...); +H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...); /* Generic functions */ H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, hid_t dxpl_id,void **req, ...); diff --git a/src/H5trace.c b/src/H5trace.c index 2e905a5..a167d43 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -2588,6 +2588,35 @@ H5_trace(const double *returning, const char *func, const char *type, ...) } /* end switch */ } /* end else */ break; + case 'B': + if(ptr) { + if(vp) + HDfprintf (out, "0x%lx", (unsigned long)vp); + else + HDfprintf(out, "NULL"); + } /* end if */ + else { + H5VL_blob_specific_t specific = (H5VL_blob_specific_t)HDva_arg(ap, int); + + switch(specific) { + case H5VL_BLOB_DELETE: + HDfprintf(out, "H5VL_BLOB_DELETE"); + break; + case H5VL_BLOB_GETSIZE: + HDfprintf(out, "H5VL_BLOB_GETSIZE"); + break; + case H5VL_BLOB_ISNULL: + HDfprintf(out, "H5VL_BLOB_ISNULL"); + break; + case H5VL_BLOB_SETNULL: + HDfprintf(out, "H5VL_BLOB_SETNULL"); + break; + default: + HDfprintf(out, "%ld", (long)specific); + break; + } /* end switch */ + } /* end else */ + break; case 'C': if(ptr) { if(vp) -- cgit v0.12 From b571cf6c3851357d86cd5a231351d75177af29a4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 23 Aug 2019 16:54:52 -0500 Subject: Adapt Jerome's "file info" H5VL 'get' query to retrieve container token info. Remove "by address" location for VOL operations. (Switching to "by token") --- src/H5Fpkg.h | 1 + src/H5Fquery.c | 38 ++++++++++++++++++++++ src/H5O.c | 4 +-- src/H5Tvlen.c | 7 ++-- src/H5VLconnector.h | 55 +++++++++++++++++++------------ src/H5VLnative_file.c | 86 ++++++++++++++++++++++++++++--------------------- src/H5VLnative_object.c | 16 ++------- src/H5trace.c | 9 ++++-- 8 files changed, 135 insertions(+), 81 deletions(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 6a5c62f..4b5b788 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -411,6 +411,7 @@ H5_DLL herr_t H5F__close(H5F_t *f); H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); H5_DLL H5F_t *H5F__get_file(void *obj, H5I_type_t type); H5_DLL hid_t H5F__get_file_id(H5F_t *file, hbool_t app_ref); +H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); /* File mount related routines */ H5_DLL herr_t H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 69b042d..32743c4 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1304,3 +1304,41 @@ H5F_get_vol_cls(const H5F_t *f) FUNC_LEAVE_NOAPI(f->shared->vol_cls) } /* end H5F_get_vol_cls */ + +/*------------------------------------------------------------------------- + * Function: H5F_get_cont_info + * + * Purpose: Get the VOL container info for the file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + + /* Verify structure version */ + if(info->version != H5VL_CONTAINER_INFO_VERSION) + HGOTO_ERROR(H5E_FILE, H5E_VERSION, FAIL, "wrong container info version #") + + /* Set the container info fields */ + info->feature_flags = 0; /* None currently defined */ + info->token_size = H5F_SIZEOF_ADDR(f); + info->blob_id_size = H5HG_HEAP_ID_SIZE(f); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_cont_info */ + diff --git a/src/H5O.c b/src/H5O.c index bf2d799..e1d0751 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -263,8 +263,8 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr) FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "ia", loc_id, addr); - loc_params.type = H5VL_OBJECT_BY_ADDR; - loc_params.loc_data.loc_by_addr.addr = addr; + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &addr; loc_params.obj_type = H5I_get_type(loc_id); /* Get the location object */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 939a26d..9f82340 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -818,20 +818,17 @@ static herr_t H5T__vlen_disk_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *seq_len) { const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR /* Check parameters */ - HDassert(f); HDassert(vl); HDassert(seq_len); /* Get length of sequence (different from blob size) */ UINT32DECODE(vl, *seq_len); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5T__vlen_disk_getlen() */ diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 1221d88..5ab1402 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -37,6 +37,9 @@ #define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ #define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +/* Container info version */ +#define H5VL_CONTAINER_INFO_VERSION 0x01 /* Container info struct version */ + /* The maximum size allowed for blobs */ #define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ @@ -94,10 +97,11 @@ typedef enum H5VL_datatype_specific_t { /* types for file GET callback */ typedef enum H5VL_file_get_t { + H5VL_FILE_GET_CONT_INFO, /* file get container info */ H5VL_FILE_GET_FAPL, /* file access property list */ H5VL_FILE_GET_FCPL, /* file creation property list */ - H5VL_FILE_GET_INTENT, /* file intent */ H5VL_FILE_GET_FILENO, /* file number */ + H5VL_FILE_GET_INTENT, /* file intent */ H5VL_FILE_GET_NAME, /* file name */ H5VL_FILE_GET_OBJ_COUNT, /* object count in file */ H5VL_FILE_GET_OBJ_IDS /* object ids in file */ @@ -179,56 +183,67 @@ typedef enum H5VL_blob_specific_t { H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ } H5VL_blob_specific_t; -/* types for different ways that objects are located in an HDF5 container */ +/* Types for different ways that objects are located in an HDF5 container */ typedef enum H5VL_loc_type_t { H5VL_OBJECT_BY_SELF, H5VL_OBJECT_BY_NAME, H5VL_OBJECT_BY_IDX, - H5VL_OBJECT_BY_ADDR, - H5VL_OBJECT_BY_REF + H5VL_OBJECT_BY_REF, + H5VL_OBJECT_BY_TOKEN } H5VL_loc_type_t; -struct H5VL_loc_by_name { +typedef struct H5VL_loc_by_name { const char *name; hid_t lapl_id; -}; +} H5VL_loc_by_name_t; -struct H5VL_loc_by_idx { +typedef struct H5VL_loc_by_idx { const char *name; H5_index_t idx_type; H5_iter_order_t order; hsize_t n; hid_t lapl_id; -}; - -struct H5VL_loc_by_addr { - haddr_t addr; -}; +} H5VL_loc_by_idx_t; -struct H5VL_loc_by_ref { +typedef struct H5VL_loc_by_ref { H5R_type_t ref_type; const void *_ref; hid_t lapl_id; -}; +} H5VL_loc_by_ref_t; + +typedef struct H5VL_loc_by_token { + void *token; +} H5VL_loc_by_token_t; /* Structure to hold parameters for object locations. - * either: BY_ADDR, BY_ID, BY_NAME, BY_IDX, BY_REF + * Either: BY_SELF, BY_NAME, BY_IDX, BY_REF, BY_TOKEN * - * Note: Leave loc_by_addr as the first union member so we + * Note: Leave loc_by_token as the first union member so we * can perform the simplest initialization of the struct * without raising warnings. + * + * Note: BY_SELF requires no union members. */ typedef struct H5VL_loc_params_t { H5I_type_t obj_type; H5VL_loc_type_t type; union{ - struct H5VL_loc_by_addr loc_by_addr; - struct H5VL_loc_by_name loc_by_name; - struct H5VL_loc_by_idx loc_by_idx; - struct H5VL_loc_by_ref loc_by_ref; + H5VL_loc_by_token_t loc_by_token; + H5VL_loc_by_name_t loc_by_name; + H5VL_loc_by_idx_t loc_by_idx; + H5VL_loc_by_ref_t loc_by_ref; } loc_data; } H5VL_loc_params_t; +/* Info for H5VL_FILE_GET_CONT_INFO */ +typedef struct H5VL_file_cont_info_t { + unsigned version; /* version information (keep first) */ + uint64_t feature_flags; /* Container feature flags */ + /* (none currently defined) */ + size_t token_size; /* Size of tokens */ + size_t blob_id_size; /* Size of blob IDs */ +} H5VL_file_cont_info_t; + /* VOL connector info fields & callbacks */ typedef struct H5VL_info_class_t { size_t size; /* Size of the VOL info */ diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 0ac70e3..9afb718 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -129,6 +129,18 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, FUNC_ENTER_PACKAGE switch(get_type) { + /* "get container info" */ + case H5VL_FILE_GET_CONT_INFO: + { + H5VL_file_cont_info_t *info = HDva_arg(arguments, H5VL_file_cont_info_t *); + + /* Retrieve the file's container info */ + if(H5F__get_cont_info((H5F_t *)obj, info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file container info") + + break; + } + /* H5Fget_access_plist */ case H5VL_FILE_GET_FAPL: { @@ -139,7 +151,7 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, /* Retrieve the file's access property list */ if((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file access property list") if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") @@ -163,42 +175,6 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, break; } - /* H5Fget_obj_count */ - case H5VL_FILE_GET_OBJ_COUNT: - { - unsigned types = HDva_arg(arguments, unsigned); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") - - /* Set the return value */ - *ret = (ssize_t)obj_count; - break; - } - - /* H5Fget_obj_ids */ - case H5VL_FILE_GET_OBJ_IDS: - { - unsigned types = HDva_arg(arguments, unsigned); - size_t max_objs = HDva_arg(arguments, size_t); - hid_t *oid_list = HDva_arg(arguments, hid_t *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") - - /* Set the return value */ - *ret = (ssize_t)obj_count; - break; - } - /* H5Fget_intent */ case H5VL_FILE_GET_INTENT: { @@ -266,6 +242,42 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, break; } + /* H5Fget_obj_count */ + case H5VL_FILE_GET_OBJ_COUNT: + { + unsigned types = HDva_arg(arguments, unsigned); + ssize_t *ret = HDva_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + + /* H5Fget_obj_ids */ + case H5VL_FILE_GET_OBJ_IDS: + { + unsigned types = HDva_arg(arguments, unsigned); + size_t max_objs = HDva_arg(arguments, size_t); + hid_t *oid_list = HDva_arg(arguments, hid_t *); + ssize_t *ret = HDva_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") } /* end switch */ diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index de2a8a5..ef8918d 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -71,10 +71,10 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ break; } - case H5VL_OBJECT_BY_ADDR: + case H5VL_OBJECT_BY_TOKEN: { /* Open the object */ - if(NULL == (ret_value = H5O_open_by_addr(&loc, loc_params->loc_data.loc_by_addr.addr, opened_type))) + if(NULL == (ret_value = H5O_open_by_addr(&loc, *(haddr_t *)loc_params->loc_data.loc_by_token.token, opened_type))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by address") break; } @@ -225,18 +225,6 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve object name") } /* end if */ - else if(loc_params->type == H5VL_OBJECT_BY_ADDR) { - H5O_loc_t obj_oloc; /* Object location */ - - /* Initialize the object location */ - H5O_loc_reset(&obj_oloc); - obj_oloc.file = loc.oloc->file; - obj_oloc.addr = loc_params->loc_data.loc_by_addr.addr; - - /* Retrieve object's name */ - if((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine object name") - } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_name parameters") break; diff --git a/src/H5trace.c b/src/H5trace.c index a167d43..fe2d622 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -2754,18 +2754,21 @@ H5_trace(const double *returning, const char *func, const char *type, ...) H5VL_file_get_t get = (H5VL_file_get_t)HDva_arg(ap, int); switch(get) { + case H5VL_FILE_GET_CONT_INFO: + HDfprintf(out, "H5VL_FILE_GET_CONT_INFO"); + break; case H5VL_FILE_GET_FAPL: HDfprintf(out, "H5VL_FILE_GET_FAPL"); break; case H5VL_FILE_GET_FCPL: HDfprintf(out, "H5VL_FILE_GET_FCPL"); break; - case H5VL_FILE_GET_INTENT: - HDfprintf(out, "H5VL_FILE_GET_INTENT"); - break; case H5VL_FILE_GET_FILENO: HDfprintf(out, "H5VL_FILE_GET_FILENO"); break; + case H5VL_FILE_GET_INTENT: + HDfprintf(out, "H5VL_FILE_GET_INTENT"); + break; case H5VL_FILE_GET_NAME: HDfprintf(out, "H5VL_FILE_GET_NAME"); break; -- cgit v0.12 From f4bc0af55cfe3fdbf2e9963849e84cf166f6d41d Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Tue, 10 Sep 2019 11:31:11 -0500 Subject: Add H5VL_MAX_TOKEN_SIZE and H5VL_token_t --- src/H5VLconnector.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 5ab1402..910136d 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -43,10 +43,17 @@ /* The maximum size allowed for blobs */ #define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ +/* The maximum size allowed for tokens */ +#define H5VL_MAX_TOKEN_SIZE (16) /* Allow for 128-bits tokens */ + /*******************/ /* Public Typedefs */ /*******************/ +/* type for tokens. Token are unique and permanent identifiers that are + * used to reference HDF5 objects. */ +typedef unsigned char H5VL_token_t[H5VL_MAX_TOKEN_SIZE]; + /* types for attribute GET callback */ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_ACPL, /* creation property list */ -- cgit v0.12 From fd4f6253ce5ed029263dfa47681fcd48fe2d1bc7 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Wed, 22 May 2019 13:32:25 -0500 Subject: Add H5VL_OBJECT_GET_TYPE to get object type Add H5VL_OBJECT_LOOKUP to lookup objects --- src/H5VLconnector.h | 4 +++- src/H5VLnative_object.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ src/H5trace.c | 6 ++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 910136d..6ec0aac 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -162,13 +162,15 @@ typedef enum H5VL_object_get_t { H5VL_REF_GET_NAME, /* object name, for reference */ H5VL_REF_GET_REGION, /* dataspace of region */ H5VL_REF_GET_TYPE, /* type of object */ - H5VL_OBJECT_GET_NAME /* object name */ + H5VL_OBJECT_GET_NAME, /* object name */ + H5VL_OBJECT_GET_TYPE /* object type */ } H5VL_object_get_t; /* types for object SPECIFIC callback */ typedef enum H5VL_object_specific_t { H5VL_OBJECT_CHANGE_REF_COUNT, /* H5Oincr/decr_refcount */ H5VL_OBJECT_EXISTS, /* H5Oexists_by_name */ + H5VL_OBJECT_LOOKUP, /* Lookup object */ H5VL_OBJECT_VISIT, /* H5Ovisit(_by_name) */ H5VL_REF_CREATE, /* H5Rcreate */ H5VL_OBJECT_FLUSH, /* H5{D|G|O|T}flush */ diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index ef8918d..a554a78 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -230,6 +230,29 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj break; } + /* Object type */ + case H5VL_OBJECT_GET_TYPE: + { + H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); + + if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { + H5O_loc_t obj_oloc; /* Object location */ + unsigned rc; /* Reference count of object */ + + /* Initialize the object location */ + H5O_loc_reset(&obj_oloc); + obj_oloc.file = loc.oloc->file; + obj_oloc.addr = *(haddr_t *)loc_params->loc_data.loc_by_token.token; + + /* Get the # of links for object, and its type */ + /* (To check to make certain that this object hasn't been deleted) */ + if(H5O_get_rc_and_type(&obj_oloc, &rc, obj_type) < 0 || 0 == rc) + HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") + } else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_type parameters") + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") } /* end switch */ @@ -288,6 +311,37 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V break; } + /* Lookup object */ + case H5VL_OBJECT_LOOKUP: + { + void *token = va_arg(arguments, void *); + + HDassert(token); + + if(loc_params->type == H5VL_OBJECT_BY_NAME) { + H5G_loc_t obj_loc; /* Group hier. location of object */ + H5G_name_t obj_path; /* Object group hier. path */ + H5O_loc_t obj_oloc; /* Object object location */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object */ + if(H5G_loc_find(&loc, loc_params->loc_data.loc_by_name.name, &obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + *(haddr_t *)token = obj_loc.oloc->addr; + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + break; + } + case H5VL_OBJECT_VISIT: { H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ diff --git a/src/H5trace.c b/src/H5trace.c index fe2d622..038263c 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -2966,6 +2966,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_OBJECT_GET_NAME: HDfprintf(out, "H5VL_OBJECT_GET_NAME"); break; + case H5VL_OBJECT_GET_TYPE: + HDfprintf(out, "H5VL_OBJECT_GET_TYPE"); + break; default: HDfprintf(out, "%ld", (long)get); break; @@ -2989,6 +2992,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_OBJECT_EXISTS: HDfprintf(out, "H5VL_OBJECT_EXISTS"); break; + case H5VL_OBJECT_LOOKUP: + HDfprintf(out, "H5VL_OBJECT_LOOKUP"); + break; case H5VL_OBJECT_VISIT: HDfprintf(out, "H5VL_OBJECT_VISIT"); break; -- cgit v0.12 From fcc1f0b7c747b5450a230e1a38f3fe062b4a97ca Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Fri, 30 Aug 2019 19:37:06 +0200 Subject: Add support for retrieving object name by token --- src/H5VLnative_object.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index a554a78..282a8ff 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -225,6 +225,18 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve object name") } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { + H5O_loc_t obj_oloc; /* Object location */ + + /* Initialize the object location */ + H5O_loc_reset(&obj_oloc); + obj_oloc.file = loc.oloc->file; + obj_oloc.addr = *(haddr_t *)loc_params->loc_data.loc_by_token.token; + + /* Retrieve object's name */ + if((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine object name") + } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_name parameters") break; -- cgit v0.12 From e9570c198b7950dd7459cd005068d772b33c7fd4 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Thu, 10 Jan 2019 19:58:17 -0600 Subject: Remove ability to loc by ref from H5VL layer --- src/H5VLconnector.h | 16 ++------- src/H5VLnative_object.c | 87 ------------------------------------------------- src/H5trace.c | 12 ------- 3 files changed, 2 insertions(+), 113 deletions(-) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 6ec0aac..3597751 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -159,9 +159,6 @@ typedef enum H5VL_link_specific_t { /* types for object GET callback */ typedef enum H5VL_object_get_t { - H5VL_REF_GET_NAME, /* object name, for reference */ - H5VL_REF_GET_REGION, /* dataspace of region */ - H5VL_REF_GET_TYPE, /* type of object */ H5VL_OBJECT_GET_NAME, /* object name */ H5VL_OBJECT_GET_TYPE /* object type */ } H5VL_object_get_t; @@ -172,7 +169,6 @@ typedef enum H5VL_object_specific_t { H5VL_OBJECT_EXISTS, /* H5Oexists_by_name */ H5VL_OBJECT_LOOKUP, /* Lookup object */ H5VL_OBJECT_VISIT, /* H5Ovisit(_by_name) */ - H5VL_REF_CREATE, /* H5Rcreate */ H5VL_OBJECT_FLUSH, /* H5{D|G|O|T}flush */ H5VL_OBJECT_REFRESH /* H5{D|G|O|T}refresh */ } H5VL_object_specific_t; @@ -197,7 +193,6 @@ typedef enum H5VL_loc_type_t { H5VL_OBJECT_BY_SELF, H5VL_OBJECT_BY_NAME, H5VL_OBJECT_BY_IDX, - H5VL_OBJECT_BY_REF, H5VL_OBJECT_BY_TOKEN } H5VL_loc_type_t; @@ -214,18 +209,12 @@ typedef struct H5VL_loc_by_idx { hid_t lapl_id; } H5VL_loc_by_idx_t; -typedef struct H5VL_loc_by_ref { - H5R_type_t ref_type; - const void *_ref; - hid_t lapl_id; -} H5VL_loc_by_ref_t; - typedef struct H5VL_loc_by_token { void *token; } H5VL_loc_by_token_t; /* Structure to hold parameters for object locations. - * Either: BY_SELF, BY_NAME, BY_IDX, BY_REF, BY_TOKEN + * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN * * Note: Leave loc_by_token as the first union member so we * can perform the simplest initialization of the struct @@ -236,11 +225,10 @@ typedef struct H5VL_loc_by_token { typedef struct H5VL_loc_params_t { H5I_type_t obj_type; H5VL_loc_type_t type; - union{ + union { H5VL_loc_by_token_t loc_by_token; H5VL_loc_by_name_t loc_by_name; H5VL_loc_by_idx_t loc_by_idx; - H5VL_loc_by_ref_t loc_by_ref; } loc_data; } H5VL_loc_params_t; diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index 282a8ff..3f56334 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -16,7 +16,6 @@ */ #define H5O_FRIEND /* Suppress error about including H5Opkg */ -#define H5R_FRIEND /* Suppress error about including H5Rpkg */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ @@ -25,7 +24,6 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ -#include "H5Rpkg.h" /* References */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ @@ -79,26 +77,6 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ break; } - case H5VL_OBJECT_BY_REF: - { - hid_t temp_id = H5I_INVALID_HID; - H5F_t *file = NULL; - - /* Get the file pointer from the entry */ - file = loc.oloc->file; - - /* Create reference */ - if((temp_id = H5R__dereference(file, loc_params->loc_data.loc_by_ref.lapl_id, - loc_params->loc_data.loc_by_ref.ref_type, - loc_params->loc_data.loc_by_ref._ref)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, NULL, "unable to dereference object") - - *opened_type = H5I_get_type(temp_id); - if(NULL == (ret_value = H5I_remove(temp_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") - break; - } - case H5VL_OBJECT_BY_SELF: default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown open parameters") @@ -166,53 +144,6 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") switch(get_type) { - /* H5Rget_region */ - case H5VL_REF_GET_REGION: - { - hid_t *ret = HDva_arg(arguments, hid_t *); - H5R_type_t H5_ATTR_UNUSED ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - H5S_t *space = NULL; /* Dataspace object */ - - /* Get the dataspace with the correct region selected */ - if((space = H5R__get_region(loc.oloc->file, ref)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve region") - - /* Atomize */ - if((*ret = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") - - break; - } - - /* H5Rget_obj_type1/2 */ - case H5VL_REF_GET_TYPE: - { - H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - - /* Get the object information */ - if(H5R__get_obj_type(loc.oloc->file, ref_type, ref, obj_type) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object type") - break; - } - - /* H5Rget_name */ - case H5VL_REF_GET_NAME: - { - ssize_t *ret = HDva_arg(arguments, ssize_t *); - char *name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - - /* Get name */ - if((*ret = H5R__get_name(loc.oloc->file, ref_type, ref, name, size)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object path") - break; - } - /* Object name */ case H5VL_OBJECT_GET_NAME: { @@ -401,24 +332,6 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V break; } - case H5VL_REF_CREATE: - { - void *ref = HDva_arg(arguments, void *); - const char *name = HDva_arg(arguments, char *); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - hid_t space_id = HDva_arg(arguments, hid_t); - H5S_t *space = NULL; /* Pointer to dataspace containing region */ - - if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - - /* Create reference */ - if(H5R__create(ref, &loc, name, ref_type, space) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create reference") - - break; - } - default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") } /* end switch */ diff --git a/src/H5trace.c b/src/H5trace.c index 038263c..2099383 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -2954,15 +2954,6 @@ H5_trace(const double *returning, const char *func, const char *type, ...) H5VL_object_get_t get = (H5VL_object_get_t)HDva_arg(ap, int); switch(get) { - case H5VL_REF_GET_REGION: - HDfprintf(out, "H5VL_REF_GET_REGION"); - break; - case H5VL_REF_GET_TYPE: - HDfprintf(out, "H5VL_REF_GET_TYPE"); - break; - case H5VL_REF_GET_NAME: - HDfprintf(out, "H5VL_REF_GET_NAME"); - break; case H5VL_OBJECT_GET_NAME: HDfprintf(out, "H5VL_OBJECT_GET_NAME"); break; @@ -2998,9 +2989,6 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_OBJECT_VISIT: HDfprintf(out, "H5VL_OBJECT_VISIT"); break; - case H5VL_REF_CREATE: - HDfprintf(out, "H5VL_REF_CREATE"); - break; case H5VL_OBJECT_FLUSH: HDfprintf(out, "H5VL_OBJECT_FLUSH"); break; -- cgit v0.12 From dabdcf95593aa97185c83006f35a0849ea012450 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Tue, 16 Jul 2019 11:15:43 -0500 Subject: Add new H5R API that abstracts object, region and attribute reference types Also support references to external files Add new H5T_REF type and type conversion routines Support conversion from H5T_REF_OBJ/DSET_REG to H5T_REF Add H5Treclaim() API to reclaim memory of vlen/reference types Deprecate H5Dvlen_reclaim() Fix H5T_vlen_reclaim() and H5T_reclaim() to use private callback Add H5T_ref_reclaim() Move previous H5R APIs to H5Rdeprec.c Clean up H5Ocopy Separate H5O_copy_expand_ref() to H5Ocopy_ref() Add support for copying new reference types Clean up deprecated routines to go through VOL and same code path Fix return codes in existing trefer.c test Rename trefer.c to trefer_deprec.c trefer.c is for new references Add performance test for trefer Add additional obj_copy_ref test Make use of tokens and blobs to store references Skip blob encoding for object references Start adding new reference examples --- MANIFEST | 10 +- bin/trace | 4 +- examples/CMakeLists.txt | 6 +- examples/Makefile.am | 16 +- examples/h5_ref2reg.c | 208 ---- examples/h5_ref2reg_deprec.c | 208 ++++ examples/h5_ref_compat.c | 90 ++ examples/h5_ref_extern.c | 94 ++ examples/h5_reference.c | 147 --- examples/h5_reference_deprec.c | 147 +++ examples/run-c-ex.sh.in | 12 +- src/CMakeLists.txt | 2 + src/H5Aint.c | 14 +- src/H5D.c | 50 - src/H5Dchunk.c | 12 +- src/H5Dcompact.c | 16 +- src/H5Dcontig.c | 9 +- src/H5Ddeprec.c | 50 + src/H5Dint.c | 46 +- src/H5Dio.c | 5 - src/H5Dprivate.h | 3 - src/H5Dpublic.h | 2 +- src/H5Ocopy.c | 198 ---- src/H5Ocopy_ref.c | 485 +++++++++ src/H5Odtype.c | 36 +- src/H5Ofill.c | 2 +- src/H5Oprivate.h | 4 +- src/H5Pint.c | 38 +- src/H5Pprivate.h | 1 + src/H5Ppublic.h | 4 + src/H5R.c | 973 ++++++++++++----- src/H5Rdeprec.c | 498 +++++++-- src/H5Rint.c | 1856 ++++++++++++++++++++++++-------- src/H5Rpkg.h | 80 +- src/H5Rprivate.h | 3 +- src/H5Rpublic.h | 106 +- src/H5S.c | 5 +- src/H5T.c | 169 ++- src/H5Tconv.c | 273 +++++ src/H5Tnative.c | 25 +- src/H5Tpkg.h | 87 +- src/H5Tprivate.h | 8 +- src/H5Tpublic.h | 5 +- src/H5Tref.c | 761 +++++++++++++ src/H5Tvlen.c | 127 +-- src/H5VLnative_file.c | 1 - src/H5detect.c | 16 +- src/H5trace.c | 78 +- src/Makefile.am | 3 +- test/CMakeLists.txt | 2 + test/Makefile.am | 6 +- test/objcopy_ref.c | 1739 ++++++++++++++++++++++++++++++ test/testhdf5.c | 3 +- test/testhdf5.h | 2 + test/trefer.c | 2306 +++++++++++++++++++++++++++++----------- test/trefer_deprec.c | 1827 +++++++++++++++++++++++++++++++ 56 files changed, 10511 insertions(+), 2367 deletions(-) delete mode 100644 examples/h5_ref2reg.c create mode 100644 examples/h5_ref2reg_deprec.c create mode 100644 examples/h5_ref_compat.c create mode 100644 examples/h5_ref_extern.c delete mode 100644 examples/h5_reference.c create mode 100644 examples/h5_reference_deprec.c create mode 100644 src/H5Ocopy_ref.c create mode 100644 src/H5Tref.c create mode 100644 test/objcopy_ref.c create mode 100644 test/trefer_deprec.c diff --git a/MANIFEST b/MANIFEST index 5e7caff..a1b3b4a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -167,8 +167,10 @@ ./examples/h5_select.c ./examples/h5_attribute.c ./examples/h5_mount.c -./examples/h5_reference.c -./examples/h5_ref2reg.c +./examples/h5_ref_compat.c +./examples/h5_ref_extern.c +./examples/h5_reference_deprec.c +./examples/h5_ref2reg_deprec.c ./examples/h5_shared_mesg.c ./examples/ph5example.c ./examples/h5_vds.c @@ -782,6 +784,7 @@ ./src/H5Ochunk.c ./src/H5Ocont.c ./src/H5Ocopy.c +./src/H5Ocopy_ref.c ./src/H5Odbg.c ./src/H5Odeprec.c ./src/H5Odrvinfo.c @@ -911,6 +914,7 @@ ./src/H5Tprecis.c ./src/H5Tprivate.h ./src/H5Tpublic.h +./src/H5Tref.c ./src/H5Tstrpad.c ./src/H5Tvisit.c ./src/H5Tvlen.c @@ -1107,6 +1111,7 @@ ./test/null_vol_connector.h ./test/ohdr.c ./test/objcopy.c +./test/objcopy_ref.c ./test/page_buffer.c ./test/paged_nopersist.h5 ./test/paged_persist.h5 @@ -1176,6 +1181,7 @@ ./test/tmtimeo.h5 ./test/ttime.c ./test/trefer.c +./test/trefer_deprec.c ./test/trefstr.c ./test/tselect.c ./test/tsizeslheap.h5 diff --git a/bin/trace b/bin/trace index fe0443d..3cae0a4 100755 --- a/bin/trace +++ b/bin/trace @@ -78,7 +78,9 @@ $Source = ""; "off_t" => "o", "H5O_type_t" => "Ot", "H5P_class_t" => "p", - "hobj_ref_t" => "r", + "hobj_ref_t" => "Ro", + "hdset_reg_ref_t" => "Rd", + "H5R_ref_t" => "Rr", "H5R_type_t" => "Rt", "char" => "s", "unsigned char" => "s", diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6e1f79d..9f42f95 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,9 +23,11 @@ set (examples h5_select h5_attribute h5_mount - h5_reference + h5_ref_extern + h5_ref_compat + h5_reference_deprec h5_drivers - h5_ref2reg + h5_ref2reg_deprec h5_extlink h5_elink_unix2win h5_shared_mesg diff --git a/examples/Makefile.am b/examples/Makefile.am index 554ee44..131842c 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -34,8 +34,9 @@ INSTALL_TOP_FILES = README EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \ h5_crtgrpd h5_subset h5_cmprss h5_rdwt h5_crtgrpar h5_extend \ h5_crtatt h5_crtgrp h5_crtdat \ - h5_group h5_select h5_attribute h5_mount h5_reference h5_drivers \ - h5_ref2reg h5_extlink h5_elink_unix2win h5_shared_mesg h5_vds h5_vds-exc \ + h5_group h5_select h5_attribute h5_mount h5_reference_deprec h5_drivers \ + h5_ref_extern h5_ref_compat \ + h5_ref2reg_deprec h5_extlink h5_elink_unix2win h5_shared_mesg h5_vds h5_vds-exc \ h5_vds-exclim h5_vds-eiger h5_vds-simpleIO h5_vds-percival \ h5_vds-percival-unlim h5_vds-percival-unlim-maxmin TEST_SCRIPT=testh5cc.sh @@ -47,8 +48,9 @@ INSTALL_FILES = h5_write.c h5_read.c h5_extend_write.c h5_chunk_read.c \ h5_crtgrpd.c h5_subset.c h5_cmprss.c h5_rdwt.c h5_crtgrpar.c \ h5_extend.c h5_crtatt.c h5_crtgrp.c h5_crtdat.c \ h5_compound.c h5_group.c h5_select.c h5_attribute.c h5_mount.c \ - h5_reference.c h5_drivers.c h5_extlink.c h5_elink_unix2win.c \ - h5_ref2reg.c h5_shared_mesg.c ph5example.c h5_vds.c h5_vds-exc.c \ + h5_reference_deprec.c h5_drivers.c h5_extlink.c h5_elink_unix2win.c \ + h5_ref_extern.c h5_ref_compat.c \ + h5_ref2reg_deprec.c h5_shared_mesg.c ph5example.c h5_vds.c h5_vds-exc.c \ h5_vds-exclim.c h5_vds-eiger.c h5_vds-simpleIO.c h5_vds-percival.c \ h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin.c @@ -111,8 +113,10 @@ h5_read: $(srcdir)/h5_read.c h5_select: $(srcdir)/h5_select.c h5_attribute: $(srcdir)/h5_attribute.c h5_mount: $(srcdir)/h5_mount.c -h5_reference: $(srcdir)/h5_reference.c -h5_ref2reg: $(srcdir)/h5_ref2reg.c +h5_ref_compat: $(srcdir)/h5_ref_compat.c +h5_ref_extern: $(srcdir)/h5_ref_extern.c +h5_reference_deprec: $(srcdir)/h5_reference_deprec.c +h5_ref2reg_deprec: $(srcdir)/h5_ref2reg_deprec.c h5_drivers: $(srcdir)/h5_drivers.c ph5example: $(srcdir)/ph5example.c h5_dtransform: $(srcdir)/h5_dtransform.c diff --git a/examples/h5_ref2reg.c b/examples/h5_ref2reg.c deleted file mode 100644 index dc2964c..0000000 --- a/examples/h5_ref2reg.c +++ /dev/null @@ -1,208 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* - This program shows how to create, store and dereference references - to the dataset regions. - - It creates a file and writes a two dimensional integer dataset - to it. Then it creates a dataset to store region references in. It - stores references to a hyperslab and 3 points selected (for the - integer dataset previously created). - - It then reopens the references dataset, reads and dereferences the - region references, and then reads and displays the selected hyperslab - and selected elements data from the integer dataset. -*/ - -#include "hdf5.h" - -#define filename "REF_REG.h5" -#define dsetnamev "MATRIX" -#define dsetnamer "REGION_REFERENCES" - -int main(void) -{ - hid_t file_id; /* file identifier */ - hid_t space_id; /* dataspace identifiers */ - hid_t spacer_id; - hid_t dsetv_id; /*dataset identifiers*/ - hid_t dsetr_id; - hsize_t dims[2] = {2,9}; - hsize_t dimsr[1] = {2}; - int rank = 2; - int rankr =1; - herr_t status; - hdset_reg_ref_t ref[2]; - hdset_reg_ref_t ref_out[2]; - int data[2][9] = {{1,1,2,3,3,4,5,5,6},{1,2,2,3,4,4,5,6,6}}; - int data_out[2][9] = {{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0}}; - hsize_t start[2]; - hsize_t count[2]; - hsize_t coord[2][3] = {{0, 0, 1}, {6, 0, 8}}; - unsigned num_points = 3; - int i, j; - size_t name_size1, name_size2; - char buf1[10], buf2[10]; - - /* - * Create file with default file access and file creation properties. - */ - file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Create dataspace for datasets. - */ - space_id = H5Screate_simple(rank, dims, NULL); - spacer_id = H5Screate_simple(rankr, dimsr, NULL); - - /* - * Create integer dataset. - */ - dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Write data to the dataset. - */ - status = H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data); - status = H5Dclose(dsetv_id); - - /* - * Dataset with references. - */ - dsetr_id = H5Dcreate2(file_id, dsetnamer, H5T_STD_REF_DSETREG, spacer_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Create a reference to the hyperslab. - */ - start[0] = 0; - start[1] = 3; - count[0] = 2; - count[1] = 3; - status = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, NULL, count, NULL); - status = H5Rcreate(&ref[0], file_id, dsetnamev, H5R_DATASET_REGION, space_id); - - /* - * Create a reference to elements selection. - */ - status = H5Sselect_none(space_id); - status = H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord); - status = H5Rcreate(&ref[1], file_id, dsetnamev, H5R_DATASET_REGION, space_id); - - /* - * Write dataset with the references. - */ - status = H5Dwrite(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref); - - /* - * Close all objects. - */ - status = H5Sclose(space_id); - status = H5Sclose(spacer_id); - status = H5Dclose(dsetr_id); - status = H5Fclose(file_id); - - /* - * Reopen the file to read selections back. - */ - file_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); - - /* - * Reopen the dataset with object references and read references - * to the buffer. - */ - dsetr_id = H5Dopen2(file_id, dsetnamer, H5P_DEFAULT); - - status = H5Dread(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, - H5P_DEFAULT, ref_out); - - /* - * Dereference the first reference. - */ - dsetv_id = H5Rdereference2(dsetr_id, H5P_DEFAULT, H5R_DATASET_REGION, &ref_out[0]); - /* - * Get name of the dataset the first region reference points to - * using H5Rget_name - */ - name_size1 = H5Rget_name(dsetr_id, H5R_DATASET_REGION, &ref_out[0], (char*)buf1, 10); - printf(" Dataset's name (returned by H5Rget_name) the reference points to is %s, name length is %d\n", buf1, (int)name_size1); - /* - * Get name of the dataset the first region reference points to - * using H5Iget_name - */ - name_size2 = H5Iget_name(dsetv_id, (char*)buf2, 10); - printf(" Dataset's name (returned by H5Iget_name) the reference points to is %s, name length is %d\n", buf2, (int)name_size2); - - space_id = H5Rget_region(dsetr_id, H5R_DATASET_REGION,&ref_out[0]); - - /* - * Read and display hyperslab selection from the dataset. - */ - - status = H5Dread(dsetv_id, H5T_NATIVE_INT, H5S_ALL, space_id, - H5P_DEFAULT, data_out); - printf("Selected hyperslab: "); - for (i = 0; i <= 1; i++) - { - printf("\n"); - for (j = 0; j <= 8; j++) - printf("%d ", data_out[i][j]); - } - printf("\n"); - - /* - * Close dataspace and the dataset. - */ - status = H5Sclose(space_id); - status = H5Dclose(dsetv_id); - - /* - * Initialize data_out array again to get point selection. - */ - for (i = 0; i <= 1; i++) - for (j = 0; j <= 8; j++) - data_out[i][j] = 0; - - /* - * Dereference the second reference. - */ - dsetv_id = H5Rdereference2(dsetr_id, H5P_DEFAULT, H5R_DATASET_REGION, &ref_out[1]); - space_id = H5Rget_region(dsetv_id, H5R_DATASET_REGION,&ref_out[1]); - - /* - * Read selected data from the dataset. - */ - - status = H5Dread(dsetv_id, H5T_NATIVE_INT, H5S_ALL, space_id, - H5P_DEFAULT, data_out); - printf("Selected points: "); - for (i = 0; i <= 1; i++) - { - printf("\n"); - for (j = 0; j <= 8; j++) - printf("%d ", data_out[i][j]); - } - printf("\n"); - - /* - * Close dataspace and the dataset. - */ - status = H5Sclose(space_id); - status = H5Dclose(dsetv_id); - status = H5Dclose(dsetr_id); - status = H5Fclose(file_id); - - return 0; -} - - - diff --git a/examples/h5_ref2reg_deprec.c b/examples/h5_ref2reg_deprec.c new file mode 100644 index 0000000..dc2964c --- /dev/null +++ b/examples/h5_ref2reg_deprec.c @@ -0,0 +1,208 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* + This program shows how to create, store and dereference references + to the dataset regions. + + It creates a file and writes a two dimensional integer dataset + to it. Then it creates a dataset to store region references in. It + stores references to a hyperslab and 3 points selected (for the + integer dataset previously created). + + It then reopens the references dataset, reads and dereferences the + region references, and then reads and displays the selected hyperslab + and selected elements data from the integer dataset. +*/ + +#include "hdf5.h" + +#define filename "REF_REG.h5" +#define dsetnamev "MATRIX" +#define dsetnamer "REGION_REFERENCES" + +int main(void) +{ + hid_t file_id; /* file identifier */ + hid_t space_id; /* dataspace identifiers */ + hid_t spacer_id; + hid_t dsetv_id; /*dataset identifiers*/ + hid_t dsetr_id; + hsize_t dims[2] = {2,9}; + hsize_t dimsr[1] = {2}; + int rank = 2; + int rankr =1; + herr_t status; + hdset_reg_ref_t ref[2]; + hdset_reg_ref_t ref_out[2]; + int data[2][9] = {{1,1,2,3,3,4,5,5,6},{1,2,2,3,4,4,5,6,6}}; + int data_out[2][9] = {{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0}}; + hsize_t start[2]; + hsize_t count[2]; + hsize_t coord[2][3] = {{0, 0, 1}, {6, 0, 8}}; + unsigned num_points = 3; + int i, j; + size_t name_size1, name_size2; + char buf1[10], buf2[10]; + + /* + * Create file with default file access and file creation properties. + */ + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create dataspace for datasets. + */ + space_id = H5Screate_simple(rank, dims, NULL); + spacer_id = H5Screate_simple(rankr, dimsr, NULL); + + /* + * Create integer dataset. + */ + dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Write data to the dataset. + */ + status = H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data); + status = H5Dclose(dsetv_id); + + /* + * Dataset with references. + */ + dsetr_id = H5Dcreate2(file_id, dsetnamer, H5T_STD_REF_DSETREG, spacer_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create a reference to the hyperslab. + */ + start[0] = 0; + start[1] = 3; + count[0] = 2; + count[1] = 3; + status = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, NULL, count, NULL); + status = H5Rcreate(&ref[0], file_id, dsetnamev, H5R_DATASET_REGION, space_id); + + /* + * Create a reference to elements selection. + */ + status = H5Sselect_none(space_id); + status = H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord); + status = H5Rcreate(&ref[1], file_id, dsetnamev, H5R_DATASET_REGION, space_id); + + /* + * Write dataset with the references. + */ + status = H5Dwrite(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref); + + /* + * Close all objects. + */ + status = H5Sclose(space_id); + status = H5Sclose(spacer_id); + status = H5Dclose(dsetr_id); + status = H5Fclose(file_id); + + /* + * Reopen the file to read selections back. + */ + file_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT); + + /* + * Reopen the dataset with object references and read references + * to the buffer. + */ + dsetr_id = H5Dopen2(file_id, dsetnamer, H5P_DEFAULT); + + status = H5Dread(dsetr_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, + H5P_DEFAULT, ref_out); + + /* + * Dereference the first reference. + */ + dsetv_id = H5Rdereference2(dsetr_id, H5P_DEFAULT, H5R_DATASET_REGION, &ref_out[0]); + /* + * Get name of the dataset the first region reference points to + * using H5Rget_name + */ + name_size1 = H5Rget_name(dsetr_id, H5R_DATASET_REGION, &ref_out[0], (char*)buf1, 10); + printf(" Dataset's name (returned by H5Rget_name) the reference points to is %s, name length is %d\n", buf1, (int)name_size1); + /* + * Get name of the dataset the first region reference points to + * using H5Iget_name + */ + name_size2 = H5Iget_name(dsetv_id, (char*)buf2, 10); + printf(" Dataset's name (returned by H5Iget_name) the reference points to is %s, name length is %d\n", buf2, (int)name_size2); + + space_id = H5Rget_region(dsetr_id, H5R_DATASET_REGION,&ref_out[0]); + + /* + * Read and display hyperslab selection from the dataset. + */ + + status = H5Dread(dsetv_id, H5T_NATIVE_INT, H5S_ALL, space_id, + H5P_DEFAULT, data_out); + printf("Selected hyperslab: "); + for (i = 0; i <= 1; i++) + { + printf("\n"); + for (j = 0; j <= 8; j++) + printf("%d ", data_out[i][j]); + } + printf("\n"); + + /* + * Close dataspace and the dataset. + */ + status = H5Sclose(space_id); + status = H5Dclose(dsetv_id); + + /* + * Initialize data_out array again to get point selection. + */ + for (i = 0; i <= 1; i++) + for (j = 0; j <= 8; j++) + data_out[i][j] = 0; + + /* + * Dereference the second reference. + */ + dsetv_id = H5Rdereference2(dsetr_id, H5P_DEFAULT, H5R_DATASET_REGION, &ref_out[1]); + space_id = H5Rget_region(dsetv_id, H5R_DATASET_REGION,&ref_out[1]); + + /* + * Read selected data from the dataset. + */ + + status = H5Dread(dsetv_id, H5T_NATIVE_INT, H5S_ALL, space_id, + H5P_DEFAULT, data_out); + printf("Selected points: "); + for (i = 0; i <= 1; i++) + { + printf("\n"); + for (j = 0; j <= 8; j++) + printf("%d ", data_out[i][j]); + } + printf("\n"); + + /* + * Close dataspace and the dataset. + */ + status = H5Sclose(space_id); + status = H5Dclose(dsetv_id); + status = H5Dclose(dsetr_id); + status = H5Fclose(file_id); + + return 0; +} + + + diff --git a/examples/h5_ref_compat.c b/examples/h5_ref_compat.c new file mode 100644 index 0000000..a1fbf96 --- /dev/null +++ b/examples/h5_ref_compat.c @@ -0,0 +1,90 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * The example below illustrates the use of the new API with a file that was + * written using the old-style reference API, showing how one can take + * advantage of the automatic type conversion from old reference type to new + * reference type. + */ + +#include + +#include "hdf5.h" +#include + +#define H5FILE_NAME "refer_deprec.h5" + +#define NDIMS 1 /* Number of dimensions */ +#define BUF_SIZE 4 /* Size of example buffer */ +#define NREFS 1 /* Number of references */ + +int +main(void) { + hid_t file1, dset1, space1; + hsize_t dset1_dims[NDIMS] = { BUF_SIZE }; + int dset_buf[BUF_SIZE]; + + hid_t dset2, space2; + hsize_t dset2_dims[NDIMS] = { NREFS }; + hobj_ref_t ref_buf[NREFS] = { 0 }; + H5R_ref_t new_ref_buf[NREFS] = { 0 }; + H5O_type_t obj_type; + int i; + + for (i = 0; i < BUF_SIZE; i++) + dset_buf[i] = i; + + /* Create file with one dataset and close it */ + file1 = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + space1 = H5Screate_simple(NDIMS, dset1_dims, NULL); + dset1 = H5Dcreate2(file1, "dataset1", H5T_NATIVE_INT, space1, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_buf); + H5Dclose(dset1); + H5Sclose(space1); + + /** + * Create reference to dataset1 with deprecated API + * (reminder: there is no destroy call for those references) + */ + H5Rcreate(&ref_buf[0], file1, "dataset1", H5R_OBJECT, H5I_INVALID_HID); + + /* Store reference in separate dataset using deprecated reference type */ + space2 = H5Screate_simple(NDIMS, dset2_dims, NULL); + dset2 = H5Dcreate2(file1, "references", H5T_STD_REF_OBJ, space2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Dwrite(dset2, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_buf); + H5Dclose(dset2); + H5Sclose(space2); + H5Fclose(file1); + + /* Read reference from file using new reference type */ + file1 = H5Fopen(H5FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT); + dset2 = H5Dopen2(file1, "references", H5P_DEFAULT); + H5Dread(dset2, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, new_ref_buf); + H5Dclose(dset2); + + /* Access reference and read dataset data through new API */ + assert(H5Rget_type((const H5R_ref_t *)&new_ref_buf[0]) == H5R_OBJECT2); + H5Rget_obj_type3((const H5R_ref_t *)&new_ref_buf[0], H5P_DEFAULT, &obj_type); + assert(obj_type == H5O_TYPE_DATASET); + dset1 = H5Ropen_object((const H5R_ref_t *)&new_ref_buf[0], H5P_DEFAULT, H5P_DEFAULT); + H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_buf); + H5Dclose(dset1); + H5Rdestroy(&new_ref_buf[0]); + + for (i = 0; i < BUF_SIZE; i++) + assert(dset_buf[i] == i); + return 0; +} + diff --git a/examples/h5_ref_extern.c b/examples/h5_ref_extern.c new file mode 100644 index 0000000..4327a06 --- /dev/null +++ b/examples/h5_ref_extern.c @@ -0,0 +1,94 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * The example below illustrates the use of the new API with files that are + * opened read-only. Created references to the objects in that file are + * stored into a separate file, and accessed from that file, without the user + * explicitly opening the original file that was referenced. + */ + +#include + +#include "hdf5.h" +#include + +#define H5FILE_NAME1 "refer_extern1.h5" +#define H5FILE_NAME2 "refer_extern2.h5" + +#define NDIMS 1 /* Number of dimensions */ +#define BUF_SIZE 4 /* Size of example buffer */ +#define NREFS 1 /* Number of references */ + +int +main(void) { + hid_t file1, dset1, space1; + hsize_t dset1_dims[NDIMS] = { BUF_SIZE }; + int dset_buf[BUF_SIZE]; + + hid_t file2, dset2, space2; + hsize_t dset2_dims[NDIMS] = { NREFS }; + H5R_ref_t ref_buf[NREFS] = { 0 }; + H5O_type_t obj_type; + int i; + + for (i = 0; i < BUF_SIZE; i++) + dset_buf[i] = i; + + /* Create file with one dataset and close it */ + file1 = H5Fcreate(H5FILE_NAME1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + space1 = H5Screate_simple(NDIMS, dset1_dims, NULL); + dset1 = H5Dcreate2(file1, "dataset1", H5T_NATIVE_INT, space1, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_buf); + H5Dclose(dset1); + H5Sclose(space1); + H5Fclose(file1); + + /* Create reference to dataset1 in "refer_extern1.h5" */ + file1 = H5Fopen(H5FILE_NAME1, H5F_ACC_RDONLY, H5P_DEFAULT); + H5Rcreate_object(file1, "dataset1", &ref_buf[0]); + H5Fclose(file1); + + /* Store reference in dataset in separate file "refer_extern2.h5" */ + file2 = H5Fcreate(H5FILE_NAME2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + space2 = H5Screate_simple(NDIMS, dset2_dims, NULL); + dset2 = H5Dcreate2(file2, "references", H5T_STD_REF, space2, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + H5Dwrite(dset2, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_buf); + H5Dclose(dset2); + H5Sclose(space2); + H5Fclose(file2); + H5Rdestroy(&ref_buf[0]); + + /* Read reference back from "refer_extern2.h5" */ + file2 = H5Fopen(H5FILE_NAME2, H5F_ACC_RDONLY, H5P_DEFAULT); + dset2 = H5Dopen2(file2, "references", H5P_DEFAULT); + H5Dread(dset2, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_buf); + H5Dclose(dset2); + H5Fclose(file2); + + /* Access reference and read dataset data without opening original file */ + assert(H5Rget_type((const H5R_ref_t *)&ref_buf[0]) == H5R_OBJECT2); + H5Rget_obj_type3((const H5R_ref_t *)&ref_buf[0], H5P_DEFAULT, &obj_type); + assert(obj_type == H5O_TYPE_DATASET); + dset1 = H5Ropen_object((const H5R_ref_t *)&ref_buf[0], H5P_DEFAULT, H5P_DEFAULT); + H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_buf); + H5Dclose(dset1); + H5Rdestroy(&ref_buf[0]); + + for (i = 0; i < BUF_SIZE; i++) + assert(dset_buf[i] == i); + + return 0; +} + diff --git a/examples/h5_reference.c b/examples/h5_reference.c deleted file mode 100644 index 32a5f59..0000000 --- a/examples/h5_reference.c +++ /dev/null @@ -1,147 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - /* - * This program illustrates how references to objects can be used. - * Program creates a dataset and a group in a file. It also creates - * second dataset, and references to the first dataset and the group - * are stored in it. - * Program reopens the file and reads dataset with the references. - * References are used to open the objects. Information about the - * objects is displayed. - */ - -#include - -#include "hdf5.h" - -#define H5FILE_NAME "refere.h5" - -int -main(void) { - hid_t fid; /* File, group, datasets, datatypes */ - hid_t gid_a; /* and dataspaces identifiers */ - hid_t did_b, sid_b, tid_b; - hid_t did_r, tid_r, sid_r; - H5O_type_t obj_type; - herr_t status; - - hobj_ref_t *wbuf; /* buffer to write to disk */ - hobj_ref_t *rbuf; /* buffer to read from disk */ - - - hsize_t dim_r[1]; - hsize_t dim_b[2]; - - /* - * Create a file using default properties. - */ - fid = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Create group "A" in the file. - */ - gid_a = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Create dataset "B" in the file. - */ - dim_b[0] = 2; - dim_b[1] = 6; - sid_b = H5Screate_simple(2, dim_b, NULL); - did_b = H5Dcreate2(fid, "B", H5T_NATIVE_FLOAT, sid_b, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Create dataset "R" to store references to the objects "A" and "B". - */ - dim_r[0] = 2; - sid_r = H5Screate_simple(1, dim_r, NULL); - tid_r = H5Tcopy(H5T_STD_REF_OBJ); - did_r = H5Dcreate2(fid, "R", tid_r, sid_r, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - /* - * Allocate write and read buffers. - */ - wbuf = (hobj_ref_t *)malloc(sizeof(hobj_ref_t) * 2); - rbuf = (hobj_ref_t *)malloc(sizeof(hobj_ref_t) * 2); - - /* - * Create references to the group "A" and dataset "B" - * and store them in the wbuf. - */ - H5Rcreate(&wbuf[0], fid, "A", H5R_OBJECT, (hid_t)-1); - H5Rcreate(&wbuf[1], fid, "B", H5R_OBJECT, (hid_t)-1); - - /* - * Write dataset R using default transfer properties. - */ - status = H5Dwrite(did_r, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); - - /* - * Close all objects. - */ - H5Gclose(gid_a); - - H5Sclose(sid_b); - H5Dclose(did_b); - - H5Tclose(tid_r); - H5Sclose(sid_r); - H5Dclose(did_r); - - H5Fclose(fid); - - /* - * Reopen the file. - */ - fid = H5Fopen(H5FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT); - - /* - * Open and read dataset "R". - */ - did_r = H5Dopen2(fid, "R", H5P_DEFAULT); - status = H5Dread(did_r, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); - - /* - * Find the type of referenced objects. - */ - status = H5Rget_obj_type2(did_r, H5R_OBJECT, &rbuf[0], &obj_type); - if(obj_type == H5O_TYPE_GROUP) - printf("First dereferenced object is a group. \n"); - - status = H5Rget_obj_type2(did_r, H5R_OBJECT, &rbuf[1], &obj_type); - if(obj_type == H5O_TYPE_DATASET) - printf("Second dereferenced object is a dataset. \n"); - - /* - * Get datatype of the dataset "B" - */ - did_b = H5Rdereference2(did_r, H5P_DEFAULT, H5R_OBJECT, &rbuf[1]); - tid_b = H5Dget_type(did_b); - if(H5Tequal(tid_b, H5T_NATIVE_FLOAT)) - printf("Datatype of the dataset is H5T_NATIVE_FLOAT.\n"); - printf("\n"); - - /* - * Close all objects and free memory buffers. - */ - H5Dclose(did_r); - H5Dclose(did_b); - H5Tclose(tid_b); - H5Fclose(fid); - free(rbuf); - free(wbuf); - - return 0; - } - diff --git a/examples/h5_reference_deprec.c b/examples/h5_reference_deprec.c new file mode 100644 index 0000000..32a5f59 --- /dev/null +++ b/examples/h5_reference_deprec.c @@ -0,0 +1,147 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * This program illustrates how references to objects can be used. + * Program creates a dataset and a group in a file. It also creates + * second dataset, and references to the first dataset and the group + * are stored in it. + * Program reopens the file and reads dataset with the references. + * References are used to open the objects. Information about the + * objects is displayed. + */ + +#include + +#include "hdf5.h" + +#define H5FILE_NAME "refere.h5" + +int +main(void) { + hid_t fid; /* File, group, datasets, datatypes */ + hid_t gid_a; /* and dataspaces identifiers */ + hid_t did_b, sid_b, tid_b; + hid_t did_r, tid_r, sid_r; + H5O_type_t obj_type; + herr_t status; + + hobj_ref_t *wbuf; /* buffer to write to disk */ + hobj_ref_t *rbuf; /* buffer to read from disk */ + + + hsize_t dim_r[1]; + hsize_t dim_b[2]; + + /* + * Create a file using default properties. + */ + fid = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create group "A" in the file. + */ + gid_a = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create dataset "B" in the file. + */ + dim_b[0] = 2; + dim_b[1] = 6; + sid_b = H5Screate_simple(2, dim_b, NULL); + did_b = H5Dcreate2(fid, "B", H5T_NATIVE_FLOAT, sid_b, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create dataset "R" to store references to the objects "A" and "B". + */ + dim_r[0] = 2; + sid_r = H5Screate_simple(1, dim_r, NULL); + tid_r = H5Tcopy(H5T_STD_REF_OBJ); + did_r = H5Dcreate2(fid, "R", tid_r, sid_r, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Allocate write and read buffers. + */ + wbuf = (hobj_ref_t *)malloc(sizeof(hobj_ref_t) * 2); + rbuf = (hobj_ref_t *)malloc(sizeof(hobj_ref_t) * 2); + + /* + * Create references to the group "A" and dataset "B" + * and store them in the wbuf. + */ + H5Rcreate(&wbuf[0], fid, "A", H5R_OBJECT, (hid_t)-1); + H5Rcreate(&wbuf[1], fid, "B", H5R_OBJECT, (hid_t)-1); + + /* + * Write dataset R using default transfer properties. + */ + status = H5Dwrite(did_r, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + + /* + * Close all objects. + */ + H5Gclose(gid_a); + + H5Sclose(sid_b); + H5Dclose(did_b); + + H5Tclose(tid_r); + H5Sclose(sid_r); + H5Dclose(did_r); + + H5Fclose(fid); + + /* + * Reopen the file. + */ + fid = H5Fopen(H5FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT); + + /* + * Open and read dataset "R". + */ + did_r = H5Dopen2(fid, "R", H5P_DEFAULT); + status = H5Dread(did_r, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + + /* + * Find the type of referenced objects. + */ + status = H5Rget_obj_type2(did_r, H5R_OBJECT, &rbuf[0], &obj_type); + if(obj_type == H5O_TYPE_GROUP) + printf("First dereferenced object is a group. \n"); + + status = H5Rget_obj_type2(did_r, H5R_OBJECT, &rbuf[1], &obj_type); + if(obj_type == H5O_TYPE_DATASET) + printf("Second dereferenced object is a dataset. \n"); + + /* + * Get datatype of the dataset "B" + */ + did_b = H5Rdereference2(did_r, H5P_DEFAULT, H5R_OBJECT, &rbuf[1]); + tid_b = H5Dget_type(did_b); + if(H5Tequal(tid_b, H5T_NATIVE_FLOAT)) + printf("Datatype of the dataset is H5T_NATIVE_FLOAT.\n"); + printf("\n"); + + /* + * Close all objects and free memory buffers. + */ + H5Dclose(did_r); + H5Dclose(did_b); + H5Tclose(tid_b); + H5Fclose(fid); + free(rbuf); + free(wbuf); + + return 0; + } + diff --git a/examples/run-c-ex.sh.in b/examples/run-c-ex.sh.in index 209cdd7..a70117f 100644 --- a/examples/run-c-ex.sh.in +++ b/examples/run-c-ex.sh.in @@ -112,12 +112,16 @@ then rm h5_attribute &&\ RunTest h5_mount &&\ rm h5_mount &&\ - RunTest h5_reference &&\ - rm h5_reference &&\ + RunTest h5_reference_deprec &&\ + rm h5_reference_deprec &&\ + RunTest h5_ref_extern &&\ + rm h5_ref_extern &&\ + RunTest h5_ref_compat &&\ + rm h5_ref_compat &&\ RunTest h5_drivers &&\ rm h5_drivers &&\ - RunTest h5_ref2reg &&\ - rm h5_ref2reg &&\ + RunTest h5_ref2reg_deprec &&\ + rm h5_ref2reg_deprec &&\ RunTest h5_extlink &&\ rm h5_extlink &&\ RunTest h5_elink_unix2win &&\ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b50fa71..9bb73a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -446,6 +446,7 @@ set (H5O_SOURCES ${HDF5_SRC_DIR}/H5Ochunk.c ${HDF5_SRC_DIR}/H5Ocont.c ${HDF5_SRC_DIR}/H5Ocopy.c + ${HDF5_SRC_DIR}/H5Ocopy_ref.c ${HDF5_SRC_DIR}/H5Odbg.c ${HDF5_SRC_DIR}/H5Odeprec.c ${HDF5_SRC_DIR}/H5Odrvinfo.c @@ -616,6 +617,7 @@ set (H5T_SOURCES ${HDF5_SRC_DIR}/H5Torder.c ${HDF5_SRC_DIR}/H5Tpad.c ${HDF5_SRC_DIR}/H5Tprecis.c + ${HDF5_SRC_DIR}/H5Tref.c ${HDF5_SRC_DIR}/H5Tstrpad.c ${HDF5_SRC_DIR}/H5Tvisit.c ${HDF5_SRC_DIR}/H5Tvlen.c diff --git a/src/H5Aint.c b/src/H5Aint.c index 94fe97a..f9ae009 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -2269,7 +2269,7 @@ H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_s H5MM_memcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size); - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data") } /* end if */ else { @@ -2400,17 +2400,9 @@ H5A__attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *attr_src, /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - size_t dst_dt_size; /* Destination datatype size */ - - /* Determine size of the destination datatype */ - if(0 == (dst_dt_size = H5T_get_size(attr_dst->shared->dt))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") - /* Determine # of reference elements to copy */ - ref_count = attr_dst->shared->data_size / dst_dt_size; - /* Copy objects referenced in source buffer to destination file and set destination elements */ - if(H5O_copy_expand_ref(file_src, attr_dst->shared->data, file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_dst->shared->dt), cpy_info) < 0) + if(H5O_copy_expand_ref(file_src, H5I_INVALID_HID, attr_src->shared->dt, + attr_src->shared->data, attr_src->shared->data_size, file_dst, attr_dst->shared->data, cpy_info) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else diff --git a/src/H5D.c b/src/H5D.c index 96dce3f..9d811c6 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -706,56 +706,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Dvlen_reclaim - * - * Purpose: Frees the buffers allocated for storing variable-length data - * in memory. Only frees the VL data in the selection defined in the - * dataspace. The dataset transfer property list is required to find the - * correct allocation/free methods for the VL data in the buffer. - * - * Return: Non-negative on success, negative on failure - * - * Programmer: Quincey Koziol - * Thursday, June 10, 1999 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) -{ - H5S_t *space; /* Dataspace for iteration */ - herr_t ret_value; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); - - /* Check args */ - if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") - if(!(H5S_has_extent(space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if(H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else - if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Call internal routine */ - ret_value = H5D_vlen_reclaim(type_id, space, buf); - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dvlen_reclaim() */ - - -/*------------------------------------------------------------------------- * Function: H5Dvlen_get_buf_size * * Purpose: This routine checks the number of bytes required to store the VL diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index e3bbd59..7da05cb 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -5956,23 +5956,15 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed") /* Reclaim space from variable length data */ - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, H5_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; - size_t dt_size; - - /* Determine # of reference elements to copy */ - if((dt_size = H5T_get_size(udata->dt_src)) == 0) - HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "size must not be 0") - ref_count = nbytes / dt_size; - /* Copy the reference elements */ - if(H5O_copy_expand_ref(udata->file_src, buf, udata->idx_info_dst->f, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0) + if(H5O_copy_expand_ref(udata->file_src, udata->tid_src, udata->dt_src, buf, nbytes, udata->idx_info_dst->f, bkg, udata->cpy_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy reference attribute") } /* end if */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index 29401f8..edad3c5 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -551,26 +551,16 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds H5MM_memcpy(storage_dst->buf, buf, storage_dst->size); - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ else if(H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) { if(f_src != f_dst) { /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - size_t src_dt_size; /* Source datatype size */ - - /* 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") - - /* Determine # of reference elements to copy */ - ref_count = storage_src->size / src_dt_size; - /* Copy objects referenced in source buffer to destination file and set destination elements */ - if(H5O_copy_expand_ref(f_src, storage_src->buf, f_dst, - storage_dst->buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + if (H5O_copy_expand_ref(f_src, tid_src, dt_src, storage_src->buf, + storage_src->size, f_dst, storage_dst->buf, cpy_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index c9f9fc2..0be7364 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -1543,19 +1543,14 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") /* Reclaim space from variable length data */ - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ 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, f_dst, bkg, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + if(H5O_copy_expand_ref(f_src, tid_src, dt_src, buf, buf_size, f_dst, bkg, 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 */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 6380bee..f321c82 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -303,5 +303,55 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Dextend() */ + +/*------------------------------------------------------------------------- + * Function: H5Dvlen_reclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. The dataset transfer property list is required to find the + * correct allocation/free methods for the VL data in the buffer. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Thursday, June 10, 1999 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) +{ + H5S_t *space; /* Dataspace for iteration */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); + + /* Check args */ + if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + + /* Call internal routine */ + ret_value = H5T_reclaim(type_id, space, buf); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dvlen_reclaim() */ + #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Dint.c b/src/H5Dint.c index ada542e..772a150 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -547,7 +547,7 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type) /* To use at least v18 format versions or not */ use_at_least_v18 = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18); - /* Copy the datatype if it's a custom datatype or if it'll change when it's location is changed */ + /* Copy the datatype if it's a custom datatype or if it'll change when its location is changed */ if(!immutable || relocatable || use_at_least_v18) { /* Copy datatype for dataset */ if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL)) == NULL) @@ -2542,50 +2542,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5D_vlen_reclaim - * - * Purpose: Frees the buffers allocated for storing variable-length data - * in memory. Only frees the VL data in the selection defined in the - * dataspace. - * - * Return: Non-negative on success, negative on failure - *------------------------------------------------------------------------- - */ -herr_t -H5D_vlen_reclaim(hid_t type_id, H5S_t *space, void *buf) -{ - H5T_t *type; /* Datatype */ - H5S_sel_iter_op_t dset_op; /* Operator for iteration */ - H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ - herr_t ret_value = FAIL; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Check args */ - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - HDassert(space); - HDassert(buf); - - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype") - - /* Get the allocation info */ - if(H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") - - /* Call H5S_select_iterate with args, etc. */ - dset_op.op_type = H5S_SEL_ITER_OP_APP; - dset_op.u.app_op.op = H5T_vlen_reclaim; - dset_op.u.app_op.type_id = type_id; - - ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_vlen_reclaim() */ - - -/*------------------------------------------------------------------------- * Function: H5D__vlen_get_buf_size_alloc * * Purpose: This routine makes certain there is enough space in the temporary diff --git a/src/H5Dio.c b/src/H5Dio.c index 5160de8..79a856a 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -32,11 +32,6 @@ #include "H5VLnative_private.h" /* Native VOL connector */ -#ifdef H5_HAVE_PARALLEL -/* Remove this if H5R_DATASET_REGION is no longer used in this file */ -#include "H5Rpublic.h" -#endif /*H5_HAVE_PARALLEL*/ - /****************/ /* Local Macros */ diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 511e380..9a5277f 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -170,9 +170,6 @@ H5_DLL herr_t H5D_flush_all(H5F_t *f); H5_DLL hid_t H5D_get_create_plist(const H5D_t *dset); H5_DLL hid_t H5D_get_access_plist(const H5D_t *dset); -/* Functions that operate on vlen data */ -H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, void *buf); - /* Functions that operate on chunked storage */ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 7234d16..281da81 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -156,7 +156,6 @@ H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf); H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op, void *operator_data); -H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size); H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, hid_t buf_type, hid_t space); @@ -203,6 +202,7 @@ H5_DLL hid_t H5Dcreate1(hid_t file_id, const char *name, hid_t type_id, hid_t space_id, hid_t dcpl_id); H5_DLL hid_t H5Dopen1(hid_t file_id, const char *name); H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); +H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 9578f95..6e0db25 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -85,8 +85,6 @@ static herr_t H5O__copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /* hid_t ocpypl_id, hid_t lcpl_id); static herr_t H5O__copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); -static herr_t H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); static herr_t H5O__copy_free_comm_dt_cb(void *item, void *key, void *op_data); static int H5O__copy_comm_dt_cmp(const void *dt1, const void *dt2); static herr_t H5O__copy_search_comm_dt_cb(hid_t group, const char *name, @@ -110,7 +108,6 @@ H5FL_DEFINE(H5O_copy_search_comm_dt_key_t); /* Declare a free list to manage haddr_t variables */ H5FL_DEFINE(haddr_t); - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -1235,201 +1232,6 @@ 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, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_STATIC - - 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, cpy_info, FALSE, NULL, NULL)) < 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 */ - HDsnprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); - - /* Create a link to the newly copied object */ - /* Note: since H5O_copy_header_map actually copied the target object, it - * must exist either in cache or on disk, therefore it is is safe to not - * pass the obj_type and udata fields returned by H5O_copy_header_map. - * This could be changed in the future to slightly improve performance - * --NAF */ - if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, cpy_info->lcpl_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, 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 */ - const uint8_t *q; /* Pointer to source OID to store */ - uint8_t *p; /* Pointer to destination OID to store */ - size_t i; /* Local index variable */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(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 */ - q = (uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* Attempt to copy object from source to destination file */ - if(src_oloc.addr != (haddr_t)0) { - if(H5O__copy_obj_by_ref(&src_oloc, &dst_oloc, &dst_root_loc, cpy_info) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&dst_oloc.addr, 0, sizeof(dst_oloc.addr)); - - /* Set the object reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, 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 = NULL; /* Buffer to store serialized selection in */ - 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 */ - q = (const uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(hobjid.addr)); - UINT32DECODE(q, hobjid.idx); - - if(hobjid.addr != (haddr_t)0) { - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(src_oloc.file, &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 */ - q = (const uint8_t *)buf; - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(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, &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, buf_size, buf, &hobjid) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") - } /* end if */ - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&hobjid, 0, sizeof(hobjid)); - - /* 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); - UINT32ENCODE(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__copy_free_comm_dt_cb * * Purpose: Frees the merge committed dt skip list key and object. diff --git a/src/H5Ocopy_ref.c b/src/H5Ocopy_ref.c new file mode 100644 index 0000000..e8212d6bb --- /dev/null +++ b/src/H5Ocopy_ref.c @@ -0,0 +1,485 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ocopy_ref.c + * + * Purpose: Object with references copying routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Omodule.h" /* This source code file is part of the H5O module */ +#define H5F_FRIEND /* Suppress error about including H5Fpkg */ +#define H5R_FRIEND /* Suppress error about including H5Rpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Fpkg.h" /* File */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Opkg.h" /* Object headers */ +#include "H5Rpkg.h" /* References */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); +static herr_t H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, + const void *buf_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, + void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info); +static herr_t H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, + const void *buf_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, + void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info); +static herr_t H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, + H5T_t *dt_src, const void *buf_src, size_t nbytes_src, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, + H5O_copy_t *cpy_info); + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Declare extern the free list to manage blocks of type conversion data */ +H5FL_BLK_EXTERN(type_conv); + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + +/*------------------------------------------------------------------------- + * Function: H5O__copy_obj_by_ref + * + * Purpose: Copy the object pointed to by src_oloc. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + 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, cpy_info, FALSE, NULL, NULL)) < 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 */ + HDsnprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); + + /* Create a link to the newly copied object */ + /* Note: since H5O_copy_header_map actually copied the target object, it + * must exist either in cache or on disk, therefore it is is safe to not + * pass the obj_type and udata fields returned by H5O_copy_header_map. + * This could be changed in the future to slightly improve performance + * --NAF */ + if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, cpy_info->lcpl_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_object1 + * + * Purpose: Copy the object pointed by a deprecated object reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, + H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, + size_t ref_count, H5O_copy_t *cpy_info) +{ + const hobj_ref_t *src_ref = (const hobj_ref_t *)buf_src; + hobj_ref_t *dst_ref = (hobj_ref_t *)buf_dst; + const unsigned char zeros[H5R_OBJ_REF_BUF_SIZE] = { 0 }; + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + const unsigned char *src_buf = (const unsigned char *)&src_ref[i]; + unsigned char *dst_buf = (unsigned char *)&dst_ref[i]; + + /* If data is not initialized, copy zeros and skip */ + if(0 == HDmemcmp(src_buf, zeros, buf_size)) { + HDmemset(dst_buf, 0, buf_size); + continue; + } + + /* Set up for the object copy for the reference */ + if(H5R__decode_addr_obj_compat(src_buf, &buf_size, &src_oloc->addr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address") + if(!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer") + dst_oloc->addr = HADDR_UNDEF; + + /* Attempt to copy object from source to destination file */ + if(H5O__copy_obj_by_ref(src_oloc, 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 */ + if(H5R__encode_addr_obj_compat(dst_oloc->addr, dst_buf, &buf_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to encode dst object address") + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O__copy_expand_ref_object1() */ + + +/*------------------------------------------------------------------------- + * Function: H5O__copy_expand_ref_region1 + * + * Purpose: Copy the object pointed by a deprecated region reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, const void *buf_src, + H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, + size_t ref_count, H5O_copy_t *cpy_info) +{ + const hdset_reg_ref_t *src_ref = (const hdset_reg_ref_t *)buf_src; + hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)buf_dst; + const unsigned char zeros[H5R_DSET_REG_REF_BUF_SIZE] = { 0 }; + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + const unsigned char *src_buf = (const unsigned char *)&src_ref[i]; + unsigned char *dst_buf = (unsigned char *)&dst_ref[i]; + unsigned char *data = NULL; + size_t data_size; + const uint8_t *p; + uint8_t *q; + + /* If data is not initialized, copy zeros and skip */ + if(0 == HDmemcmp(src_buf, zeros, buf_size)) { + HDmemset(dst_buf, 0, buf_size); + continue; + } + + /* Read from heap */ + if(H5R__decode_heap(src_oloc->file, src_buf, &buf_size, &data, &data_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode dataset region information") + + /* Get object address */ + p = (const uint8_t *)data; + H5F_addr_decode(src_oloc->file, &p, &src_oloc->addr); + if(!H5F_addr_defined(src_oloc->addr) || src_oloc->addr == 0) { + H5MM_free(data); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer") + } + dst_oloc->addr = HADDR_UNDEF; + + /* Attempt to copy object from source to destination file */ + if(H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) { + H5MM_free(data); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + } /* end if */ + + /* Serialize object addr */ + q = (uint8_t *)data; + H5F_addr_encode(dst_oloc->file, &q, dst_oloc->addr); + + /* Write to heap */ + if(H5R__encode_heap(dst_oloc->file, dst_buf, &buf_size, data, (size_t)data_size) < 0) { + H5MM_free(data); + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode dataset region information") + } + + /* Free the buffer allocated in H5R__decode_heap() */ + H5MM_free(data); + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O__copy_expand_ref_region1() */ + + +/*------------------------------------------------------------------------- + * Function: H5O__copy_expand_ref_object2 + * + * Purpose: Copy the object pointed by a reference (object, region, attribute). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, H5T_t *dt_src, + const void *buf_src, size_t nbytes_src, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, + H5O_copy_t *cpy_info) +{ + H5T_t *dt_mem = NULL; /* Memory datatype */ + H5T_t *dt_dst = NULL; /* Destination datatype */ + hid_t tid_mem = H5I_INVALID_HID; /* Datatype ID for memory datatype */ + hid_t tid_dst = H5I_INVALID_HID; /* Datatype ID for memory datatype */ + H5T_path_t *tpath_src_mem = NULL, + *tpath_mem_dst = NULL; /* Datatype conversion paths */ + size_t i; /* Local index variable */ + hbool_t reg_tid_src = (tid_src == H5I_INVALID_HID); + hid_t dst_loc_id = H5I_INVALID_HID; + void *conv_buf = NULL; /* Buffer for converting data */ + size_t conv_buf_size = 0; /* Buffer size */ + void *reclaim_buf = NULL; /* Buffer for reclaiming data */ + H5S_t *buf_space = NULL; /* Dataspace describing buffer */ + hsize_t buf_dim[1] = {ref_count}; /* Dimension for buffer */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + /* Create datatype ID for src datatype. */ + if((tid_src == H5I_INVALID_HID) && (tid_src = H5I_register(H5I_DATATYPE, dt_src, FALSE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") + + /* create a memory copy of the reference datatype */ + if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy") + if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem, FALSE)) < 0) { + (void)H5T_close_real(dt_mem); + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") + } /* end if */ + + /* create reference datatype at the destinaton file */ + if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy") + if(H5T_set_loc(dt_dst, dst_oloc->file, H5T_LOC_DISK) < 0) { + (void)H5T_close_real(dt_dst); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") + } /* end if */ + if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst, FALSE)) < 0) { + (void)H5T_close_real(dt_dst); + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") + } /* end if */ + + /* Set up the conversion functions */ + if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") + if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") + + /* Use extra conversion buffer (TODO we should avoid using an extra buffer once the H5Ocopy code has been reworked) */ + conv_buf_size = MAX(H5T_get_size(dt_src), H5T_get_size(dt_mem)) * ref_count; + if(NULL == (conv_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + H5MM_memcpy(conv_buf, buf_src, nbytes_src); + + /* Convert from source file to memory */ + if(H5T_convert(tpath_src_mem, tid_src, tid_mem, ref_count, (size_t)0, (size_t)0, conv_buf, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + + /* Retrieve loc ID */ + if((dst_loc_id = H5F__get_file_id(dst_oloc->file, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + H5R_ref_t *ref_ptr = (H5R_ref_t *)conv_buf; + H5R_ref_priv_t *ref = (H5R_ref_priv_t *)&ref_ptr[i]; + size_t token_size = sizeof(src_oloc->addr); + + /* Get src object address */ + if(H5R__get_obj_token(ref, (H5VL_token_t *)&src_oloc->addr, &token_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token") + + /* Attempt to copy object from source to destination file */ + if(H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Set dst object address */ + if(H5R__set_obj_token(ref, (const H5VL_token_t *)&dst_oloc->addr, token_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token") + if(H5R__set_loc_id(ref, dst_loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set destination loc id") + } /* end for */ + + /* Copy into another buffer, to reclaim memory later */ + if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + H5MM_memcpy(reclaim_buf, conv_buf, conv_buf_size); + if(NULL == (buf_space = H5S_create_simple((unsigned)1, buf_dim, NULL))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create simple dataspace") + + /* Convert from memory to destination file */ + if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, ref_count, (size_t)0, (size_t)0, conv_buf, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + H5MM_memcpy(buf_dst, conv_buf, nbytes_src); + + /* Reclaim space from reference data */ + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to reclaim reference data") + +done: + if(buf_space && (H5S_close(buf_space) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't close dataspace") + /* Don't decrement ID, we want to keep underlying datatype */ + if(reg_tid_src && (tid_src > 0) && (NULL == H5I_remove(tid_src))) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if((tid_mem > 0) && H5I_dec_ref(tid_mem) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if((tid_dst > 0) && H5I_dec_ref(tid_dst) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if(reclaim_buf) + reclaim_buf = H5FL_BLK_FREE(type_conv, reclaim_buf); + if(conv_buf) + conv_buf = H5FL_BLK_FREE(type_conv, conv_buf); + if((dst_loc_id != H5I_INVALID_HID) && (H5I_dec_ref(dst_loc_id) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O__copy_expand_ref_object2() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_expand_ref + * + * Purpose: Copy the object pointed by a reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, H5T_t *dt_src, + void *buf_src, size_t nbytes_src, H5F_t *file_dst, void *buf_dst, + 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 ref_count; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(file_src); + HDassert(buf_src); + HDassert(file_dst); + HDassert(buf_dst); + HDassert(nbytes_src); + 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") + + /* Determine # of reference elements to copy */ + ref_count = nbytes_src / H5T_get_size(dt_src); + + /* Copy object references */ + switch(H5T_get_ref_type(dt_src)) { + case H5R_OBJECT1: + if(H5O__copy_expand_ref_object1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_OBJECT1 reference") + break; + case H5R_DATASET_REGION1: + if(H5O__copy_expand_ref_region1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_DATASET_REGION1 reference") + break; + case H5R_DATASET_REGION2: + case H5R_ATTR: + case H5R_OBJECT2: + if(H5O__copy_expand_ref_object2(&src_oloc, tid_src, dt_src, buf_src, nbytes_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand reference") + break; + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + break; + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_expand_ref() */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 0523e7c..805df2b 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -145,7 +145,7 @@ H5O_dtype_decode_helper(unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t * /* Version, class & flags */ UINT32DECODE(*pp, flags); version = (flags>>4) & 0x0f; - if(version < H5O_DTYPE_VERSION_1 || version > H5O_DTYPE_VERSION_3) + if(version < H5O_DTYPE_VERSION_1 || version > H5O_DTYPE_VERSION_LATEST) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "bad version number for datatype message") dt->shared->version = version; dt->shared->type = (H5T_class_t)(flags & 0x0f); @@ -438,16 +438,28 @@ H5O_dtype_decode_helper(unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t * /* Set reference type */ dt->shared->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f); - - /* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */ - if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) { - /* Mark location this type as undefined for now. The caller function should - * decide the location. */ - dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; - - /* This type needs conversion */ - dt->shared->force_conv = TRUE; - } /* end if */ + if(dt->shared->u.atomic.u.r.rtype <= H5R_BADTYPE + || dt->shared->u.atomic.u.r.rtype >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "invalid reference type"); + + /* Set generic flag */ + if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT2 + || dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION2 + || dt->shared->u.atomic.u.r.rtype == H5R_ATTR) { + dt->shared->u.atomic.u.r.opaque = TRUE; + dt->shared->u.atomic.u.r.version = (unsigned)((flags >> 4) & 0x0f); + if(dt->shared->u.atomic.u.r.version != H5R_ENCODE_VERSION) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "reference version does not match"); + } else + dt->shared->u.atomic.u.r.opaque = FALSE; + + /* This type needs conversion */ + dt->shared->force_conv = TRUE; + + /* Mark location of this type as undefined for now. The caller + * function should decide the location. */ + if(H5T_set_loc(dt, NULL, H5T_LOC_BADLOC) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") break; case H5T_ENUM: @@ -964,6 +976,8 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt) case H5T_REFERENCE: flags |= (dt->shared->u.atomic.u.r.rtype & 0x0f); + if(dt->shared->u.atomic.u.r.opaque) + flags = (unsigned)(flags | (((unsigned)dt->shared->u.atomic.u.r.version & 0x0f) << 4)); break; case H5T_ENUM: diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 54e2ba6..36a993f 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -741,7 +741,7 @@ H5O_fill_reset_dyn(H5O_fill_t *fill) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create scalar dataspace") /* Reclaim any variable length components of the fill value */ - if(H5D_vlen_reclaim(fill_type_id, fill_space, fill->buf) < 0) { + if(H5T_reclaim(fill_type_id, fill_space, fill->buf) < 0) { H5S_close(fill_space); HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to reclaim variable-length fill value data") } /* end if */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 354a00b..5f34fcd 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -976,8 +976,8 @@ H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, H5VL_t H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, H5O_copy_t *cpy_info, hbool_t inc_depth, H5O_type_t *obj_type, void **udata); -H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, - H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, +H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, H5T_t *dt_src, + void *buf_src, size_t nbytes_src, H5F_t *file_dst, void *buf_dst, H5O_copy_t *cpy_info); H5_DLL herr_t H5O_copy(const H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); diff --git a/src/H5Pint.c b/src/H5Pint.c index 36367d7..2911eef 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -169,6 +169,8 @@ hid_t H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID; H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL; hid_t H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL; +hid_t H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; +H5P_genclass_t *H5P_CLS_REFERENCE_ACCESS_g = NULL; /* * Predefined property lists for each predefined class. These are initialized @@ -192,6 +194,7 @@ hid_t H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID; hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID; hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID; hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; +hid_t H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; /* Root property list class library initialization object */ const H5P_libclass_t H5P_CLS_ROOT[1] = {{ @@ -312,6 +315,25 @@ const H5P_libclass_t H5P_CLS_VINI[1] = {{ NULL /* Class close callback info */ }}; +/* Reference access property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_RACC[1] = {{ + "reference access", /* Class name for debugging */ + H5P_TYPE_REFERENCE_ACCESS, /* Class type */ + + &H5P_CLS_FILE_ACCESS_g, /* Parent class */ + &H5P_CLS_REFERENCE_ACCESS_g, /* Pointer to class */ + &H5P_CLS_REFERENCE_ACCESS_ID_g, /* Pointer to class ID */ + &H5P_LST_REFERENCE_ACCESS_ID_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine*/ + + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; /* Library property list classes defined in other code modules */ /* (And not present in src/H5Pprivate.h) */ @@ -364,7 +386,8 @@ static H5P_libclass_t const * const init_class[] = { H5P_CLS_ACRT, /* Attribute creation */ H5P_CLS_AACC, /* Attribute access */ H5P_CLS_LCRT, /* Link creation */ - H5P_CLS_VINI /* VOL initialization */ + H5P_CLS_VINI, /* VOL initialization */ + H5P_CLS_RACC /* Reference access */ }; /* Declare a free list to manage the H5P_genclass_t struct */ @@ -440,7 +463,7 @@ H5P__init_package(void) FUNC_ENTER_PACKAGE /* Sanity check */ - HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); + HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); /* * Initialize the Generic Property class & object groups. @@ -564,6 +587,7 @@ H5P_term_package(void) H5P_LST_LINK_CREATE_ID_g = H5P_LST_LINK_ACCESS_ID_g = H5P_LST_VOL_INITIALIZE_ID_g = + H5P_LST_REFERENCE_ACCESS_ID_g = H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID; } /* end if */ } /* end if */ @@ -594,6 +618,7 @@ H5P_term_package(void) H5P_CLS_LINK_CREATE_g = H5P_CLS_LINK_ACCESS_g = H5P_CLS_VOL_INITIALIZE_g = + H5P_CLS_REFERENCE_ACCESS_g = H5P_CLS_FILE_MOUNT_g = NULL; H5P_CLS_ROOT_ID_g = @@ -616,6 +641,7 @@ H5P_term_package(void) H5P_CLS_LINK_CREATE_ID_g = H5P_CLS_LINK_ACCESS_ID_g = H5P_CLS_VOL_INITIALIZE_ID_g = + H5P_CLS_REFERENCE_ACCESS_ID_g = H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID; } /* end if */ } /* end if */ @@ -5453,8 +5479,8 @@ H5P__new_plist_of_type(H5P_plist_type_t type) FUNC_ENTER_PACKAGE /* Sanity checks */ - HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); - HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_MAP_ACCESS); + HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); + HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_REFERENCE_ACCESS); /* Check arguments */ if(type == H5P_TYPE_USER) @@ -5544,6 +5570,10 @@ H5P__new_plist_of_type(H5P_plist_type_t type) class_id = H5P_CLS_VOL_INITIALIZE_ID_g; break; + case H5P_TYPE_REFERENCE_ACCESS: + class_id = H5P_CLS_REFERENCE_ACCESS_ID_g; + break; + case H5P_TYPE_USER: /* shut compiler warnings up */ case H5P_TYPE_ROOT: case H5P_TYPE_MAX_TYPE: diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 9fc1acc..f7253a0 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -81,6 +81,7 @@ typedef enum H5P_plist_type_t { H5P_TYPE_VOL_INITIALIZE = 19, H5P_TYPE_MAP_CREATE = 20, H5P_TYPE_MAP_ACCESS = 21, + H5P_TYPE_REFERENCE_ACCESS = 22, H5P_TYPE_MAX_TYPE } H5P_plist_type_t; diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 9f26b8b..bb33561 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -71,6 +71,7 @@ #define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g) #define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g) #define H5P_VOL_INITIALIZE (H5OPEN H5P_CLS_VOL_INITIALIZE_ID_g) +#define H5P_REFERENCE_ACCESS (H5OPEN H5P_CLS_REFERENCE_ACCESS_ID_g) /* * The library's default property lists @@ -93,6 +94,7 @@ #define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g) #define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g) #define H5P_VOL_INITIALIZE_DEFAULT (H5OPEN H5P_LST_VOL_INITIALIZE_ID_g) +#define H5P_REFERENCE_ACCESS_DEFAULT (H5OPEN H5P_LST_REFERENCE_ACCESS_ID_g) /* Common creation order flags (for links in groups and attributes on objects) */ #define H5P_CRT_ORDER_TRACKED 0x0001 @@ -204,6 +206,7 @@ H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_ID_g; H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_ID_g; H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_ID_g; H5_DLLVAR hid_t H5P_CLS_VOL_INITIALIZE_ID_g; +H5_DLLVAR hid_t H5P_CLS_REFERENCE_ACCESS_ID_g; /* Default roperty list IDs */ /* (Internal to library, do not use! Use macros above) */ @@ -225,6 +228,7 @@ H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_ID_g; H5_DLLVAR hid_t H5P_LST_LINK_CREATE_ID_g; H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_ID_g; H5_DLLVAR hid_t H5P_LST_VOL_INITIALIZE_ID_g; +H5_DLLVAR hid_t H5P_LST_REFERENCE_ACCESS_ID_g; /*********************/ /* Public Prototypes */ diff --git a/src/H5R.c b/src/H5R.c index 7d3686e..11b75ca 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -11,22 +11,24 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* + * Purpose: Reference routines. + */ + /****************/ /* Module Setup */ /****************/ #include "H5Rmodule.h" /* This source code file is part of the H5R module */ - /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Rpkg.h" /* References */ #include "H5Sprivate.h" /* Dataspaces */ @@ -61,330 +63,825 @@ /*******************/ -/*-------------------------------------------------------------------------- - NAME - H5Rcreate - PURPOSE - Creates a particular kind of reference for the user - USAGE - herr_t H5Rcreate(ref, loc_id, name, ref_type, space_id) - void *ref; OUT: Reference created - hid_t loc_id; IN: Location ID used to locate object pointed to - const char *name; IN: Name of object at location LOC_ID of object - pointed to - H5R_type_t ref_type; IN: Type of reference to create - hid_t space_id; IN: Dataspace ID with selection, used for Dataset - Region references. - - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Creates a particular type of reference specified with REF_TYPE, in the - space pointed to by REF. The LOC_ID and NAME are used to locate the object - pointed to and the SPACE_ID is used to choose the region pointed to (for - Dataset Region references). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rcreate_object + * + * Purpose: Creates an object reference. The LOC_ID and NAME are used to locate + * the object pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) +H5Rcreate_object(hid_t loc_id, const char *name, H5R_ref_t *ref_ptr) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "*xi*sRti", ref, loc_id, name, ref_type, space_id); + H5TRACE3("e", "i*s*Rr", loc_id, name, ref_ptr); /* Check args */ - if (ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(ref_type != H5R_OBJECT && ref_type != H5R_DATASET_REGION) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported") - if(space_id == (-1) && ref_type == H5R_DATASET_REGION) + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_object((const H5VL_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcreate_region + * + * Purpose: Creates a region reference. The LOC_ID and NAME are used to locate + * the object pointed to and the SPACE_ID is used to choose the region pointed + * to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, + H5R_ref_t *ref_ptr) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + struct H5S_t *space = NULL; /* Pointer to dataspace containing region */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*si*Rr", loc_id, name, space_id, ref_ptr); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + if((space_id == H5I_BADID) || (space_id == H5S_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") + if(NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_region((const H5VL_token_t *)&obj_token, cont_info.token_size, space, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcreate_attr + * + * Purpose: Creates an attribute reference. The LOC_ID, NAME and ATTR_NAME are + * used to locate the attribute pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, + H5R_ref_t *ref_ptr) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*s*s*Rr", loc_id, name, attr_name, ref_ptr); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + if(!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name given") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - /* Set up collective metadata if appropriate */ - if(H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_attr((const H5VL_token_t *)&obj_token, cont_info.token_size, attr_name, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create attribute reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_attr() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rdestroy + * + * Purpose: Destroy reference and free resources allocated during H5Rcreate. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rdestroy(H5R_ref_t *ref_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "*Rr", ref_ptr); + + /* Check args */ + if(NULL == ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid reference pointer") + + /* Destroy reference */ + if(H5R__destroy((H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "unable to destroy reference") + + /* Memset back to 0 for safety */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rdestroy() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_type + * + * Purpose: Given a reference to some object, return the type of that reference. + * + * Return: Reference type/H5R_BADTYPE on failure + * + *------------------------------------------------------------------------- + */ +H5R_type_t +H5Rget_type(const H5R_ref_t *ref_ptr) +{ + H5R_type_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5R_BADTYPE) + H5TRACE1("Rt", "*Rr", ref_ptr); + + /* Check args */ + if(NULL == ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5R_BADTYPE, "invalid reference pointer") + + /* Get reference type */ + ret_value = H5R__get_type((const H5R_ref_priv_t *)ref_ptr); + if((ret_value <= H5R_BADTYPE) || (ret_value >= H5R_MAXTYPE)) + HGOTO_ERROR(H5E_REFERENCE, H5E_BADVALUE, H5R_BADTYPE, "invalid reference type") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5Requal + * + * Purpose: Compare two references + * + * Return: TRUE if equal, FALSE if unequal, FAIL if error + * + *------------------------------------------------------------------------- + */ +htri_t +H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("t", "*Rr*Rr", ref1_ptr, ref2_ptr); + + /* Check args */ + if(!ref1_ptr || !ref2_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + + /* Compare references */ + if((ret_value = H5R__equal((const H5R_ref_priv_t *)ref2_ptr, (const H5R_ref_priv_t *)ref2_ptr)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare references") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Requal() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcopy + * + * Purpose: Copy a reference + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ - /* Get the file object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "*Rr*Rr", src_ref_ptr, dst_ref_ptr); - /* Set up collective metadata if appropriate */ - if(H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + /* Check args */ + if(NULL == src_ref_ptr || NULL == dst_ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid reference pointer") - /* Create reference */ - if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_REF_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, ref, name, (int)ref_type, space_id)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create reference") + /* Copy reference */ + if(H5R__copy((const H5R_ref_priv_t *)src_ref_ptr, (H5R_ref_priv_t *)dst_ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "cannot copy reference") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rcreate() */ +} /* end H5Rcopy() */ -/*-------------------------------------------------------------------------- - NAME - H5Rdereference2 - PURPOSE - Opens the HDF5 object referenced. - USAGE - hid_t H5Rdereference2(ref) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - hid_t oapl_id; IN: Property list of the object being referenced. - H5R_type_t ref_type; IN: Type of reference to create - void *ref; IN: Reference to open. - - RETURNS - Valid ID on success, H5I_INVALID_HID on failure - DESCRIPTION - Given a reference to some object, open that object and return an ID for - that object. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG - Raymond Lu - 13 July 2011 - I added the OAPL_ID parameter for the object being referenced. It only - supports dataset access property list currently. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Ropen_object + * + * Purpose: Given a reference to some object, open that object and return an + * ID for that object. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) +H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5I_type_t opened_type; - void *opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE4("i", "iiRt*x", obj_id, oapl_id, ref_type, _ref); + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") if(oapl_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") - if(_ref == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") /* Verify access property list and set up collective metadata if appropriate */ - if(H5CX_set_apl(&oapl_id, H5P_CLS_DACC, obj_id, FALSE) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + if(H5CX_set_apl(&oapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") /* Get the VOL object */ - if(NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_REF; - loc_params.loc_data.loc_by_ref.ref_type = ref_type; - loc_params.loc_data.loc_by_ref._ref = _ref; - loc_params.loc_data.loc_by_ref.lapl_id = oapl_id; - loc_params.obj_type = H5I_get_type(obj_id); + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* Dereference */ + /* Open object by token */ if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to dereference object") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + /* Register object */ if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rdereference2() */ +} /* end H5Ropen_object() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_region - PURPOSE - Retrieves a dataspace with the region pointed to selected. - USAGE - hid_t H5Rget_region(id, ref_type, ref) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to get region of - void *ref; IN: Reference to open. - - RETURNS - Valid ID on success, H5I_INVALID_HID on failure - DESCRIPTION - Given a reference to some object, creates a copy of the dataset pointed - to's dataspace and defines a selection in the copy which is the region - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Ropen_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy which is the + * region pointed to. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) +H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + H5S_t *space = NULL; /* Dataspace pointer (copy) */ + hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "iRt*x", id, ref_type, ref); + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); /* Check args */ - if(ref_type != H5R_DATASET_REGION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") - if(ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if((H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_DATASET_REGION1) + && (H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_DATASET_REGION2)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + if(oapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Open object by token */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + + /* Register object */ + if((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + + /* Get VOL object object */ + if(NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get dataspace from object */ + if(H5VL_dataset_get(opened_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &space_id) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace from dataset") + if(NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace") /* Get the dataspace with the correct region selected */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_REGION, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, (int)ref_type, ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve dataspace") + if(H5R__get_region((const H5R_ref_priv_t *)ref_ptr, space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get selection on dataspace") + + /* Simply return space_id */ + ret_value = space_id; + +done: + if((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object") + if(H5I_INVALID_HID == ret_value) /* Cleanup on failure */ + if((space_id != H5I_INVALID_HID) && (H5I_dec_ref(space_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close dataspace") + + FUNC_LEAVE_API(ret_value) +} /* end H5Ropen_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5Ropen_attr + * + * Purpose: Given a reference to some attribute, open that attribute and + * return an ID for that attribute. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) +{ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + void *opened_attr = NULL; /* Opened attribute */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_ATTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + if(aapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Open object by token */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + + /* Register object */ + if((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = opened_type; + + /* Get VOL object object */ + if(NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Open the attribute */ + if(NULL == (opened_attr = H5VL_attr_open(opened_obj, &loc_params, H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr), aapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr)) + + /* Register the attribute and get an ID for it */ + if((ret_value = H5VL_register(H5I_ATTR, opened_attr, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") done: + if((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object") + if(H5I_INVALID_HID == ret_value) /* Cleanup on failure */ + if(opened_attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_LEAVE_API(ret_value) -} /* end H5Rget_region() */ +} /* end H5Ropen_attr() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_obj_type2 - PURPOSE - Retrieves the type of object that an object reference points to - USAGE - herr_t H5Rget_obj_type2(id, ref_type, ref, obj_type) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to query - void *ref; IN: Reference to query. - H5O_type_t *obj_type; OUT: Type of object reference points to - - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Given a reference to some object, this function retrieves the type of - object pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rget_obj_type3 + * + * Purpose: Given a reference to some object, this function returns the type + * of object pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, - H5O_type_t *obj_type) +H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); + H5TRACE3("e", "*Rri*Ot", ref_ptr, rapl_id, obj_type); /* Check args */ - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, FAIL, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get object token") - /* Get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object type */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_type, (int)ref_type, ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object type") + /* Retrieve object's type */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_type) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object type") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_obj_type2() */ +} /* end H5Rget_obj_type3() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_name - PURPOSE - Determines a name for the object referenced - USAGE - ssize_t H5Rget_name(loc_id, ref_type, ref, name, size) - hid_t loc_id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to query. - char *name; OUT: Buffer to place name of object referenced. If NULL - then this call will return the size in bytes of name. - size_t size; IN: Size of name buffer (user needs to include NULL terminator - when passing in the size) - - RETURNS - Non-negative length of the path on success, -1 on failure - DESCRIPTION - Given a reference to some object, determine a path to the object - referenced in the file. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This may not be the only path to that object. - EXAMPLES - REVISION LOG - M. Scot Breitenfeld - 22 January 2014 - Changed the behavior for the returned value of the function when name is NULL. - If name is NULL then size is ignored and the function returns the size - of the name buffer (not including the NULL terminator), it still returns - negative on failure. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rget_file_name + * + * Purpose: Given a reference to some object, determine a file name of the + * object located into. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ ssize_t -H5Rget_name(hid_t id, H5R_type_t ref_type, const void *_ref, char *name, - size_t size) +H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + hid_t loc_id; /* Reference location ID */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE5("Zs", "iRt*x*sz", id, ref_type, _ref, name, size); + H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); /* Check args */ - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") - if(_ref == NULL) + + /* Get name */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Un-opened external references do not have loc_id set but hold a + * copy of the filename */ + if((ret_value = H5R__get_file_name((const H5R_ref_priv_t *)ref_ptr, buf, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to retrieve file name") + } else { + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + + /* Retrieve VOL file object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + if(H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5I_FILE, size, buf, &ret_value) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get file name") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_file_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_obj_name + * + * Purpose: Given a reference to some object, determine a path to the object + * referenced in the file. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) +{ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API((-1)) + H5TRACE4("Zs", "*Rri*sz", ref_ptr, rapl_id, buf, size); + + /* Check args */ + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, (-1), "cannot re-open referenced file") + } - /* Get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Get object token */ + if((ret_value = H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get object token") - /* Get name */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, name, size, (int)ref_type, _ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to determine object path") + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Retrieve object's name */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, buf, size) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't retrieve object name") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_name() */ +} /* end H5Rget_obj_name() */ + +/*------------------------------------------------------------------------- + * Function: H5Rget_attr_name + * + * Purpose: Given a reference to some attribute, determine its name. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) +{ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API((-1)) + H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_ATTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") + + /* Get attribute name */ + if((ret_value = H5R__get_attr_name((const H5R_ref_priv_t *)ref_ptr, buf, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to determine attribute name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_attr_name() */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index ab8d3b4..4743c77 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -37,14 +37,15 @@ #include "H5Ppublic.h" /* Property lists */ /* Private headers needed by this file */ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Gprivate.h" /* Groups */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ -#include "H5Oprivate.h" /* Object headers */ +#include "H5Oprivate.h" /* Object headers */ #include "H5Rpkg.h" /* References */ +#include "H5Sprivate.h" /* Dataspaces */ /****************/ @@ -81,53 +82,61 @@ /* Local Variables */ /*******************/ - #ifndef H5_NO_DEPRECATED_SYMBOLS - + /*------------------------------------------------------------------------- * Function: H5Rget_obj_type1 * - * Purpose: Retrieves the type of the object that an object points to. + * Purpose: Retrieves the type of the object that a reference points to. * - * Parameters: - * id IN: Dataset reference object is in or location ID of - * object that the dataset is located within - * ref_type IN: Type of reference to query - * ref IN: Reference to query - * - * Return: Success: An object type (as defined in H5Gpublic.h) - * Failure: H5G_UNKNOWN + * Return: Object type (as defined in H5Gpublic.h) on success + * H5G_UNKNOWN on failure * *------------------------------------------------------------------------- */ H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - H5O_type_t obj_type; /* Object type */ - H5G_obj_t ret_value; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + H5O_type_t obj_type; /* Object type */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE3("Go", "iRt*x", id, ref_type, ref); /* Check args */ - if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type") - if (ref == NULL) + if(buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") - /* Get the vol object */ - if (NULL == (vol_obj = H5VL_vol_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid file identifier") + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ - /* Get the object information */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &obj_type, (int)ref_type, ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5G_UNKNOWN, "unable to determine object type") + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") + + /* Get object address */ + if(H5R__decode_addr_compat(id, vol_obj_type, ref_type, buf, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5G_UNKNOWN, "unable to get object address") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_addr; + loc_params.obj_type = vol_obj_type; + + /* Retrieve object's type */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &obj_type) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, H5G_UNKNOWN, "can't retrieve object type") /* Set return value */ ret_value = H5G_map_obj_type(obj_type); @@ -140,54 +149,61 @@ done: /*------------------------------------------------------------------------- * Function: H5Rdereference1 * - * Purpose: Opens the HDF5 object referenced. - * - * Parameters: - * id IN: Dataset reference object is in or location ID of - * object that the dataset is located within - * ref_type IN: Type of reference to create - * ref IN: Reference to open + * Purpose: Given a reference to some object, open that object and return an + * ID for that object. * - * Return: Success: Valid HDF5 ID - * Failure: H5I_INVALID_HID + * Return: Valid ID on success/Negative on failure * *------------------------------------------------------------------------- */ hid_t -H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *_ref) +H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5I_type_t opened_type; - void *opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "iRt*x", obj_id, ref_type, _ref); + H5TRACE3("i", "iRt*x", obj_id, ref_type, ref); /* Check args */ - if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") - if (_ref == NULL) + if(buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") /* Get the VOL object */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ - loc_params.type = H5VL_OBJECT_BY_REF; - loc_params.loc_data.loc_by_ref.ref_type = ref_type; - loc_params.loc_data.loc_by_ref._ref = _ref; - loc_params.loc_data.loc_by_ref.lapl_id = H5P_DATASET_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(obj_id); + /* Get object type */ + if((vol_obj_type = H5I_get_type(obj_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get object address */ + if(H5R__decode_addr_compat(obj_id, vol_obj_type, ref_type, buf, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5I_INVALID_HID, "unable to get object address") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_addr; + loc_params.obj_type = vol_obj_type; /* Dereference */ if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to dereference object") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by address") - /* Get an atom for the object */ + /* Register object */ if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: FUNC_LEAVE_API(ret_value) @@ -195,3 +211,363 @@ done: #endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/*------------------------------------------------------------------------- + * Function: H5Rcreate + * + * Purpose: Creates a particular type of reference specified with REF_TYPE, + * in the space pointed to by REF. The LOC_ID and NAME are used to locate the + * object pointed to and the SPACE_ID is used to choose the region pointed to + * (for Dataset Region references). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, + hid_t space_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + unsigned char *buf = (unsigned char *)ref; /* Return reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*xi*sRti", ref, loc_id, name, ref_type, space_id); + + /* Check args */ + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + + /* Set up collective metadata if appropriate */ + if(H5CX_set_loc(loc_id) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = vol_obj_type; + + /* Get the object address */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object address") + + /* Create reference */ + if(ref_type == H5R_OBJECT1) { + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + + if((ret_value = H5R__encode_addr_obj_compat(obj_addr, buf, &buf_size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to encode object reference") + } else { + void *vol_obj_file = NULL; + H5F_t *f = NULL; + H5S_t *space = NULL; /* Pointer to dataspace containing region */ + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, vol_obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data(vol_obj_file))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") + + /* Retrieve space */ + if(space_id == H5I_BADID) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") + if(NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Encode dataset region */ + if((ret_value = H5R__encode_addr_region_compat(f, obj_addr, space, buf, &buf_size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to encode region reference") + } + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_obj_type2 + * + * Purpose: Given a reference to some object, this function returns the type + * of object pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, + H5O_type_t *obj_type) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); + + /* Check args */ + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object address */ + if(H5R__decode_addr_compat(id, vol_obj_type, ref_type, buf, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_addr; + loc_params.obj_type = vol_obj_type; + + /* Retrieve object's type */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_type) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object type") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_obj_type2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rdereference2 + * + * Purpose: Given a reference to some object, open that object and return an + * ID for that object. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, + const void *ref) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE4("i", "iiRt*x", obj_id, oapl_id, ref_type, ref); + + /* Check args */ + if(oapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&oapl_id, H5P_CLS_DACC, obj_id, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* Get object type */ + if((vol_obj_type = H5I_get_type(obj_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get object address */ + if(H5R__decode_addr_compat(obj_id, vol_obj_type, ref_type, buf, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5I_INVALID_HID, "unable to get object address") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_addr; + loc_params.obj_type = vol_obj_type; + + /* Open object by address */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by address") + + /* Register object */ + if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rdereference2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy which is the + * region pointed to. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + void *vol_obj_file = NULL; /* VOL file */ + H5F_t *f = NULL; /* Native file */ + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Reference buffer size */ + H5S_t *space = NULL; /* Dataspace object */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "iRt*x", id, ref_type, ref); + + /* Check args */ + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(id, vol_obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file or file object") + + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data(vol_obj_file))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid VOL object") + + /* Get the dataspace with the correct region selected */ + if(H5R__decode_addr_region_compat(f, buf, &buf_size, NULL, &space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") + + /* Atomize */ + if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataspace atom") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_region1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_name + * + * Purpose: Given a reference to some object, determine a path to the object + * referenced in the file. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name, + size_t size) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + haddr_t obj_addr; /* Object address */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ + ssize_t ret_value = -1; /* Return value */ + + FUNC_ENTER_API((-1)) + H5TRACE5("Zs", "iRt*x*sz", id, ref_type, ref, name, size); + + /* Check args */ + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + /* Get object address */ + if(H5R__decode_addr_compat(id, vol_obj_type, ref_type, buf, &obj_addr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, (-1), "unable to get object address") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = &obj_addr; + loc_params.obj_type = vol_obj_type; + + /* Retrieve object's name */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, name, size) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't retrieve object name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_name() */ diff --git a/src/H5Rint.c b/src/H5Rint.c index 07efae2..e33eecb 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -35,11 +35,73 @@ #include "H5Sprivate.h" /* Dataspaces */ #include "H5Tprivate.h" /* Datatypes */ - /****************/ /* Local Macros */ /****************/ +#define H5R_MAX_STRING_LEN (1 << 16) /* Max encoded string length */ + +/* Encode macro */ +#define H5R_ENCODE(func, val, buf, buf_size, actual, m) do {\ + size_t __nalloc = buf_size; \ + if(func(val, buf, &__nalloc) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \ + if(buf && buf_size >= __nalloc) { \ + buf += __nalloc; \ + buf_size -= __nalloc; \ + } \ + actual += __nalloc; \ +} while(0) + +#define H5R_ENCODE_VAR(func, var, size, buf, buf_size, actual, m) do { \ + size_t __nalloc = buf_size; \ + if(func(var, size, buf, &__nalloc) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \ + if(buf && buf_size >= __nalloc) { \ + p += __nalloc; \ + buf_size -= __nalloc; \ + } \ + actual += __nalloc; \ +} while(0) + +/* Decode macro */ +#define H5R_DECODE(func, val, buf, buf_size, actual, m) do {\ + size_t __nbytes = buf_size; \ + if(func(buf, &__nbytes, val) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \ + buf += __nbytes; \ + buf_size -= __nbytes; \ + actual += __nbytes; \ +} while(0) + +#define H5R_DECODE_VAR(func, var, size, buf, buf_size, actual, m) do { \ + size_t __nbytes = buf_size; \ + if(func(buf, &__nbytes, var, size) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \ + p += __nbytes; \ + buf_size -= __nbytes; \ + actual += __nbytes; \ +} while(0) + +/* Debug */ +//#define H5R_DEBUG +#ifdef H5R_DEBUG +#define H5R_LOG_DEBUG(...) do { \ + HDfprintf(stdout, " # %s(): ", __func__); \ + HDfprintf(stdout, __VA_ARGS__); \ + HDfprintf(stdout, "\n"); \ + HDfflush(stdout); \ + } while (0) +static const char * +H5R__print_token(const H5VL_token_t token) { + static char string[64]; + HDsnprintf(string, 64, "%zu", *(haddr_t *)token); + return string; +} +#else +#define H5R_LOG_DEBUG(...) do { } while (0) +#endif + /******************/ /* Local Typedefs */ /******************/ @@ -48,6 +110,13 @@ /* Local Prototypes */ /********************/ +static herr_t H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, uint8_t *token_size); +static herr_t H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr); +static herr_t H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -82,14 +151,15 @@ DESCRIPTION herr_t H5R__init_package(void) { - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR /* Mark "top" of interface as initialized */ H5R_top_package_initialize_s = TRUE; - FUNC_LEAVE_NOAPI(ret_value) + /* Sanity check, if assert fails, H5R_REF_BUF_SIZE must be increased */ + HDcompile_assert(sizeof(H5R_ref_priv_t) <= H5R_REF_BUF_SIZE); + + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5R__init_package() */ @@ -167,571 +237,1473 @@ H5R_term_package(void) } /* end H5R_term_package() */ -/*-------------------------------------------------------------------------- - NAME - H5R__create - PURPOSE - Creates a particular kind of reference for the user - USAGE - herr_t H5R__create(ref, loc, name, ref_type, space) - void *ref; OUT: Reference created - H5G_loc_t *loc; IN: File location used to locate object pointed to - const char *name; IN: Name of object at location LOC_ID of object - pointed to - H5R_type_t ref_type; IN: Type of reference to create - H5S_t *space; IN: Dataspace ID with selection, used for Dataset - Region references. +/*------------------------------------------------------------------------- + * Function: H5R__create_object + * + * Purpose: Creates an object reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, + H5R_ref_priv_t *ref) +{ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Creates a particular type of reference specified with REF_TYPE, in the - space pointed to by REF. The LOC_ID and NAME are used to locate the object - pointed to and the SPACE_ID is used to choose the region pointed to (for - Dataset Region references). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE + + HDassert(ref); + + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_OBJECT2; + ref->token_size = (uint8_t)token_size; + + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; + + H5R_LOG_DEBUG("Created object reference, %d, filename=%s, obj_addr=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__create_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__create_region + * + * Purpose: Creates a region reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space) +H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, + H5S_t *space, H5R_ref_priv_t *ref) { - H5G_loc_t obj_loc; /* Group hier. location of object */ - H5G_name_t path; /* Object group hier. path */ - H5O_loc_t oloc; /* Object object location */ - hbool_t obj_found = FALSE; /* Object location found */ - herr_t ret_value = SUCCEED; /* Return value */ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(loc); - HDassert(name); - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); + HDassert(space); + HDassert(ref); - /* Set up object location to fill in */ - obj_loc.oloc = &oloc; - obj_loc.path = &path; - H5G_loc_reset(&obj_loc); + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + if(NULL == (ref->ref.reg.space = H5S_copy(space, FALSE, TRUE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") - /* Set the FAPL for the API context */ - H5CX_set_libver_bounds(loc->oloc->file); + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_DATASET_REGION2; + ref->token_size = (uint8_t)token_size; - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; - switch (ref_type) { - case H5R_OBJECT: - { - hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + H5R_LOG_DEBUG("Created region reference, %d, filename=%s, obj_addr=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); - *ref = obj_loc.oloc->addr; - break; +done: + if(ret_value < 0) { + if(ref->ref.reg.space) { + H5S_close(ref->ref.reg.space); + ref->ref.reg.space = NULL; } + } + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__create_region */ - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - hssize_t buf_size; /* Size of buffer needed to serialize selection */ - uint8_t *p; /* Pointer to OID to store */ - uint8_t *buf; /* Buffer to store serialized selection in */ - unsigned heapid_found; /* Flag for non-zero heap ID found */ - unsigned u; /* local index */ - - /* Set up information for dataset region */ - - /* Return any previous heap block to the free list if we are - * garbage collecting - */ - if (H5F_GC_REF(loc->oloc->file)) { - /* Check for an existing heap ID in the reference */ - for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++) - if (p[u] != 0) { - heapid_found = 1; - break; - } - - if (heapid_found != 0) { - /* Return heap block to free list */ - } - } - - /* Zero the heap ID out, may leak heap space if user is re-using - * reference and doesn't have garbage collection turned on - */ - HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE); - - /* Get the amount of space required to serialize the selection */ - if ((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") - - /* Increase buffer size to allow for the dataset OID */ - buf_size += (hssize_t)sizeof(haddr_t); - - /* Allocate the space to store the serialized information */ - H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); - if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Serialize information for dataset OID into heap buffer */ - p = (uint8_t *)buf; - H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); - - /* Serialize the selection into heap buffer */ - if (H5S_SELECT_SERIALIZE(space, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") - - /* Save the serialized buffer for later */ - H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); - if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection") - - /* Serialize the heap ID and index for storage in the file */ - p = (uint8_t *)ref; - H5F_addr_encode(loc->oloc->file, &p, hobjid.addr); - UINT32ENCODE(p, hobjid.idx); - - /* Free the buffer we serialized data in */ - H5MM_xfree(buf); - break; - } /* end case H5R_DATASET_REGION */ + +/*------------------------------------------------------------------------- + * Function: H5R__create_attr + * + * Purpose: Creates an attribute reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, + const char *attr_name, H5R_ref_priv_t *ref) +{ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + HDassert(attr_name); + HDassert(ref); + + /* Make sure that attribute name is not longer than supported encode size */ + if(HDstrlen(attr_name) > H5R_MAX_STRING_LEN) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "attribute name too long (%d > %d)", (int)HDstrlen(attr_name), H5R_MAX_STRING_LEN) + + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + if(NULL == (ref->ref.attr.name = HDstrdup(attr_name))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") + + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_ATTR; + ref->token_size = (uint8_t)token_size; + + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; + + H5R_LOG_DEBUG("Created attribute reference, %d, filename=%s, obj_addr=%s, attr name=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->ref.attr.name, ref->encode_size); +done: + if(ret_value < 0) + ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__create_attr */ + + +/*------------------------------------------------------------------------- + * Function: H5R__destroy + * + * Purpose: Destroy reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__destroy(H5R_ref_priv_t *ref) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + HDassert(ref != NULL); + + ref->ref.obj.filename = H5MM_xfree(ref->ref.obj.filename); + + switch(ref->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + if(H5S_close(ref->ref.reg.space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace") + ref->ref.reg.space = NULL; + break; + case H5R_ATTR: + ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ -done: - if (obj_found) - H5G_loc_free(&obj_loc); + /* Decrement refcount of attached loc_id */ + if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed") +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__create() */ +} /* end H5R__destroy() */ -/*-------------------------------------------------------------------------- - NAME - H5R__dereference - PURPOSE - Opens the HDF5 object referenced. - USAGE - hid_t H5R__dereference(ref, oapl_id, ref_type, ref) - H5F_t *file; IN: File the object being dereferenced is within - hid_t oapl_id; IN: Object access property list ID - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to open. +/*------------------------------------------------------------------------- + * Function: H5R__set_loc_id + * + * Purpose: Attach location ID to reference and increment location refcount. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref) +{ + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Valid ID on success, Negative on failure - DESCRIPTION - Given a reference to some object, open that object and return an ID for - that object. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Currently only set up to work with references to datasets - EXAMPLES - REVISION LOG - Raymond Lu - 13 July 2011 - I added the OAPL_ID parameter for the object being referenced. It only - supports dataset access property list currently. - - M. Scot Breitenfeld - 3 March 2015 - Added a check for undefined reference pointer. ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE + + HDassert(ref != NULL); + HDassert(id != H5I_INVALID_HID); + + /* If a location ID was previously assigned, decrement refcount and assign new one */ + if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed") + ref->loc_id = id; + + /* Prevent location ID from being freed until reference is destroyed */ + if(inc_ref && H5I_inc_ref(ref->loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINC, FAIL, "incrementing location ID failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__set_loc_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__get_loc_id + * + * Purpose: Retrieve location ID attached to existing reference. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5R__dereference(H5F_t *file, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) +H5R__get_loc_id(const H5R_ref_priv_t *ref) { - H5O_loc_t oloc; /* Object location */ - H5G_name_t path; /* Path of object */ - H5G_loc_t loc; /* Group location */ - unsigned rc; /* Reference count of object */ - H5O_type_t obj_type; /* Type of object */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ + FUNC_ENTER_PACKAGE_NOERR + + HDassert(ref != NULL); + + ret_value = ref->loc_id; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_loc_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__reopen_file + * + * Purpose: Re-open referenced file using file access property list. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) +{ + void *new_file = NULL; + H5VL_connector_prop_t connector_prop; + unsigned flags = H5F_ACC_RDWR; /* Must open file read-write to allow for object modifications */ + H5P_genplist_t *plist; + hid_t ret_value = H5I_INVALID_HID; + FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); - HDassert(file); + /* TODO add search path */ - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = file; + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - switch (ref_type) { - case H5R_OBJECT: - { - oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ - if (!H5F_addr_defined(oloc.addr) || oloc.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") - break; - } + /* Get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file access property list") + if(H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info") - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ + /* Stash a copy of the "top-level" connector property, before any pass-through + * connectors modify or unwrap it. + */ + if(H5CX_set_vol_connector_prop(&connector_prop) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context") - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); + /* Open the file */ + if(NULL == (new_file = H5VL_file_open(&connector_prop, H5R_REF_FILENAME(ref), flags, fapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file") - if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") + /* Get an ID for the file */ + if((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5I_INVALID_HID, "Unable to read dataset region information") + /* Attach loc_id to reference */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref, ret_value, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "unable to attach location id to reference") - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__reopen_file() */ - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - break; - } /* end case H5R_DATASET_REGION */ + +/*------------------------------------------------------------------------- + * Function: H5R__get_type + * + * Purpose: Given a reference to some object, return the type of that reference. + * + * Return: Type of the reference + * + *------------------------------------------------------------------------- + */ +H5R_type_t +H5R__get_type(const H5R_ref_priv_t *ref) +{ + H5R_type_t ret_value = H5R_BADTYPE; + + FUNC_ENTER_PACKAGE_NOERR + + HDassert(ref != NULL); + ret_value = ref->type; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__equal + * + * Purpose: Compare two references + * + * Return: TRUE if equal, FALSE if unequal, FAIL if error + * + *------------------------------------------------------------------------- + */ +htri_t +H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2) +{ + htri_t ret_value = TRUE; + + FUNC_ENTER_PACKAGE + HDassert(ref1 != NULL); + HDassert(ref2 != NULL); + + /* Compare reference types */ + if(ref1->type != ref2->type) + HGOTO_DONE(FALSE); + + /* Compare object addresses */ + if(ref1->token_size != ref2->token_size) + HGOTO_DONE(FALSE); + if(0 != HDmemcmp(ref1->ref.obj.token, ref2->ref.obj.token, ref1->token_size)) + HGOTO_DONE(FALSE); + + /* Compare filenames */ + if((ref1->ref.obj.filename && (NULL == ref2->ref.obj.filename)) + || ((NULL == ref1->ref.obj.filename) && ref2->ref.obj.filename)) + HGOTO_DONE(FALSE); + if(ref1->ref.obj.filename && ref1->ref.obj.filename + && (0 != HDstrcmp(ref1->ref.obj.filename, ref2->ref.obj.filename))) + HGOTO_DONE(FALSE); + + switch(ref1->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + if((ret_value = H5S_extent_equal(ref1->ref.reg.space, ref2->ref.reg.space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare dataspace extents") + break; + case H5R_ATTR: + HDassert(ref1->ref.attr.name && ref2->ref.attr.name); + if(0 != HDstrcmp(ref1->ref.attr.name, ref2->ref.attr.name)) + HGOTO_DONE(FALSE); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); - HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5I_INVALID_HID, "internal error (unknown reference type)") + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Get the # of links for object, and its type - * (To check to make certain that this object hasn't been deleted - * since the reference was created) - */ - if(H5O_get_rc_and_type(&oloc, &rc, &obj_type) < 0 || 0 == rc) - HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5I_INVALID_HID, "dereferencing deleted object") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__equal() */ - /* Construct a group location for opening the object */ - H5G_name_reset(&path); - loc.oloc = &oloc; - loc.path = &path; + +/*------------------------------------------------------------------------- + * Function: H5R__copy + * + * Purpose: Copy a reference + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) +{ + herr_t ret_value = SUCCEED; - /* Open the object */ - switch (obj_type) { - case H5O_TYPE_GROUP: - { - H5G_t *group; /* Pointer to group to open */ + FUNC_ENTER_PACKAGE - if(NULL == (group = H5G_open(&loc))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5I_INVALID_HID, "not found") + HDassert((src_ref != NULL) && (dst_ref != NULL)); - /* Create an atom for the group */ - if((ret_value = H5I_register(H5I_GROUP, group, TRUE)) < 0) { - H5G_close(group); - HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register group") - } + H5MM_memcpy(dst_ref->ref.obj.token, src_ref->ref.obj.token, src_ref->token_size); + dst_ref->encode_size = src_ref->encode_size; + dst_ref->type = src_ref->type; + dst_ref->token_size = src_ref->token_size; + switch(src_ref->type) { + case H5R_OBJECT2: break; - } - - case H5O_TYPE_NAMED_DATATYPE: - { - H5T_t *type; /* Pointer to datatype to open */ - - if(NULL == (type = H5T_open(&loc))) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, H5I_INVALID_HID, "not found") + case H5R_DATASET_REGION2: + if(NULL == (dst_ref->ref.reg.space = H5S_copy(src_ref->ref.reg.space, FALSE, TRUE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") + break; + case H5R_ATTR: + if(NULL == (dst_ref->ref.attr.name = HDstrdup(src_ref->ref.attr.name))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ - /* Create an atom for the datatype */ - if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) { - H5T_close(type); - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register datatype") - } + /* We only need to keep a copy of the filename if we don't have the loc_id */ + if(src_ref->loc_id == H5I_INVALID_HID) { + HDassert(src_ref->ref.obj.filename); - break; - } + if(NULL == (dst_ref->ref.obj.filename = HDstrdup(src_ref->ref.obj.filename))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy filename") + dst_ref->loc_id = H5I_INVALID_HID; + } else { + dst_ref->ref.obj.filename = NULL; - case H5O_TYPE_DATASET: - { - H5D_t *dset; /* Pointer to dataset to open */ + /* Set location ID and hold reference to it */ + if(H5R__set_loc_id(dst_ref, src_ref->loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "cannot set reference location ID") + } - /* Open the dataset */ - if(NULL == (dset = H5D_open(&loc, oapl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, H5I_INVALID_HID, "not found") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__copy() */ - /* Create an atom for the dataset */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) { - H5D_close(dset); - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset") - } + +/*------------------------------------------------------------------------- + * Function: H5R__get_obj_token + * + * Purpose: Given a reference to some object, get the encoded object addr. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, + size_t *token_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ - break; - } + FUNC_ENTER_PACKAGE - case H5O_TYPE_MAP: - HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "maps not supported in native VOL connector") + HDassert(ref != NULL); + HDassert(ref->token_size <= H5VL_MAX_TOKEN_SIZE); - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: - HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "can't identify type of object referenced") - } /* end switch */ + if(obj_token) { + if(0 == ref->token_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "NULL token size") + H5MM_memcpy(obj_token, ref->ref.obj.token, ref->token_size); + } + if(token_size) + *token_size = ref->token_size; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__dereference() */ +} /* end H5R__get_obj_token() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_region - PURPOSE - Retrieves a dataspace with the region pointed to selected. - USAGE - H5S_t *H5R__get_region(file, ref) - H5F_t *file; IN: File the object being dereferenced is within - void *ref; IN: Reference to open. +/*------------------------------------------------------------------------- + * Function: H5R__set_obj_token + * + * Purpose: Given a reference to some object, set the encoded object addr. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, + size_t token_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Pointer to the dataspace on success, NULL on failure - DESCRIPTION - Given a reference to some object, creates a copy of the dataset pointed - to's dataspace and defines a selection in the copy which is the region - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -H5S_t * -H5R__get_region(H5F_t *file, const void *_ref) + FUNC_ENTER_PACKAGE_NOERR + + HDassert(ref != NULL); + HDassert(obj_token); + HDassert(token_size); + HDassert(token_size <= H5VL_MAX_TOKEN_SIZE); + + H5MM_memcpy(ref->ref.obj.token, obj_token, ref->token_size); + ref->token_size = token_size; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__set_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__get_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy which is the + * region pointed to. + * + * Return: Pointer to the dataspace on success/NULL on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space) { - H5O_loc_t oloc; /* Object location */ - const uint8_t *p; /* Pointer to OID to store */ - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf = NULL; /* Buffer to store serialized selection in */ - H5S_t *ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(file); + HDassert(ref != NULL); + HDassert(ref->type == H5R_DATASET_REGION2); + HDassert(space); - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = file; + /* Copy reference selection to destination */ + if(H5S_select_copy(space, ref->ref.reg.space, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy selection") - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__get_file_name + * + * Purpose: Given a reference to some object, determine a file name of the + * object located into. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size) +{ + size_t copy_len; + ssize_t ret_value = -1; /* Return value */ - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information") + FUNC_ENTER_PACKAGE - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + /* Check args */ + HDassert(ref != NULL); - /* Open and copy the dataset's dataspace */ - if(NULL == (ret_value = H5S_read(&oloc))) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found") + /* Return if that reference has no filename set */ + if(!ref->ref.obj.filename) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, (-1), "no filename available for that reference") - /* Unserialize the selection */ - if(H5S_SELECT_DESERIALIZE(&ret_value, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") + /* Get the file name length */ + copy_len = HDstrlen(ref->ref.obj.filename); + HDassert(copy_len <= H5R_MAX_STRING_LEN); -done: - /* Free the buffer allocated in H5HG_read() */ - if(buf) - H5MM_xfree(buf); + /* Copy the file name */ + if(buf) { + copy_len = MIN(copy_len, size - 1); + H5MM_memcpy(buf, ref->ref.obj.filename, copy_len); + buf[copy_len] = '\0'; + } + ret_value = (ssize_t)(copy_len + 1); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_region() */ +} /* end H5R__get_file_name() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_obj_type - PURPOSE - Retrieves the type of object that an object reference points to - USAGE - H5O_type_t H5R__get_obj_type(file, ref_type, ref) - H5F_t *file; IN: File the object being dereferenced is within - H5R_type_t ref_type; IN: Type of reference to query - void *ref; IN: Reference to query. - H5O_type_t *obj_type; OUT: The type of the object, set on success +/*------------------------------------------------------------------------- + * Function: H5R__get_attr_name + * + * Purpose: Given a reference to some attribute, determine its name. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size) +{ + ssize_t ret_value = -1; /* Return value */ + size_t attr_name_len; /* Length of the attribute name */ - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Given a reference to some object, this function returns the type of object - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE_NOERR + + /* Check args */ + HDassert(ref != NULL); + HDassert(ref->type == H5R_ATTR); + + /* Get the attribute name length */ + attr_name_len = HDstrlen(ref->ref.attr.name); + HDassert(attr_name_len <= H5R_MAX_STRING_LEN); + + /* Get the attribute name */ + if(buf) { + size_t copy_len = MIN(attr_name_len, size - 1); + H5MM_memcpy(buf, ref->ref.attr.name, copy_len); + buf[copy_len] = '\0'; + } + + ret_value = (ssize_t)(attr_name_len + 1); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_attr_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode + * + * Purpose: Private function for H5Rencode. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref, - H5O_type_t *obj_type) +H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, + size_t *nalloc, unsigned flags) { - H5O_loc_t oloc; /* Object location */ - unsigned rc; /* Reference count of object */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *p = (uint8_t *)buf; + size_t buf_size = 0, encode_size = 0; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - HDassert(file); - HDassert(_ref); + HDassert(ref); + HDassert(nalloc); + + /** + * Encoding format: + * | Reference type (8 bits) | Flags (8 bits) | Token (token size) + * | | + * | |----> H5R_IS_EXTERNAL: File info + * | + * |----> H5R_DATASET_REGION2: Serialized selection + * | + * |----> H5R_ATTR: Attribute name len + name + * + */ + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= H5R_ENCODE_HEADER_SIZE) { + /* Encode the type of the reference */ + *p++ = (uint8_t)ref->type; + + /* Encode the flags */ + *p++ = (uint8_t)flags; - /* Initialize the symbol table entry */ - H5O_loc_reset(&oloc); - oloc.file = file; + buf_size = *nalloc - H5R_ENCODE_HEADER_SIZE; + } + encode_size += H5R_ENCODE_HEADER_SIZE; + + /* Encode object token */ + H5R_ENCODE_VAR(H5R__encode_obj_token, &ref->ref.obj.token, ref->token_size, + p, buf_size, encode_size, "Cannot encode object address"); + + /** + * TODO Encode VOL info + * When we have a better way of storing blobs, we should add + * support for referencing files in external VOLs. + * There are currently multiple limitations: + * - avoid duplicating VOL info on each reference + * - must query terminal VOL connector to avoid passthrough confusion + */ + if(flags & H5R_IS_EXTERNAL) { + /* Encode file name */ + H5R_ENCODE(H5R__encode_string, filename, p, buf_size, encode_size, + "Cannot encode filename"); + } - switch (ref_type) { - case H5R_OBJECT: - { - /* Get the object oid */ - oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + switch(ref->type) { + case H5R_OBJECT2: break; - } + case H5R_DATASET_REGION2: + /* Encode dataspace */ + H5R_ENCODE(H5R__encode_region, ref->ref.reg.space, p, buf_size, + encode_size, "Cannot encode region"); + break; + case H5R_ATTR: + /* Encode attribute name */ + H5R_ENCODE(H5R__encode_string, ref->ref.attr.name, p, buf_size, + encode_size, "Cannot encode attribute name"); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: + case H5R_BADTYPE: + case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ + + *nalloc = encode_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode() */ - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - const uint8_t *p; /* Pointer to reference to decode */ - uint8_t *buf; /* Buffer to store serialized selection in */ + +/*------------------------------------------------------------------------- + * Function: H5R__decode + * + * Purpose: Private function for H5Rdecode. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size = 0, decode_size = 0; + uint8_t flags; + herr_t ret_value = SUCCEED; - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); + FUNC_ENTER_PACKAGE - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + HDassert(buf); + HDassert(nbytes); + HDassert(ref); + buf_size = *nbytes; - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + /* Don't decode if buffer size isn't big enough */ + if(buf_size < H5R_ENCODE_HEADER_SIZE) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); + /* Set new reference */ + ref->type = (H5R_type_t)*p++; + if(ref->type <= H5R_BADTYPE || ref->type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - break; - } + /* Set flags */ + flags = *p++; + + buf_size -= H5R_ENCODE_HEADER_SIZE; + decode_size += H5R_ENCODE_HEADER_SIZE; + /* Decode object token */ + H5R_DECODE_VAR(H5R__decode_obj_token, &ref->ref.obj.token, &ref->token_size, + p, buf_size, decode_size, "Cannot decode object address"); + + /* We do not need to store the filename if the reference is internal */ + if(flags & H5R_IS_EXTERNAL) { + /* Decode file name */ + H5R_DECODE(H5R__decode_string, &ref->ref.obj.filename, p, buf_size, + decode_size, "Cannot decode filename"); + } else + ref->ref.obj.filename = NULL; + + switch(ref->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + /* Decode dataspace */ + H5R_DECODE(H5R__decode_region, &ref->ref.reg.space, p, buf_size, + decode_size, "Cannot decode region"); + break; + case H5R_ATTR: + /* Decode attribute name */ + H5R_DECODE(H5R__decode_string, &ref->ref.attr.name, p, buf_size, + decode_size, "Cannot decode attribute name"); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Get the # of links for object, and its type */ - /* (To check to make certain that this object hasn't been deleted since the reference was created) */ - if(H5O_get_rc_and_type(&oloc, &rc, obj_type) < 0 || 0 == rc) - HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") + /* Set loc ID to invalid */ + ref->loc_id = H5I_INVALID_HID; + + /* Set encoding size */ + ref->encode_size = decode_size; + + H5R_LOG_DEBUG("Decoded reference, filename=%s, obj_addr=%s, encode size=%u", + ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); + + *nbytes = decode_size; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_obj_type() */ +} /* end H5R__decode() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_name - PURPOSE - Internal routine to determine a name for the object referenced - USAGE - ssize_t H5R__get_name(f, ref_type, ref, name, size) - H5F_t *f; IN: Pointer to the file that the reference is pointing - into - hid_t lapl_id; IN: LAPL to use for operation - hid_t id; IN: Location ID given for reference - H5R_type_t ref_type; IN: Type of reference - void *_ref; IN: Reference to query. - char *name; OUT: Buffer to place name of object referenced - size_t size; IN: Size of name buffer +/*------------------------------------------------------------------------- + * Function: H5R__encode_obj_token + * + * Purpose: Encode an object address. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, + unsigned char *buf, size_t *nalloc) +{ + herr_t ret_value = SUCCEED; - RETURNS - Non-negative length of the path on success, -1 on failure - DESCRIPTION - Given a reference to some object, determine a path to the object - referenced in the file. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This may not be the only path to that object. - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -ssize_t -H5R__get_name(H5F_t *f, H5R_type_t ref_type, const void *_ref, - char *name, size_t size) + FUNC_ENTER_STATIC_NOERR + + HDassert(nalloc); + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= token_size) { + uint8_t *p = (uint8_t *)buf; + + /* Encode token size */ + *p++ = (uint8_t)(token_size & 0xff); + + /* Encode token */ + H5MM_memcpy(p, obj_token, token_size); + } + *nalloc = token_size + H5_SIZEOF_UINT8_T; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_obj_token + * + * Purpose: Decode an object address. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, + H5VL_token_t *obj_token, uint8_t *token_size) { - H5O_loc_t oloc; /* Object location describing object for reference */ - ssize_t ret_value = -1; /* Return value */ + const uint8_t *p = (const uint8_t *)buf; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(obj_token); + HDassert(token_size); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < H5_SIZEOF_UINT8_T) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get token size */ + *token_size = *p++; + if(*token_size > sizeof(H5VL_token_t)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Invalid token size (%u)", *token_size) + + /* Decode token */ + H5MM_memcpy(obj_token, p, *token_size); + + *nbytes = *token_size + H5_SIZEOF_UINT8_T; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_region + * + * Purpose: Encode a selection. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc) +{ + uint8_t *p = NULL; /* Pointer to data to store */ + hssize_t buf_size = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(space); + HDassert(nalloc); + + /* Get the amount of space required to serialize the selection */ + if((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot determine amount of space needed for serializing selection") + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= ((size_t)buf_size + 2 * H5_SIZEOF_UINT32_T)) { + p = (uint8_t *)buf; + int rank; + + /* Encode the size for safety check */ + UINT32ENCODE(p, (uint32_t)buf_size); + + /* Encode the extent rank */ + if((rank = H5S_get_simple_extent_ndims(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get extent rank for selection") + UINT32ENCODE(p, (uint32_t)rank); + + /* Serialize the selection */ + if(H5S_SELECT_SERIALIZE(space, (unsigned char **)&p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't serialize selection") + } + *nalloc = (size_t)buf_size + 2 * H5_SIZEOF_UINT32_T; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_region + * + * Purpose: Decode a selection. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size = 0; + unsigned rank; + H5S_t *space; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(space_ptr); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < (2 * H5_SIZEOF_UINT32_T)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Decode the selection size */ + UINT32DECODE(p, buf_size); + buf_size += H5_SIZEOF_UINT32_T; + + /* Decode the extent rank */ + UINT32DECODE(p, rank); + buf_size += H5_SIZEOF_UINT32_T; + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Deserialize the selection (dataspaces need the extent rank information) */ + if(NULL == (space = H5S_create(H5S_SIMPLE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + if(H5S_set_extent_simple(space, rank, NULL, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set extent rank for selection") + if(H5S_SELECT_DESERIALIZE(&space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection") + + *nbytes = buf_size; + *space_ptr = space; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_string + * + * Purpose: Encode a string. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc) +{ + size_t string_len, buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(string); + HDassert(nalloc); + + /* Get the amount of space required to serialize the string */ + string_len = HDstrlen(string); + if(string_len > H5R_MAX_STRING_LEN) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "string too long") + + /* Compute buffer size, allow for the attribute name length and object address */ + buf_size = string_len + sizeof(uint16_t); + + if(buf && *nalloc >= buf_size) { + uint8_t *p = (uint8_t *)buf; + /* Serialize information for string length into the buffer */ + UINT16ENCODE(p, string_len); + /* Copy the string into the buffer */ + H5MM_memcpy(p, string, string_len); + } + *nalloc = buf_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_string() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_string + * + * Purpose: Decode a string. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t string_len; + char *string = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(string_ptr); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < sizeof(uint16_t)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the string length */ + UINT16DECODE(p, string_len); + HDassert(string_len <= H5R_MAX_STRING_LEN); + + /* Allocate the string */ + if(NULL == (string = H5MM_malloc(string_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "Cannot allocate string") + + /* Copy the string */ + H5MM_memcpy(string, p, string_len); + string[string_len] = '\0'; + + *string_ptr = string; + *nbytes = sizeof(uint16_t) + string_len; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_string() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_heap + * + * Purpose: Encode data and insert into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, + const unsigned char *data, size_t data_size) +{ + size_t buf_size; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - /* Check args */ HDassert(f); - HDassert(_ref); + HDassert(nalloc); - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = f; + buf_size = H5HG_HEAP_ID_SIZE(f); + if(buf && *nalloc >= buf_size) { + H5HG_t hobjid; + uint8_t *p = (uint8_t *)buf; - /* Get address for reference */ - switch (ref_type) { - case H5R_OBJECT: - { - oloc.addr = *(const hobj_ref_t *)_ref; - break; - } + /* Write the reference information to disk (allocates space also) */ + if(H5HG_insert(f, data_size, (void *)data, &hobjid) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write reference information") - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ + /* Encode the heap information */ + H5F_addr_encode(f, &p, hobjid.addr); + UINT32ENCODE(p, hobjid.idx); + } + *nalloc = buf_size; - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_heap() */ - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, (-1), "Unable to read dataset region information") + +/*------------------------------------------------------------------------- + * Function: H5R__decode_heap + * + * Purpose: Decode data inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, + unsigned char **data_ptr, size_t *data_size) +{ + const uint8_t *p = (const uint8_t *)buf; + H5HG_t hobjid; + size_t buf_size; + herr_t ret_value = SUCCEED; - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + FUNC_ENTER_PACKAGE - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); + HDassert(f); + HDassert(buf); + HDassert(nbytes); + HDassert(data_ptr); + + buf_size = H5HG_HEAP_ID_SIZE(f); + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the heap information */ + H5F_addr_decode(f, &p, &(hobjid.addr)); + if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + UINT32DECODE(p, hobjid.idx); - break; - } + /* Read the information from disk */ + if(NULL == (*data_ptr = (unsigned char *)H5HG_read(f, &hobjid, (void *)*data_ptr, data_size))) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read reference data") - case H5R_BADTYPE: - case H5R_MAXTYPE: - default: - HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, (-1), "internal error (unknown reference type)") - } /* end switch */ + *nbytes = buf_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__free_heap + * + * Purpose: Remove data previously inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes) +{ + H5HG_t hobjid; + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(buf); + + buf_size = H5HG_HEAP_ID_SIZE(f); + /* Don't decode if buffer size isn't big enough */ + if(nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the heap information */ + H5F_addr_decode(f, &p, &(hobjid.addr)); + if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + UINT32DECODE(p, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) { + /* Free heap object */ + if(H5HG_remove(f, &hobjid) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__free_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_addr_compat + * + * Purpose: Decode an object address. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_addr_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type, + const unsigned char *buf, haddr_t *addr_ptr) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + if(ref_type == H5R_OBJECT1) { + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + + /* Get object address */ + if(H5R__decode_addr_obj_compat(buf, &buf_size, addr_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + } else { + void *vol_obj_file = NULL; + H5F_t *f = NULL; + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(id, type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data(vol_obj_file))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") + + /* Get object address */ + if(H5R__decode_addr_region_compat(f, buf, &buf_size, addr_ptr, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + } + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_addr_obj_compat + * + * Purpose: Encode an object address. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_addr_obj_compat(haddr_t addr, unsigned char *buf, size_t *nalloc) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE_NOERR + + HDassert(nalloc); + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= sizeof(addr)) + H5MM_memcpy(buf, &addr, sizeof(addr)); + *nalloc = sizeof(addr); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_addr_obj_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_addr_obj_compat + * + * Purpose: Decode an object address. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_addr_obj_compat(const unsigned char *buf, size_t *nbytes, + haddr_t *addr_ptr) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(buf); + HDassert(nbytes); + HDassert(addr_ptr); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < sizeof(*addr_ptr)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") - /* Get name, length, etc. */ - if((ret_value = H5G_get_name_by_addr(f, &oloc, name, size)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't determine name") + H5MM_memcpy(addr_ptr, buf, sizeof(*addr_ptr)); + + *nbytes = sizeof(*addr_ptr); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_name() */ +} /* H5R__decode_addr_obj_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_addr_region_compat + * + * Purpose: Encode dataset selection and insert data into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_addr_region_compat(H5F_t *f, haddr_t obj_addr, H5S_t *space, + unsigned char *buf, size_t *nalloc) +{ + size_t buf_size; + unsigned char *data = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(space); + HDassert(nalloc); + + /* Get required buffer size */ + if(H5R__encode_heap(f, NULL, &buf_size, NULL, (size_t)0) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + if(buf && *nalloc >= buf_size) { + ssize_t data_size; + uint8_t *p; + + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper encode */ + H5CX_set_libver_bounds(f); + + /* Zero the heap ID out, may leak heap space if user is re-using + * reference and doesn't have garbage collection turned on + */ + HDmemset(buf, 0, buf_size); + + /* Get the amount of space required to serialize the selection */ + if((data_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") + /* Increase buffer size to allow for the dataset OID */ + data_size += (hssize_t)sizeof(haddr_t); + + /* Allocate the space to store the serialized information */ + H5_CHECK_OVERFLOW(data_size, hssize_t, size_t); + if(NULL == (data = (uint8_t *)H5MM_malloc((size_t)data_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Serialize information for dataset OID into heap buffer */ + p = (uint8_t *)data; + H5F_addr_encode(f, &p, obj_addr); + + /* Serialize the selection into heap buffer */ + if(H5S_SELECT_SERIALIZE(space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + + /* Write to heap */ + if(H5R__encode_heap(f, buf, nalloc, data, (size_t)data_size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + } + *nalloc = buf_size; + +done: + H5MM_free(data); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__encode_addr_region_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_obj_addr_compat + * + * Purpose: Decode dataset selection from data inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_addr_region_compat(H5F_t *f, const unsigned char *buf, + size_t *nbytes, haddr_t *obj_addr_ptr, H5S_t **space_ptr) +{ + unsigned char *data = NULL; + size_t data_size; + haddr_t obj_addr; + const uint8_t *p; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(buf); + HDassert(nbytes); + + /* Read from heap */ + if(H5R__decode_heap(f, buf, nbytes, &data, &data_size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object address */ + p = (const uint8_t *)data; + H5F_addr_decode(f, &p, &obj_addr); + if(!H5F_addr_defined(obj_addr) || obj_addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + + if(space_ptr) { + H5O_loc_t oloc; /* Object location */ + H5S_t *space = NULL; + + /* Initialize the object location */ + H5O_loc_reset(&oloc); + oloc.file = f; + oloc.addr = obj_addr; + + /* Open and copy the dataset's dataspace */ + if(NULL == (space = H5S_read(&oloc))) + HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "not found") + + /* Unserialize the selection */ + if(H5S_SELECT_DESERIALIZE(&space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection") + + *space_ptr = space; + } + if(obj_addr_ptr) + *obj_addr_ptr = obj_addr; + +done: + H5MM_free(data); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_addr_region_compat() */ diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 1c1c8eb..1843bcf 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -36,11 +36,51 @@ /* Package Private Macros */ /**************************/ +/* Encode flags */ +#define H5R_IS_EXTERNAL 0x1 /* Set when encoding reference to external file */ + +/* Macros for convenience */ +#define H5R_REF_FILENAME(x) ((x)->ref.obj.filename) +#define H5R_REF_ATTRNAME(x) ((x)->ref.attr.name) + +/* Header size */ +#define H5R_ENCODE_HEADER_SIZE (2 * H5_SIZEOF_UINT8_T) /****************************/ /* Package Private Typedefs */ /****************************/ +/* Object reference */ +typedef struct H5R_ref_priv_obj_t { + H5VL_token_t token; /* Object token */ + char *filename; /* File name */ +} H5R_ref_priv_obj_t; + +/* Region reference */ +typedef struct H5R_ref_priv_reg_t { + H5R_ref_priv_obj_t obj; /* Object reference */ + H5S_t *space; /* Selection */ +} H5R_ref_priv_reg_t; + +/* Attribute reference */ +typedef struct H5R_ref_priv_attr_t { + H5R_ref_priv_obj_t obj; /* Object reference */ + char *name; /* Attribute name */ +} H5R_ref_priv_attr_t; + +/* Generic reference type (keep it cache aligned) */ +typedef struct H5R_ref_priv_t { + union { + H5R_ref_priv_obj_t obj;/* Object reference */ + H5R_ref_priv_reg_t reg;/* Region reference */ + H5R_ref_priv_attr_t attr;/* Attribute Reference */ + } ref; + hid_t loc_id; /* Cached location identifier */ + uint32_t encode_size; /* Cached encoding size */ + int8_t type; /* Reference type */ + uint8_t token_size; /* Cached token size */ + char unused[18]; /* Unused */ +} H5R_ref_priv_t; /*****************************/ /* Package Private Variables */ @@ -50,11 +90,41 @@ /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5R__create(void *ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space); -H5_DLL hid_t H5R__dereference(H5F_t *file, hid_t dapl_id, H5R_type_t ref_type, const void *_ref); -H5_DLL H5S_t *H5R__get_region(H5F_t *file, const void *_ref); -H5_DLL herr_t H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type); -H5_DLL ssize_t H5R__get_name(H5F_t *file, H5R_type_t ref_type, const void *_ref, char *name, size_t size); +H5_DLL herr_t H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__destroy(H5R_ref_priv_t *ref); + +H5_DLL herr_t H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref); +H5_DLL hid_t H5R__get_loc_id(const H5R_ref_priv_t *ref); +H5_DLL hid_t H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id); + +H5_DLL H5R_type_t H5R__get_type(const H5R_ref_priv_t *ref); +H5_DLL htri_t H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2); +H5_DLL herr_t H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref); + +H5_DLL herr_t H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, size_t *token_size); +H5_DLL herr_t H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, size_t token_size); +H5_DLL herr_t H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space); + +H5_DLL ssize_t H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size); +H5_DLL ssize_t H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size); + +H5_DLL herr_t H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, size_t *nalloc, unsigned flags); +H5_DLL herr_t H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref); + +/* Native HDF5 specific routines */ +H5_DLL herr_t H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, const unsigned char *data, size_t data_size); +H5_DLL herr_t H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, unsigned char **data_ptr, size_t *data_size); +H5_DLL herr_t H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes); + +H5_DLL herr_t H5R__decode_addr_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type, const unsigned char *buf, haddr_t *addr_ptr); + +H5_DLL herr_t H5R__encode_addr_obj_compat(haddr_t obj_addr, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_addr_obj_compat(const unsigned char *buf, size_t *nbytes, haddr_t *obj_addr_ptr); + +H5_DLL herr_t H5R__encode_addr_region_compat(H5F_t *f, haddr_t obj_addr, H5S_t *space, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_addr_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, haddr_t *obj_addr_ptr, H5S_t **space_ptr); #endif /* _H5Rpkg_H */ diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h index 1bf2e92..6afec47 100644 --- a/src/H5Rprivate.h +++ b/src/H5Rprivate.h @@ -25,6 +25,8 @@ /* Library Private Macros */ /**************************/ +#define H5R_ENCODE_VERSION 0x1 /* Version for encoding references */ + /****************************/ /* Library Private Typedefs */ @@ -41,4 +43,3 @@ /******************************/ #endif /* _H5Rprivate_H */ - diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 598bafd..ce54ac4 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -26,47 +26,64 @@ /* Public Macros */ /*****************/ -/* Note! Be careful with the sizes of the references because they should really - * depend on the run-time values in the file. Unfortunately, the arrays need - * to be defined at compile-time, so we have to go with the worst case sizes - * for them. -QAK - */ +/* Deprecated reference buffer sizes that are kept for backward compatibility */ #define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) +#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) -/* 4 is used instead of sizeof(int) to permit portability between the Crays - * and other machines (the heap ID is always encoded as an int32 anyway). +/* Default reference buffer size. + * Note! Be careful with the sizes of the references because they should really + * depend on the run-time values in the file. */ -#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) +#define H5R_REF_BUF_SIZE (64) /*******************/ /* Public Typedefs */ /*******************/ -/* Reference types */ -typedef enum H5R_type_t { - H5R_BADTYPE = (-1), /* Invalid Reference Type */ - H5R_OBJECT, /* Object reference */ - H5R_DATASET_REGION, /* Dataset Region Reference */ - H5R_MAXTYPE /* Highest type (Invalid as true type) */ +/* + * Reference types allowed. + * DO NOT CHANGE THE ORDER or VALUES as reference type values are encoded into + * the datatype message header. + */ +typedef enum { + H5R_BADTYPE = (-1), /* Invalid reference type */ + H5R_OBJECT1 = 0, /* Backward compatibility (object) */ + H5R_DATASET_REGION1 = 1, /* Backward compatibility (region) */ + H5R_OBJECT2 = 2, /* Object reference */ + H5R_DATASET_REGION2 = 3, /* Region reference */ + H5R_ATTR = 4, /* Attribute Reference */ + H5R_MAXTYPE = 5 /* Highest type (invalid) */ } H5R_type_t; -/* Object reference structure for user's code - * This needs to be large enough to store largest haddr_t on a worst case - * machine (8 bytes currently). +/* Deprecated types are kept for backward compatibility with previous versions */ + +/** + * Deprecated object reference type that is used with deprecated reference APIs. + * Note! This type can only be used with the "native" HDF5 VOL connector. */ typedef haddr_t hobj_ref_t; -/* Dataset Region reference structure for user's code +/** + * Dataset region reference type that is used with deprecated reference APIs. * (Buffer to store heap ID and index) * This needs to be large enough to store largest haddr_t in a worst case - * machine (8 bytes currently) plus an int + * machine (8 bytes currently) plus an int. + * Note! This type can only be used with the "native" HDF5 VOL connector. */ typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE]; +/** + * Opaque reference type. The same reference type is used for object, + * dataset region and attribute references. This is the type that + * should always be used with the current reference API. + */ +typedef unsigned char H5R_ref_t[H5R_REF_BUF_SIZE]; + /********************/ /* Public Variables */ /********************/ + /*********************/ /* Public Prototypes */ /*********************/ @@ -75,30 +92,57 @@ typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE]; extern "C" { #endif -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 H5Rdereference2(hid_t obj_id, hid_t oapl_id, 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 herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *_ref, - H5O_type_t *obj_type); -H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, - char *name /*out*/, size_t size); +/* Constructors */ +H5_DLL herr_t H5Rcreate_object(hid_t loc_id, const char *name, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rdestroy(H5R_ref_t *ref_ptr); + +/* Info */ +H5_DLL H5R_type_t H5Rget_type(const H5R_ref_t *ref_ptr); +H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); +H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr); + +/* Dereference */ +H5_DLL hid_t H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id); + +/* Get type */ +H5_DLL herr_t H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type); + +/* Get name */ +H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); +H5_DLL ssize_t H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size); +H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); /* Symbols defined for compatibility with previous versions of the HDF5 API. * - * Use of these symbols is deprecated. + * Use of these symbols is or will be deprecated. */ -#ifndef H5_NO_DEPRECATED_SYMBOLS + +/* Macros */ + +/* Versions for compatibility */ +#define H5R_OBJECT H5R_OBJECT1 +#define H5R_DATASET_REGION H5R_DATASET_REGION1 /* Function prototypes */ -H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *_ref); +#ifndef H5_NO_DEPRECATED_SYMBOLS + +H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref); H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref); #endif /* H5_NO_DEPRECATED_SYMBOLS */ +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 herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type); +H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, 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 ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, char *name, size_t size); + #ifdef __cplusplus } #endif #endif /* _H5Rpublic_H */ - diff --git a/src/H5S.c b/src/H5S.c index d9cfdeb..9eda3ae 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -1356,7 +1356,6 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, /* Check args */ HDassert(rank <= H5S_MAX_RANK); - HDassert(0 == rank || dims); /* shift out of the previous state to a "simple" dataspace. */ if(H5S__extent_release(&space->extent) < 0) @@ -1377,7 +1376,7 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, space->extent.size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank); /* Copy the dimensions & compute the number of elements in the extent */ - for(u = 0, nelem = 1; u < space->extent.rank; u++) { + for(u = 0, nelem = 1; dims && (u < space->extent.rank); u++) { space->extent.size[u] = dims[u]; nelem *= dims[u]; } /* end for */ @@ -1389,7 +1388,7 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, if(max != NULL) H5MM_memcpy(space->extent.max, max, sizeof(hsize_t) * rank); else - for(u = 0; u < space->extent.rank; u++) + for(u = 0; dims && (u < space->extent.rank); u++) space->extent.max[u] = dims[u]; } /* end else */ diff --git a/src/H5T.c b/src/H5T.c index cafcf4b..15d534e 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -226,18 +226,34 @@ #define H5T_INIT_TYPE_REF_COMMON { \ H5T_INIT_TYPE_ALLOC_COMMON(H5T_REFERENCE) \ H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE) \ + dt->shared->force_conv = TRUE; \ + dt->shared->u.atomic.u.r.f = NULL; \ + dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \ + dt->shared->u.atomic.u.r.cls = NULL; \ } #define H5T_INIT_TYPE_OBJREF_CORE { \ H5T_INIT_TYPE_REF_COMMON \ - dt->shared->force_conv = TRUE; \ - dt->shared->u.atomic.u.r.rtype = H5R_OBJECT; \ - dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; \ + dt->shared->u.atomic.u.r.rtype = H5R_OBJECT1; \ + dt->shared->u.atomic.u.r.opaque = FALSE; \ + dt->shared->u.atomic.u.r.version = 0; \ } #define H5T_INIT_TYPE_REGREF_CORE { \ H5T_INIT_TYPE_REF_COMMON \ - dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION; \ + dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION1; \ + dt->shared->u.atomic.u.r.opaque = FALSE; \ + dt->shared->u.atomic.u.r.version = 0; \ +} + +/* rtype value is only used as a placeholder to differentiate the type from + * other types, any opaque (i.e. "new") reference type could be used. + */ +#define H5T_INIT_TYPE_REF_CORE { \ + H5T_INIT_TYPE_REF_COMMON \ + dt->shared->u.atomic.u.r.rtype = H5R_OBJECT2; \ + dt->shared->u.atomic.u.r.opaque = TRUE; \ + dt->shared->u.atomic.u.r.version = H5R_ENCODE_VERSION; \ } /* Define the code templates for the "SIZE_TMPL" in the H5T_INIT_TYPE macro */ @@ -295,7 +311,7 @@ static htri_t H5T__compiler_conv(H5T_t *src, H5T_t *dst); static herr_t H5T__set_size(H5T_t *dt, size_t size); static herr_t H5T__close_cb(H5T_t *dt); static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv); -static hbool_t H5T__detect_reg_ref(const H5T_t *dt); +static hbool_t H5T__detect_vlen_ref(const H5T_t *dt); /*****************************/ @@ -354,6 +370,7 @@ hid_t H5T_STD_B64BE_g = FAIL; hid_t H5T_STD_B64LE_g = FAIL; hid_t H5T_STD_REF_OBJ_g = FAIL; hid_t H5T_STD_REF_DSETREG_g = FAIL; +hid_t H5T_STD_REF_g = FAIL; hid_t H5T_UNIX_D32BE_g = FAIL; hid_t H5T_UNIX_D32LE_g = FAIL; @@ -444,6 +461,7 @@ size_t H5T_POINTER_COMP_ALIGN_g = 0; size_t H5T_HVL_COMP_ALIGN_g = 0; size_t H5T_HOBJREF_COMP_ALIGN_g = 0; size_t H5T_HDSETREGREF_COMP_ALIGN_g = 0; +size_t H5T_REF_COMP_ALIGN_g = 0; /* * Alignment constraints for native types. These are initialized at run time @@ -736,7 +754,9 @@ H5T__init_package(void) H5T_t *enum_type=NULL; /* Datatype structure for enum objects */ H5T_t *vlen=NULL; /* Datatype structure for vlen objects */ H5T_t *array=NULL; /* Datatype structure for array objects */ - H5T_t *objref=NULL; /* Datatype structure for object reference objects */ + H5T_t *objref=NULL; /* Datatype structure for deprecated reference objects */ + H5T_t *regref=NULL; /* Datatype structure for deprecated region references */ + H5T_t *ref=NULL; /* Datatype structure for opaque references */ hsize_t dim[1]={1}; /* Dimension info for array datatype */ herr_t status; hbool_t copied_dtype = TRUE; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */ @@ -988,12 +1008,23 @@ H5T__init_package(void) *------------------------------------------------------------ */ - /* Object reference (i.e. object header address in file) */ - H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, SET, H5R_OBJ_REF_BUF_SIZE) + /* Deprecated object reference type */ + H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") objref = dt; /* Keep type for later */ - /* Dataset Region reference (i.e. selection inside a dataset) */ - H5T_INIT_TYPE(REGREF, H5T_STD_REF_DSETREG_g, ALLOC, -, SET, H5R_DSET_REG_REF_BUF_SIZE) + /* Deprecated region reference type */ + H5T_INIT_TYPE(REGREF, H5T_STD_REF_DSETREG_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + regref = dt; /* Keep type for later */ + + /* Opaque reference type */ + H5T_INIT_TYPE(REF, H5T_STD_REF_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + ref = dt; /* Keep type for later */ /* * Register conversion functions beginning with the most general and @@ -1029,6 +1060,10 @@ H5T__init_package(void) status |= H5T__register_int(H5T_PERS_SOFT, "vlen", vlen, vlen, H5T__conv_vlen); status |= H5T__register_int(H5T_PERS_SOFT, "array", array, array, H5T__conv_array); status |= H5T__register_int(H5T_PERS_SOFT, "objref", objref, objref, H5T__conv_order_opt); + status |= H5T__register_int(H5T_PERS_SOFT, "regref", regref, regref, H5T__conv_noop); + status |= H5T__register_int(H5T_PERS_SOFT, "ref", ref, ref, H5T__conv_ref); + status |= H5T__register_int(H5T_PERS_SOFT, "objref_ref", objref, ref, H5T__conv_ref); + status |= H5T__register_int(H5T_PERS_SOFT, "regref_ref", regref, ref, H5T__conv_ref); /* * Native conversions should be listed last since we can use hardware to @@ -1472,6 +1507,7 @@ H5T_top_term_package(void) H5T_STD_B64LE_g = FAIL; H5T_STD_REF_OBJ_g = FAIL; H5T_STD_REF_DSETREG_g = FAIL; + H5T_STD_REF_g = FAIL; H5T_UNIX_D32BE_g = FAIL; H5T_UNIX_D32LE_g = FAIL; @@ -2882,6 +2918,56 @@ done: /*------------------------------------------------------------------------- + * Function: H5Treclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. The dataset transfer property list is required to find the + * correct allocation/free methods for the VL data in the buffer. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Thursday, June 10, 1999 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Treclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) +{ + H5S_t *space; /* Dataspace for iteration */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); + + /* Check args */ + if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + + /* Call internal routine */ + ret_value = H5T_reclaim(type_id, space, buf); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Treclaim() */ + + +/*------------------------------------------------------------------------- * Function: H5Tencode * * Purpose: Given an datatype ID, converts the object description into @@ -4455,28 +4541,10 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) HGOTO_DONE(-1); if(dt1->shared->u.atomic.u.r.rtype > dt2->shared->u.atomic.u.r.rtype) HGOTO_DONE(1); - - switch(dt1->shared->u.atomic.u.r.rtype) { - case H5R_OBJECT: - if(dt1->shared->u.atomic.u.r.loc < dt2->shared->u.atomic.u.r.loc) - HGOTO_DONE(-1); - if(dt1->shared->u.atomic.u.r.loc > dt2->shared->u.atomic.u.r.loc) - HGOTO_DONE(1); - break; - - case H5R_DATASET_REGION: - /* Does this need more to distinguish it? -QAK 11/30/98 */ - /*void */ - break; - - case H5R_BADTYPE: - case H5R_MAXTYPE: - HDassert("invalid type" && 0); - break; - default: - HDassert("not implemented yet" && 0); - break; - } + if(dt1->shared->u.atomic.u.r.loc < dt2->shared->u.atomic.u.r.loc) + HGOTO_DONE(-1); + if(dt1->shared->u.atomic.u.r.loc > dt2->shared->u.atomic.u.r.loc) + HGOTO_DONE(1); break; case H5T_NO_CLASS: @@ -5329,7 +5397,7 @@ done: htri_t H5T_set_loc(dt,f,loc) H5T_t *dt; IN/OUT: Pointer to the datatype to mark H5F_t *f; IN: Pointer to the file the datatype is in - H5T_vlen_type_t loc IN: location of type + H5T_loc_t loc IN: location of type RETURNS One of two values on success: @@ -5454,17 +5522,9 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc) break; case H5T_REFERENCE: - /* Only need to change location of object references */ - if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) { - /* Mark this reference */ - if(loc != dt->shared->u.atomic.u.r.loc) { - /* Set the location */ - dt->shared->u.atomic.u.r.loc = loc; - - /* Indicate that the location changed */ - ret_value = TRUE; - } /* end if */ - } /* end if */ + /* Reference types go through type conversion */ + if((ret_value = H5T__ref_set_loc(dt, f, loc)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "Unable to set reference location"); break; case H5T_NO_CLASS: @@ -5491,7 +5551,7 @@ done: * * Purpose: Check if a datatype will change between disk and memory. * - * Notes: Currently, only variable-length and object references change + * Notes: Currently, only variable-length and references change * between disk & memory (see cases where things are changed in * the H5T_set_loc() code above). * @@ -5526,9 +5586,9 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_detect_reg_ref + * Function: H5T__detect_vlen_ref * - * Purpose: Check whether a datatype contains (or is) a region reference + * Purpose: Check whether a datatype contains (or is) a vlen reference * datatype. * * Return: TRUE (1) or FALSE (0) on success @@ -5540,7 +5600,7 @@ done: *------------------------------------------------------------------------- */ static hbool_t -H5T__detect_reg_ref(const H5T_t *dt) +H5T__detect_vlen_ref(const H5T_t *dt) { unsigned u; /* Local index variable */ hbool_t ret_value = FALSE; /* Return value */ @@ -5550,8 +5610,9 @@ H5T__detect_reg_ref(const H5T_t *dt) /* Sanity checks */ HDassert(dt); - /* Check if this datatype is a region reference */ - if(H5T_REFERENCE == dt->shared->type && H5R_DATASET_REGION == dt->shared->u.atomic.u.r.rtype) + /* Check if this datatype is a vlen reference */ + /* TODO currently H5T_STD_REF is always considered as a vlen type */ + if(H5T_REFERENCE == dt->shared->type && !dt->shared->u.atomic.u.r.opaque) HGOTO_DONE(TRUE); /* Check for types that might have the correct type as a component */ @@ -5560,14 +5621,14 @@ H5T__detect_reg_ref(const H5T_t *dt) /* Iterate over all the compound datatype's fields */ for(u = 0; u < dt->shared->u.compnd.nmembs; u++) /* Recurse on field's datatype */ - if(H5T__detect_reg_ref(dt->shared->u.compnd.memb[u].type)) + if(H5T__detect_vlen_ref(dt->shared->u.compnd.memb[u].type)) HGOTO_DONE(TRUE); break; case H5T_ARRAY: case H5T_VLEN: case H5T_ENUM: - HGOTO_DONE(H5T__detect_reg_ref(dt->shared->parent)); + HGOTO_DONE(H5T__detect_vlen_ref(dt->shared->parent)); break; case H5T_NO_CLASS: @@ -5585,7 +5646,7 @@ H5T__detect_reg_ref(const H5T_t *dt) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__detect_reg_ref() */ +} /* end H5T__detect_vlen_ref() */ /*------------------------------------------------------------------------- @@ -5621,7 +5682,7 @@ H5T_is_vl_storage(const H5T_t *dt) if(H5T_detect_class(dt, H5T_VLEN, FALSE)) ret_value = TRUE; else if(H5T_detect_class(dt, H5T_REFERENCE, FALSE)) - ret_value = H5T__detect_reg_ref(dt); + ret_value = H5T__detect_vlen_ref(dt); else ret_value = FALSE; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 723b9f2..84642f4 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1018,6 +1018,9 @@ H5FL_BLK_DEFINE_STATIC(vlen_seq); /* Declare a free list to manage pieces of array data */ H5FL_BLK_DEFINE_STATIC(array_seq); +/* Declare a free list to manage pieces of reference data */ +H5FL_BLK_DEFINE_STATIC(ref_seq); + /*------------------------------------------------------------------------- * Function: H5T__conv_noop @@ -3476,6 +3479,195 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__conv_array() */ +/*------------------------------------------------------------------------- + * Function: H5T__conv_ref + * + * Purpose: Converts between reference datatypes in memory and on disk. + * This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, + size_t buf_stride, size_t bkg_stride, void *buf, void *bkg) +{ + H5T_t *src = NULL; /* source datatype */ + H5T_t *dst = NULL; /* destination datatype */ + uint8_t *s = NULL; /* source buffer */ + uint8_t *d = NULL; /* destination buffer */ + uint8_t *b = NULL; /* background buffer */ + ssize_t s_stride, d_stride; /* src and dst strides */ + ssize_t b_stride; /* bkg stride */ + size_t safe; /* how many elements are safe to process in each pass */ + void *conv_buf = NULL; /* temporary conversion buffer */ + size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ + size_t elmtno; /* element number counter */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_PACKAGE + + switch(cdata->command) { + case H5T_CONV_INIT: + /* + * First, determine if this conversion function applies to the + * conversion path SRC_ID-->DST_ID. If not, return failure; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_REFERENCE != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype") + if(H5T_REFERENCE != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype") + /* Only allow for source reference that is not an opaque type, destination must be opaque */ + if(!dst->shared->u.atomic.u.r.opaque) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not an H5T_STD_REF datatype") + + /* Reference types don't need a background buffer */ + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + { + /* + * Conversion. + */ + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + HDassert(src->shared->u.atomic.u.r.cls); + + /* Initialize source & destination strides */ + if(buf_stride) { + HDassert(buf_stride >= src->shared->size); + HDassert(buf_stride >= dst->shared->size); + H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t); + s_stride = d_stride = (ssize_t)buf_stride; + } /* end if */ + else { + H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t); + H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t); + s_stride = (ssize_t)src->shared->size; + d_stride = (ssize_t)dst->shared->size; + } /* end else */ + if(bkg) { + if(bkg_stride) + b_stride = (ssize_t)bkg_stride; + else + b_stride = d_stride; + } /* end if */ + else + b_stride = 0; + + /* The outer loop of the type conversion macro, controlling which */ + /* direction the buffer is walked */ + while(nelmts > 0) { + /* Check if we need to go backwards through the buffer */ + if(d_stride > s_stride) { + /* Sanity check */ + HDassert(s_stride > 0); + HDassert(d_stride > 0); + HDassert(b_stride >= 0); + + /* Compute the number of "safe" destination elements at */ + /* the end of the buffer (Those which don't overlap with */ + /* any source elements at the beginning of the buffer) */ + safe = nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); + + /* If we're down to the last few elements, just wrap up */ + /* with a "real" reverse copy */ + if(safe < 2) { + s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; + b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; + s_stride = -s_stride; + d_stride = -d_stride; + b_stride = -b_stride; + + safe = nelmts; + } /* end if */ + else { + s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; + b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; + } /* end else */ + } /* end if */ + else { + /* Single forward pass over all data */ + s = d = (uint8_t *)buf; + b = (uint8_t *)bkg; + safe = nelmts; + } /* end else */ + + for(elmtno = 0; elmtno < safe; elmtno++) { + size_t buf_size; + hbool_t dst_copy = FALSE; + + /* Get size of references */ + if(0 == (buf_size = src->shared->u.atomic.u.r.cls->getsize( + src->shared->u.atomic.u.r.f, s, src->shared->size, + dst->shared->u.atomic.u.r.f, &dst_copy))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect size") + + /* Check if conversion buffer is large enough, resize if necessary. */ + if(conv_buf_size < buf_size) { + conv_buf_size = buf_size; + if(NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") + HDmemset(conv_buf, 0, conv_buf_size); + } /* end if */ + + if(dst_copy && (src->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) { + H5MM_memcpy(conv_buf, s, buf_size); + } else { + /* Read reference */ + if(src->shared->u.atomic.u.r.cls->read( + src->shared->u.atomic.u.r.f, s, src->shared->size, + dst->shared->u.atomic.u.r.f, conv_buf, buf_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data") + } + + if(dst_copy && (dst->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) { + H5MM_memcpy(d, conv_buf, buf_size); + } else { + /* Write reference to destination location */ + if(dst->shared->u.atomic.u.r.cls->write( + src->shared->u.atomic.u.r.f, conv_buf, buf_size, src->shared->u.atomic.u.r.rtype, + dst->shared->u.atomic.u.r.f, d, dst->shared->size, b) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data") + } + + /* Advance pointers */ + s += s_stride; + d += d_stride; + b += b_stride; + } /* end for */ + + /* Decrement number of elements left to convert */ + nelmts -= safe; + } /* end while */ + } /* end case */ + break; + + default: /* Some other command we don't know about yet.*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ + +done: + /* Release the conversion buffer (always allocated, except on errors) */ + if(conv_buf) + conv_buf = H5FL_BLK_FREE(ref_seq, conv_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__conv_ref() */ + /*------------------------------------------------------------------------- * Function: H5T__conv_i_i @@ -9307,3 +9499,84 @@ H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) FUNC_LEAVE_NOAPI(SUCCEED) } + +/*------------------------------------------------------------------------- + * Function: H5T_reclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_reclaim(hid_t type_id, H5S_t *space, void *buf) +{ + H5T_t *type; /* Datatype */ + H5S_sel_iter_op_t dset_op; /* Operator for iteration */ + H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ + herr_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(space); + HDassert(buf); + + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype") + + /* Get the allocation info */ + if(H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") + + /* Call H5S_select_iterate with args, etc. */ + dset_op.op_type = H5S_SEL_ITER_OP_LIB; + dset_op.u.lib_op = H5T_reclaim_cb; + + ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_reclaim() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_reclaim_cb + * + * Purpose: Iteration callback to reclaim conversion allocated memory for a + * buffer element. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned H5_ATTR_UNUSED ndim, + const hsize_t H5_ATTR_UNUSED *point, void *op_data) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(elem); + HDassert(dt); + + if(dt->shared->type == H5T_REFERENCE) { + if(H5T_ref_reclaim(elem, dt) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim ref elements") + } else { + HDassert(op_data); + + /* Allow vlen reclaim to recurse into that routine */ + if(H5T_vlen_reclaim(elem, dt, (H5T_vlen_alloc_info_t *)op_data) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_reclaim_cb() */ diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 6daa544..1d203c7 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -126,7 +126,6 @@ static H5T_t * H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { - H5T_t *dt; /* Datatype to make native */ H5T_t *super_type; /* Super type of VL, array and enum datatypes */ H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ H5T_t *new_type = NULL; /* New native datatype */ @@ -218,26 +217,36 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali case H5T_REFERENCE: { + H5T_t *dt; /* Datatype to make native */ size_t align; size_t ref_size; - int not_equal; if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy reference type") - /* Decide if the data type is object or dataset region reference. */ + /* Decide if the data type is object reference. */ if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") - not_equal = H5T_cmp(ret_value, dt, FALSE); /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { + if(0 == H5T_cmp(ret_value, dt, FALSE)) { align = H5T_HOBJREF_COMP_ALIGN_g; ref_size = sizeof(hobj_ref_t); } /* end if */ else { - align = H5T_HDSETREGREF_COMP_ALIGN_g; - ref_size = sizeof(hdset_reg_ref_t); + /* Decide if the data type is dataset region reference. */ + if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_DSETREG_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") + + if (0 == H5T_cmp(ret_value, dt, FALSE)) { + align = H5T_HDSETREGREF_COMP_ALIGN_g; + ref_size = sizeof(hdset_reg_ref_t); + } /* end if */ + else { + /* Only pointers to underlying opaque reference types */ + align = H5T_REF_COMP_ALIGN_g; + ref_size = sizeof(H5R_ref_t); + } /* end else */ } /* end else */ if(H5T__cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align) < 0) diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 281026c..9784abd 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -95,9 +95,14 @@ /* This version also encodes array types more efficiently */ #define H5O_DTYPE_VERSION_3 3 +/* This is the version that adds support for new reference types and prevents + * older versions of the library to attempt reading unknown types. + */ +#define H5O_DTYPE_VERSION_4 4 + /* The latest version of the format. Look through the 'encode helper' routine * and 'size' callback for places to change when updating this. */ -#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_3 +#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_4 /* Flags for visiting datatype */ @@ -175,37 +180,52 @@ struct H5T_path_t { H5T_cdata_t cdata; /*data for this function */ }; +/* Reference function pointers */ +typedef size_t (*H5T_ref_getsizefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +typedef herr_t (*H5T_ref_readfunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); +typedef herr_t (*H5T_ref_writefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5R_type_t src_type, H5F_t *dst_f, void *dst_buf, size_t dst_size, void *bg_buf); + +typedef struct H5T_ref_class_t { + H5T_ref_getsizefunc_t getsize; /* get reference size (bytes) */ + H5T_ref_readfunc_t read; /* read reference into buffer */ + H5T_ref_writefunc_t write; /* write reference from buffer */ +} H5T_ref_class_t; + typedef struct H5T_atomic_t { - H5T_order_t order; /*byte order */ - size_t prec; /*precision in bits */ - size_t offset; /*bit position of lsb of value */ - H5T_pad_t lsb_pad;/*type of lsb padding */ - H5T_pad_t msb_pad;/*type of msb padding */ + H5T_order_t order; /* byte order */ + size_t prec; /* precision in bits */ + size_t offset; /* bit position of lsb of value */ + H5T_pad_t lsb_pad; /* type of lsb padding */ + H5T_pad_t msb_pad; /* type of msb padding */ union { - struct { - H5T_sign_t sign; /*type of integer sign */ - } i; /*integer; integer types */ - - struct { - size_t sign; /*bit position of sign bit */ - size_t epos; /*position of lsb of exponent */ - size_t esize; /*size of exponent in bits */ - uint64_t ebias; /*exponent bias */ - size_t mpos; /*position of lsb of mantissa */ - size_t msize; /*size of mantissa */ - H5T_norm_t norm; /*normalization */ - H5T_pad_t pad; /*type of padding for internal bits */ - } f; /*floating-point types */ - - struct { - H5T_cset_t cset; /*character set */ - H5T_str_t pad; /*space or null padding of extra bytes */ - } s; /*string types */ - - struct { - H5R_type_t rtype; /*type of reference stored */ - H5T_loc_t loc; /* Location of data in buffer */ - } r; /*reference types */ + struct { + H5T_sign_t sign; /* type of integer sign */ + } i; /* integer; integer types */ + + struct { + size_t sign; /* bit position of sign bit */ + size_t epos; /* position of lsb of exponent */ + size_t esize; /* size of exponent in bits */ + uint64_t ebias; /* exponent bias */ + size_t mpos; /* position of lsb of mantissa */ + size_t msize; /* size of mantissa */ + H5T_norm_t norm; /* normalization */ + H5T_pad_t pad; /* type of padding for internal bits */ + } f; /* floating-point types */ + + struct { + H5T_cset_t cset; /* character set */ + H5T_str_t pad; /* space or null padding of extra bytes */ + } s; /* string types */ + + struct { + H5R_type_t rtype; /* type of reference stored */ + unsigned version; /* version of encoded reference */ + hbool_t opaque; /* opaque reference type */ + H5T_loc_t loc; /* location of data in buffer */ + H5F_t *f; /* file pointer (if data is on disk) */ + const H5T_ref_class_t *cls; /* Pointer to ref class callbacks */ + } r; /* reference types */ } u; } H5T_atomic_t; @@ -378,6 +398,7 @@ H5_DLLVAR size_t H5T_POINTER_COMP_ALIGN_g; H5_DLLVAR size_t H5T_HVL_COMP_ALIGN_g; H5_DLLVAR size_t H5T_HOBJREF_COMP_ALIGN_g; H5_DLLVAR size_t H5T_HDSETREGREF_COMP_ALIGN_g; +H5_DLLVAR size_t H5T_REF_COMP_ALIGN_g; /* * Alignment information for native types. A value of N indicates that the @@ -490,6 +511,9 @@ H5_DLL herr_t H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, H5_DLL herr_t H5T__conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); +H5_DLL herr_t H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, size_t buf_stride, + size_t bkg_stride, void *buf, void *bkg); H5_DLL herr_t H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *bkg); @@ -1156,6 +1180,9 @@ H5_DLL H5T_t *H5T__array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/ H5_DLL int H5T__get_array_ndims(const H5T_t *dt); H5_DLL int H5T__get_array_dims(const H5T_t *dt, hsize_t dims[]); +/* Reference functions */ +H5_DLL htri_t H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc); + /* Compound functions */ H5_DLL herr_t H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 3dcbb2c..13a0938 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -52,6 +52,9 @@ typedef struct H5T_t H5T_t; typedef struct H5T_stats_t H5T_stats_t; typedef struct H5T_path_t H5T_path_t; +/* Forward reference of H5S_t */ +struct H5S_t; + /* How to copy a datatype */ typedef enum H5T_copy_t { H5T_COPY_TRANSIENT, @@ -130,7 +133,10 @@ H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p); H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p); H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *_op_data); +H5_DLL herr_t H5T_reclaim(hid_t type_id, struct H5S_t *space, void *buf); +H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data); +H5_DLL herr_t H5T_ref_reclaim(void *elem, const H5T_t *dt); +H5_DLL herr_t H5T_vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info); H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt); H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index fc3e4ee..0ec0c73 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -262,8 +262,9 @@ H5_DLLVAR hid_t H5T_IEEE_F64LE_g; #define H5T_STD_B32LE (H5OPEN H5T_STD_B32LE_g) #define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g) #define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g) -#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) +#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) #define H5T_STD_REF_DSETREG (H5OPEN H5T_STD_REF_DSETREG_g) +#define H5T_STD_REF (H5OPEN H5T_STD_REF_g) H5_DLLVAR hid_t H5T_STD_I8BE_g; H5_DLLVAR hid_t H5T_STD_I8LE_g; H5_DLLVAR hid_t H5T_STD_I16BE_g; @@ -290,6 +291,7 @@ H5_DLLVAR hid_t H5T_STD_B64BE_g; H5_DLLVAR hid_t H5T_STD_B64LE_g; H5_DLLVAR hid_t H5T_STD_REF_OBJ_g; H5_DLLVAR hid_t H5T_STD_REF_DSETREG_g; +H5_DLLVAR hid_t H5T_STD_REF_g; /* * Types which are particular to Unix. @@ -591,6 +593,7 @@ H5_DLL H5T_conv_t H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata); H5_DLL htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id); H5_DLL herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background, hid_t plist_id); +H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Tref.c b/src/H5Tref.c new file mode 100644 index 0000000..6f7bf90 --- /dev/null +++ b/src/H5Tref.c @@ -0,0 +1,761 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Module Info: This module contains the functionality for reference + * datatypes in the H5T interface. + */ + +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ +#define H5R_FRIEND /*suppress error about including H5Rpkg */ + +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Fpkg.h" /* File */ +#include "H5Rpkg.h" /* References */ +#include "H5Tpkg.h" /* Datatypes */ + +/****************/ +/* Local Macros */ +/****************/ + +#define H5T_REF_MEM_SIZE (H5R_REF_BUF_SIZE) +#define H5T_REF_OBJ_MEM_SIZE (H5R_OBJ_REF_BUF_SIZE) +#define H5T_REF_DSETREG_MEM_SIZE (H5R_DSET_REG_REF_BUF_SIZE) + +#define H5T_REF_OBJ_DISK_SIZE(f) (H5F_SIZEOF_ADDR(f)) +#define H5T_REF_DSETREG_DISK_SIZE(f) (H5HG_HEAP_ID_SIZE(f)) + +/******************/ +/* Local Typedefs */ +/******************/ + +/* For region compatibility support */ +struct H5Tref_dsetreg { + haddr_t obj_addr; /* Object address */ + H5S_t *space; /* Dataspace */ +}; + +/********************/ +/* Local Prototypes */ +/********************/ + +static size_t H5T__ref_mem_getsize(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +static herr_t H5T__ref_mem_read(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); +static herr_t H5T__ref_mem_write(H5F_t *src_f, const void *src_buf, size_t src_size, H5R_type_t src_type, H5F_t *dst_f, void *dst_buf, size_t dst_size, void *bg_buf); + +static size_t H5T__ref_disk_getsize(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +static herr_t H5T__ref_disk_read(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); +static herr_t H5T__ref_disk_write(H5F_t *src_f, const void *src_buf, size_t src_size, H5R_type_t src_type, H5F_t *dst_f, void *dst_buf, size_t dst_size, void *bg_buf); + +/* For compatibility */ +static size_t H5T__ref_obj_disk_getsize(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +static herr_t H5T__ref_obj_disk_read(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); + +static size_t H5T__ref_dsetreg_disk_getsize(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +static herr_t H5T__ref_dsetreg_disk_read(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Class for reference in memory */ +static const H5T_ref_class_t H5T_ref_mem_g = { + H5T__ref_mem_getsize, /* 'getsize' */ + H5T__ref_mem_read, /* 'read' */ + H5T__ref_mem_write /* 'write' */ +}; + +static const H5T_ref_class_t H5T_ref_disk_g = { + H5T__ref_disk_getsize, /* 'getsize' */ + H5T__ref_disk_read, /* 'read' */ + H5T__ref_disk_write /* 'write' */ +}; + +static const H5T_ref_class_t H5T_ref_obj_disk_g = { + H5T__ref_obj_disk_getsize, /* 'getsize' */ + H5T__ref_obj_disk_read, /* 'read' */ + NULL /* 'write' */ +}; + +static const H5T_ref_class_t H5T_ref_dsetreg_disk_g = { + H5T__ref_dsetreg_disk_getsize, /* 'getsize' */ + H5T__ref_dsetreg_disk_read, /* 'read' */ + NULL /* 'write' */ +}; + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_set_loc + * + * Purpose: Sets the location of a reference datatype to be either on disk + * or in memory + * + * Return: + * One of two values on success: + * TRUE - If the location of any reference types changed + * FALSE - If the location of any reference types is the same + * Negative value is returned on failure + * + *------------------------------------------------------------------------- + */ +htri_t +H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) +{ + htri_t ret_value = FALSE; /* Indicate success, but no location change */ + + FUNC_ENTER_PACKAGE + + HDassert(dt); + /* f is NULL when loc == H5T_LOC_MEMORY */ + HDassert(loc >= H5T_LOC_BADLOC && loc < H5T_LOC_MAXLOC); + + /* Only change the location if it's different */ + if(loc == dt->shared->u.atomic.u.r.loc && f == dt->shared->u.atomic.u.r.f) + HGOTO_DONE(FALSE) + + switch(loc) { + case H5T_LOC_MEMORY: /* Memory based reference datatype */ + HDassert(NULL == f); + + /* Mark this type as being stored in memory */ + dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; + + /* Reset file ID (since this reference is in memory) */ + dt->shared->u.atomic.u.r.f = f; /* f is NULL */ + + if(dt->shared->u.atomic.u.r.opaque) { + /* Size in memory, disk size is different */ + dt->shared->size = H5T_REF_MEM_SIZE; + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Set up the function pointers to access the reference in memory */ + dt->shared->u.atomic.u.r.cls = &H5T_ref_mem_g; + + } else if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { + /* Size in memory, disk size is different */ + dt->shared->size = H5T_REF_OBJ_MEM_SIZE; + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Unused for now */ + dt->shared->u.atomic.u.r.cls = NULL; + + } else if(dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { + /* Size in memory, disk size is different */ + dt->shared->size = H5T_REF_DSETREG_MEM_SIZE; + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Unused for now */ + dt->shared->u.atomic.u.r.cls = NULL; + + } + break; + + case H5T_LOC_DISK: /* Disk based reference datatype */ + HDassert(f); + + /* Mark this type as being stored on disk */ + dt->shared->u.atomic.u.r.loc = H5T_LOC_DISK; + + /* Set file pointer (since this reference is on disk) */ + dt->shared->u.atomic.u.r.f = f; + + if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { + /* Size on disk, memory size is different */ + dt->shared->size = H5T_REF_OBJ_DISK_SIZE(f); + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Set up the function pointers to access the reference in memory */ + dt->shared->u.atomic.u.r.cls = &H5T_ref_obj_disk_g; + + } else if(dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { + /* Size on disk, memory size is different */ + dt->shared->size = H5T_REF_DSETREG_DISK_SIZE(f); + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Set up the function pointers to access the reference in memory */ + dt->shared->u.atomic.u.r.cls = &H5T_ref_dsetreg_disk_g; + + } else { + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + size_t ref_encode_size; + H5R_ref_priv_t fixed_ref; + + /* Get container info */ + if(H5F__get_cont_info(f, &cont_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get file container info") + + /* Retrieve min encode size (when references have no vlen part) */ + HDmemset(&fixed_ref, 0, sizeof(fixed_ref)); + fixed_ref.type = (int8_t)H5R_OBJECT2; + fixed_ref.token_size = (uint8_t)cont_info.token_size; + if(H5R__encode(NULL, &fixed_ref, NULL, &ref_encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get encode size") + + /* Size on disk, memory size is different */ + dt->shared->size = MAX(H5_SIZEOF_UINT32_T + + H5R_ENCODE_HEADER_SIZE + cont_info.blob_id_size, + ref_encode_size); + dt->shared->u.atomic.prec = 8 * dt->shared->size; + + /* Set up the function pointers to access the information on + * disk. Region and attribute references are stored identically + * on disk, so use the same functions. + */ + dt->shared->u.atomic.u.r.cls = &H5T_ref_disk_g; + + } + break; + + case H5T_LOC_BADLOC: + /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined + * location for reference type and leaves it for the caller to decide. + */ + dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; + + /* Reset file pointer */ + dt->shared->u.atomic.u.r.f = NULL; + + /* Reset the function pointers */ + dt->shared->u.atomic.u.r.cls = NULL; + + break; + + case H5T_LOC_MAXLOC: + /* MAXLOC is invalid */ + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid reference datatype location") + } /* end switch */ + + /* Indicate that the location changed */ + ret_value = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_set_loc() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_mem_getsize + * + * Purpose: Retrieves the size of a memory based reference. + * + * Return: Non-negative on success/zero on failure + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__ref_mem_getsize(H5F_t H5_ATTR_UNUSED *src_f, const void *src_buf, + size_t H5_ATTR_UNUSED src_size, H5F_t *dst_f, hbool_t *dst_copy) +{ + void *vol_obj = NULL; + const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; + unsigned flags = 0; + size_t ret_value = 0; + + FUNC_ENTER_STATIC + + HDassert(src_buf); + HDassert(src_size == H5T_REF_MEM_SIZE); + + /* Retrieve VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(src_ref->loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid location identifier") + + /* Retrieve file from VOL object */ + if(NULL == (src_f = (H5F_t *)H5VL_object_data(vol_obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object") + + /* Set external flag if referenced file is not destination file */ + flags |= (src_f->shared != dst_f->shared) ? H5R_IS_EXTERNAL : 0; + + /* Force re-calculating encoding size if any flags are set */ + if(flags || !src_ref->encode_size) { + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper encode */ + if(src_ref->type == (int8_t)H5R_DATASET_REGION2) + H5CX_set_libver_bounds(dst_f); + + /* Determine encoding size */ + if(H5R__encode(H5F_ACTUAL_NAME(src_f), src_ref, NULL, &ret_value, flags) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, 0, "unable to determine encoding size") + } else { + /* Can do a direct copy and skip blob decoding */ + if(src_ref->type == (int8_t)H5R_OBJECT2) + *dst_copy = TRUE; + + /* Get cached encoding size */ + ret_value = src_ref->encode_size; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_mem_getsize() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_mem_read + * + * Purpose: "Reads" the memory based reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_mem_read(H5F_t H5_ATTR_UNUSED *src_f, const void *src_buf, + size_t H5_ATTR_UNUSED src_size, H5F_t *dst_f, void *dst_buf, + size_t dst_size) +{ + void *vol_obj = NULL; + const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; + unsigned flags = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_buf); + HDassert(src_size == H5T_REF_MEM_SIZE); + HDassert(dst_f); + HDassert(dst_buf); + HDassert(dst_size); + + /* Retrieve VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(src_ref->loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid location identifier") + + /* Retrieve file from VOL object */ + if(NULL == (src_f = (H5F_t *)H5VL_object_data(vol_obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object") + + /* Set external flag if referenced file is not destination file */ + flags |= (src_f->shared != dst_f->shared) ? H5R_IS_EXTERNAL : 0; + + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper encode */ + if(src_ref->type == (int8_t)H5R_DATASET_REGION2) + H5CX_set_libver_bounds(dst_f); + + /* Encode reference */ + if(H5R__encode(H5F_ACTUAL_NAME(src_f), src_ref, dst_buf, &dst_size, flags) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot encode reference") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_mem_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_mem_write + * + * Purpose: "Writes" the memory reference from a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_mem_write(H5F_t *src_f, const void *src_buf, size_t src_size, + H5R_type_t src_type, H5F_t H5_ATTR_UNUSED *dst_f, void *dst_buf, + size_t dst_size, void H5_ATTR_UNUSED *bg_buf) +{ + hid_t file_id = H5I_INVALID_HID; + H5R_ref_priv_t *dst_ref = (H5R_ref_priv_t *)dst_buf; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_f); + HDassert(src_buf); + HDassert(src_size); + HDassert(dst_buf); + HDassert(dst_size == H5T_REF_MEM_SIZE); + + /* Make sure reference buffer is correctly initialized */ + HDmemset(dst_buf, 0, dst_size); + + switch(src_type) { + case H5R_OBJECT1: { + if(H5R__create_object((const H5VL_token_t *)src_buf, sizeof(haddr_t), dst_ref) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") + } + break; + case H5R_DATASET_REGION1: { + const struct H5Tref_dsetreg *src_reg = (const struct H5Tref_dsetreg *)src_buf; + + if(H5R__create_region((const H5VL_token_t *)&src_reg->obj_addr, sizeof(src_reg->obj_addr), src_reg->space, dst_ref) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference") + /* create_region creates its internal copy of the space */ + if(H5S_close(src_reg->space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace") + } + break; + case H5R_DATASET_REGION2: + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper decode */ + H5CX_set_libver_bounds(src_f); + H5_ATTR_FALLTHROUGH + case H5R_OBJECT2: + case H5R_ATTR: + /* Decode reference */ + if(H5R__decode((const unsigned char *)src_buf, &src_size, dst_ref) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Cannot decode reference") + break; + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } + + /* If no filename set, this is not an external reference */ + if(NULL == H5R_REF_FILENAME(dst_ref)) { + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(src_f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Attach loc ID to reference and hold reference to it */ + if(H5R__set_loc_id(dst_ref, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + } + +done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_mem_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_disk_getsize + * + * Purpose: Retrieves the length of a disk based reference. + * + * Return: Non-negative value (cannot fail) + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__ref_disk_getsize(H5F_t H5_ATTR_UNUSED *src_f, const void *src_buf, + size_t src_size, H5F_t H5_ATTR_UNUSED *dst_f, hbool_t *dst_copy) +{ + const uint8_t *p = (const uint8_t *)src_buf; + unsigned flags; + H5R_type_t ref_type; + size_t ret_value = 0; + + FUNC_ENTER_STATIC + + HDassert(src_buf); + + /* Set reference type */ + ref_type = (H5R_type_t)*p++; + if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid reference type") + + /* Set flags */ + flags = (unsigned)*p++; + + if(!(flags & H5R_IS_EXTERNAL) && (ref_type == H5R_OBJECT2)) { + /* Can do a direct copy and skip blob decoding */ + *dst_copy = TRUE; + + ret_value = src_size; + } else { + /* Retrieve encoded data size */ + UINT32DECODE(p, ret_value); + + /* Add size of the header */ + ret_value += H5R_ENCODE_HEADER_SIZE; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_disk_getsize() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_disk_read + * + * Purpose: Reads the disk based reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_disk_read(H5F_t *src_f, const void *src_buf, size_t src_size, + H5F_t H5_ATTR_UNUSED *dst_f, void *dst_buf, size_t dst_size) +{ + H5VL_object_t *vol_obj = NULL; /* Object info */ + hid_t file_id = H5I_INVALID_HID; + const uint8_t *p = (const uint8_t *)src_buf; + uint8_t *q = (uint8_t *)dst_buf; + size_t buf_size_left = src_size; + size_t expected_size = dst_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_f); + HDassert(src_buf); + HDassert(dst_buf); + HDassert(dst_size); + + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(src_f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Copy header manually */ + HDmemcpy(q, p, H5R_ENCODE_HEADER_SIZE); + p += H5R_ENCODE_HEADER_SIZE; + q += H5R_ENCODE_HEADER_SIZE; + expected_size -= H5R_ENCODE_HEADER_SIZE; + + /* Skip the length of the sequence */ + p += H5_SIZEOF_UINT32_T; + HDassert(buf_size_left > H5_SIZEOF_UINT32_T); + buf_size_left -= H5_SIZEOF_UINT32_T; + + /* Retrieve blob */ + if(H5VL_blob_get(vol_obj, p, q, &dst_size, NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob") + if(dst_size != expected_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Expected data size does not match") + +done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_disk_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_disk_write + * + * Purpose: Writes the disk based reference from a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_disk_write(H5F_t H5_ATTR_UNUSED *src_f, const void *src_buf, + size_t src_size, H5R_type_t H5_ATTR_UNUSED src_type, H5F_t *dst_f, + void *dst_buf, size_t dst_size, void *bg_buf) +{ + H5VL_object_t *vol_obj = NULL; /* Object info */ + hid_t file_id = H5I_INVALID_HID; + const uint8_t *p = (const uint8_t *)src_buf; + uint8_t *q = (uint8_t *)dst_buf; + size_t buf_size_left = dst_size; + uint8_t *p_bg = (uint8_t *)bg_buf; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_buf); + HDassert(src_size); + HDassert(dst_f); + HDassert(dst_buf); + + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(dst_f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* TODO Should get rid of bg stuff */ + if(p_bg) { + size_t p_buf_size_left = dst_size; + + /* Skip the length of the reference */ + p_bg += H5_SIZEOF_UINT32_T; + HDassert(p_buf_size_left > H5_SIZEOF_UINT32_T); + p_buf_size_left -= H5_SIZEOF_UINT32_T; + + /* Remove blob for old data */ + if(H5VL_blob_specific(vol_obj, (void *)p_bg, H5VL_BLOB_DELETE) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") + } /* end if */ + + /* Copy header manually so that it does not get encoded into the blob */ + HDmemcpy(q, p, H5R_ENCODE_HEADER_SIZE); + p += H5R_ENCODE_HEADER_SIZE; + q += H5R_ENCODE_HEADER_SIZE; + src_size -= H5R_ENCODE_HEADER_SIZE; + buf_size_left -= H5_SIZEOF_UINT32_T; + + /* Set the size */ + UINT32ENCODE(q, src_size); + HDassert(buf_size_left > H5_SIZEOF_UINT32_T); + buf_size_left -= H5_SIZEOF_UINT32_T; + + /* Store blob */ + if(H5VL_blob_put(vol_obj, p, src_size, q, NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob") + +done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_disk_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_obj_disk_getsize + * + * Purpose: Retrieves the length of a disk based reference. + * + * Return: Non-negative value (cannot fail) + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__ref_obj_disk_getsize(H5F_t H5_ATTR_UNUSED *src_f, + const void H5_ATTR_UNUSED *src_buf, size_t H5_ATTR_UNUSED src_size, + H5F_t H5_ATTR_UNUSED *dst_f, hbool_t H5_ATTR_UNUSED *dst_copy) +{ + size_t ret_value = sizeof(haddr_t); + + FUNC_ENTER_STATIC_NOERR + + HDassert(src_buf); + HDassert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_obj_disk_getsize() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_obj_disk_read + * + * Purpose: Reads the disk based reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_obj_disk_read(H5F_t H5_ATTR_UNUSED *src_f, const void *src_buf, + size_t src_size, H5F_t H5_ATTR_UNUSED *dst_f, void *dst_buf, + size_t H5_ATTR_UNUSED dst_size) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_f); + HDassert(src_buf); + HDassert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); + HDassert(dst_buf); + HDassert(dst_size == sizeof(haddr_t)); + + /* Get object address */ + if(H5R__decode_addr_obj_compat((const unsigned char *)src_buf, &src_size, (haddr_t *)dst_buf) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5I_INVALID_HID, "unable to get object address") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_obj_disk_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_dsetreg_disk_getsize + * + * Purpose: Retrieves the length of a disk based reference. + * + * Return: Non-negative value (cannot fail) + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__ref_dsetreg_disk_getsize(H5F_t H5_ATTR_UNUSED *f, + const void H5_ATTR_UNUSED *buf, size_t H5_ATTR_UNUSED buf_size, + H5F_t H5_ATTR_UNUSED *dst_f, hbool_t H5_ATTR_UNUSED *dst_copy) +{ + size_t ret_value = sizeof(struct H5Tref_dsetreg); + + FUNC_ENTER_STATIC_NOERR + + HDassert(buf); + HDassert(buf_size == H5T_REF_DSETREG_DISK_SIZE(f)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_dsetreg_disk_getsize() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__ref_dsetreg_disk_read + * + * Purpose: Reads the disk based reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__ref_dsetreg_disk_read(H5F_t *src_f, const void *src_buf, size_t src_size, + H5F_t H5_ATTR_UNUSED *dst_f, void *dst_buf, size_t H5_ATTR_UNUSED dst_size) +{ + struct H5Tref_dsetreg *dst_reg = (struct H5Tref_dsetreg *)dst_buf; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(src_f); + HDassert(src_buf); + HDassert(src_size == H5T_REF_DSETREG_DISK_SIZE(src_f)); + HDassert(dst_buf); + HDassert(dst_size == sizeof(struct H5Tref_dsetreg)); + + /* Retrieve object address and space */ + if(H5R__decode_addr_region_compat(src_f, (const unsigned char *)src_buf, &src_size, &dst_reg->obj_addr, &dst_reg->space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__ref_dsetreg_disk_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_ref_reclaim + * + * Purpose: Internal routine to free reference datatypes + * + * Return: Non-negative on success / Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_ref_reclaim(void *elem, const H5T_t *dt) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(elem); + HDassert(dt && (dt->shared->type == H5T_REFERENCE)); + + if(dt->shared->u.atomic.u.r.opaque + && (H5R__destroy((H5R_ref_priv_t *)elem) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "cannot free reference") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_ref_reclaim() */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 9f82340..0253b01 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -26,15 +26,13 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Tpkg.h" /* Datatypes */ - +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Tpkg.h" /* Datatypes */ /****************/ /* Local Macros */ @@ -54,7 +52,6 @@ /********************/ /* Local Prototypes */ /********************/ -static herr_t H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info); /* Memory-based VL sequence callbacks */ static herr_t H5T__vlen_mem_seq_getlen(H5F_t *f, const void *_vl, size_t *len); @@ -100,7 +97,7 @@ static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl); /* Local Variables */ /*******************/ -/* Class for VL seqences in memory */ +/* Class for VL sequences in memory */ static const H5T_vlen_class_t H5T_vlen_mem_seq_g = { H5T__vlen_mem_seq_getlen, /* 'getlen' */ H5T__vlen_mem_seq_getptr, /* 'getptr' */ @@ -122,7 +119,7 @@ static const H5T_vlen_class_t H5T_vlen_mem_str_g = { NULL /* 'delete' */ }; -/* Class for both VL strings and seqences in file */ +/* Class for both VL strings and sequences in file */ static const H5T_vlen_class_t H5T_vlen_disk_g = { H5T__vlen_disk_getlen, /* 'getlen' */ NULL, /* 'getptr' */ @@ -1085,38 +1082,35 @@ done: } /* end H5T__vlen_disk_delete() */ -/*-------------------------------------------------------------------------- - NAME - H5T__vlen_reclaim_recurse - PURPOSE - Internal recursive routine to free VL datatypes - USAGE - herr_t H5T__vlen_reclaim_recurse(elem,dt) - void *elem; IN/OUT: Pointer to the dataset element - H5T_t *dt; IN: Datatype of dataset element - - RETURNS - SUCCEED/FAIL - DESCRIPTION - Frees any dynamic memory used by VL datatypes in the current dataset - element. Performs a recursive depth-first traversal of all compound - datatypes to free all VL datatype information allocated by any field. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info) +/*------------------------------------------------------------------------- + * Function: H5T_vlen_reclaim + * + * Purpose: Internal recursive routine to free VL datatypes + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info) { unsigned u; /* Local index variable */ + H5MM_free_t free_func; /* Free function */ + void *free_info; /* Free info */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(elem); HDassert(dt); + HDassert(alloc_info); + + free_func = alloc_info->free_func; + free_info = alloc_info->free_info; /* Check the datatype of this element */ switch(dt->shared->type) { @@ -1128,7 +1122,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo /* Calculate the offset member and recurse on it */ for(u = 0; u < dt->shared->u.array.nelem; u++) { off = ((uint8_t *)elem) + u * (dt->shared->parent->shared->size); - if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) + if(H5T_reclaim_cb(off, dt->shared->parent, 0, NULL, alloc_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free array element") } /* end for */ } /* end if */ @@ -1143,7 +1137,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo /* Calculate the offset member and recurse on it */ off = ((uint8_t *)elem) + dt->shared->u.compnd.memb[u].offset; - if(H5T__vlen_reclaim_recurse(off, dt->shared->u.compnd.memb[u].type, free_func, free_info) < 0) + if(H5T_reclaim_cb(off, dt->shared->u.compnd.memb[u].type, 0, NULL, alloc_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free compound field") } /* end if */ } /* end for */ @@ -1163,7 +1157,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo /* Calculate the offset of each array element and recurse on it */ while(vl->len > 0) { off = ((uint8_t *)vl->p) + (vl->len - 1) * dt->shared->parent->shared->size; - if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) + if(H5T_reclaim_cb(off, dt->shared->parent, 0, NULL, alloc_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free VL element") vl->len--; } /* end while */ @@ -1193,11 +1187,11 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo case H5T_STRING: case H5T_BITFIELD: case H5T_OPAQUE: - case H5T_REFERENCE: case H5T_ENUM: break; /* Should never have these values */ + case H5T_REFERENCE: case H5T_NO_CLASS: case H5T_NCLASSES: default: @@ -1208,58 +1202,6 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__vlen_reclaim_recurse() */ - - -/*-------------------------------------------------------------------------- - NAME - H5T_vlen_reclaim - PURPOSE - Default method to reclaim any VL data for a buffer element - USAGE - herr_t H5T_vlen_reclaim(elem,type_id,ndim,point,op_data) - void *elem; IN/OUT: Pointer to the dataset element - hid_t type_id; IN: Datatype of dataset element - unsigned ndim; IN: Number of dimensions in dataspace - hsize_t *point; IN: Coordinate location of element in dataspace - void *op_data IN: Operator data - - RETURNS - SUCCEED/FAIL - DESCRIPTION - Frees any dynamic memory used by VL datatypes in the current dataset - element. Recursively descends compound datatypes to free all VL datatype - information allocated by any field. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned H5_ATTR_UNUSED ndim, - const hsize_t H5_ATTR_UNUSED *point, void *op_data) -{ - H5T_vlen_alloc_info_t *vl_alloc_info = (H5T_vlen_alloc_info_t *)op_data; /* VL allocation info from iterator */ - H5T_t *dt; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(elem); - HDassert(vl_alloc_info); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - - /* Check args */ - if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - - /* Pull the free function and free info pointer out of the op_data and call the recurse datatype free function */ - if(H5T__vlen_reclaim_recurse(elem, dt, vl_alloc_info->free_func, vl_alloc_info->free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") - -done: - FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_reclaim() */ @@ -1295,10 +1237,9 @@ H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") /* Recurse on buffer to free dynamic fields */ - if(H5T__vlen_reclaim_recurse(elem, dt, vl_alloc_info.free_func, vl_alloc_info.free_info) < 0) + if(H5T_vlen_reclaim(elem, dt, &vl_alloc_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") done: FUNC_LEAVE_NOAPI(ret_value) } /* H5T_vlen_reclaim_elmt() */ - diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 9afb718..3c3712a 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -409,7 +409,6 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, break; } - default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ diff --git a/src/H5detect.c b/src/H5detect.c index 32b7d34..d01ee9f 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -107,8 +107,8 @@ typedef struct detected_t { unsigned int comp_align; /* alignment for structure */ } detected_t; -/* This structure holds structure alignment for pointers, hvl_t, hobj_ref_t, - * hdset_reg_ref_t */ +/* This structure holds structure alignment for pointers, vlen and reference + * types. */ typedef struct malign_t { const char *name; unsigned int comp_align; /* alignment for structure */ @@ -383,9 +383,8 @@ precision (detected_t *d) /*------------------------------------------------------------------------- * Function: DETECT_M * - * Purpose: This macro takes only miscellaneous structures or pointer - * (pointer, hvl_t, hobj_ref_t, hdset_reg_ref_t). It - * constructs the names and decides the alignment in structure. + * Purpose: This macro takes only miscellaneous structures or pointer. + * It constructs the names and decides the alignment in structure. * * Return: void *------------------------------------------------------------------------- @@ -761,8 +760,8 @@ H5T__init_native(void)\n\ H5T_native_order_g = H5T_ORDER_%s;\n", "BE"); } - /* Structure alignment for pointers, hvl_t, hobj_ref_t, hdset_reg_ref_t */ - fprintf(rawoutstream, "\n /* Structure alignment for pointers, hvl_t, hobj_ref_t, hdset_reg_ref_t */\n"); + /* Structure alignment for pointers, vlen and reference types */ + fprintf(rawoutstream, "\n /* Structure alignment for pointers, vlen and reference types */\n"); for(j=0; jrc < 2) + return; + + /* Extend the table */ + if(idtab_g.nobjs >= idtab_g.nalloc) { + idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc); + idtab_g.obj = (haddr_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); + } /* end if */ + + /* Insert the entry */ + n = idtab_g.nobjs++; + idtab_g.obj[n] = oi->addr; +} /* end addr_insert() */ + + +/*------------------------------------------------------------------------- + * Function: addr_lookup + * + * Purpose: Check if address has already been encountered + * + * Return: Success: TRUE/FALSE + * + * Failure: (can't fail) + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static H5_ATTR_PURE hbool_t +addr_lookup(H5O_info_t *oi) +{ + size_t n; + + if(oi->rc < 2) return FALSE; /*only one link possible*/ + + for(n = 0; n < idtab_g.nobjs; n++) + if(H5F_addr_eq(idtab_g.obj[n], oi->addr)) + return TRUE; + + return FALSE; +} /* end addr_lookup() */ + + +/*------------------------------------------------------------------------- + * Function: addr_reset + * + * Purpose: Reset the address tracking data structures + * + * Return: void + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static void +addr_reset(void) +{ + if(idtab_g.obj) + HDfree(idtab_g.obj); + idtab_g.obj = NULL; + idtab_g.nalloc = idtab_g.nobjs = 0; +} /* end addr_reset() */ + + +/*------------------------------------------------------------------------- + * Function: attach_ref_attr + * + * Purpose: Create an attribute with object references + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +attach_ref_attr(hid_t file_id, hid_t loc_id) +{ + char dsetname1[] = "dataset1_pointed_by_ref_attr"; + char dsetname2[] = "dataset2_pointed_by_ref_attr"; + hid_t did1 = (-1), did2 = (-1), aid = (-1), sid = (-1), sid_ref = (-1); + hsize_t dims[2] = {2,9}; + hsize_t dims_ref[1] = {2}; + H5R_ref_t ref[2]; + int data1[2][9] = {{1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,18}}; + int data2[2][9] = {{2,2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2,18}}; + + /* creates two simple datasets */ + if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR + if((sid_ref = H5Screate_simple(1, dims_ref, NULL)) < 0) TEST_ERROR + if((did1 = H5Dcreate2(file_id, dsetname1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data1) < 0) TEST_ERROR + if((did2 = H5Dcreate2(file_id, dsetname2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data2) < 0) TEST_ERROR + + /* create an attribute with two object references */ + if(H5Rcreate_object(file_id, dsetname1, &ref[0]) < 0) TEST_ERROR + if(H5Rcreate_object(file_id, dsetname2, &ref[1]) < 0) TEST_ERROR + if((aid = H5Acreate2(loc_id, "obj_ref_attr", H5T_STD_REF, sid_ref, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + if(H5Sclose(sid) < 0) TEST_ERROR + if(H5Sclose(sid_ref) < 0) TEST_ERROR + if(H5Dclose(did1) < 0) TEST_ERROR + if(H5Dclose(did2) < 0) TEST_ERROR + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + H5Sclose(sid_ref); + H5Dclose(did1); + H5Dclose(did2); + H5Aclose(aid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + +/*------------------------------------------------------------------------- + * Function: attach_reg_ref_attr + * + * Purpose: Create an attribute with object references + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Monday, March 5, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +attach_reg_ref_attr(hid_t file_id, hid_t loc_id) +{ + const char dsetnamev[] = "dataset_pointed_by_reg_ref_attr"; + hid_t aid = (-1); + hid_t space_id = (-1); /* dataspace identifiers */ + hid_t spacer_id = (-1); /* dataspace identifiers */ + hid_t dsetv_id = (-1); /*dataset identifiers*/ + hsize_t dims[2] = {2,9}; + hsize_t dimsr[1] = {2}; + int rank = 2; + int rankr =1; + H5R_ref_t ref[2]; + int data[2][9] = {{1,1,2,3,3,4,5,5,999},{1,2,2,3,4,4,5,6,999}}; + hsize_t start[2] = {0, 3}; + hsize_t count[2] = {2, 3}; + hsize_t coord[3][2] = {{0, 0}, {1, 6}, {0, 8}}; + size_t num_points = 3; + + /* create a 2D dataset */ + if((space_id = H5Screate_simple(rank, dims, NULL)) < 0) TEST_ERROR + if((spacer_id = H5Screate_simple(rankr, dimsr, NULL)) < 0) TEST_ERROR + if((dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data) < 0) TEST_ERROR + + /* create reg_ref of block selection */ + if(H5Sselect_hyperslab(space_id,H5S_SELECT_SET,start,NULL,count,NULL) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[0]) < 0) TEST_ERROR + + /* create reg_ref of point selection */ + if(H5Sselect_none(space_id) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[1]) < 0) TEST_ERROR + + /* create reg_ref attribute */ + if((aid = H5Acreate2(loc_id, "reg_ref_attr", H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + /* attach the reg_ref attribute to the dataset itself */ + if(H5Aclose(aid) < 0) TEST_ERROR + if((aid = H5Acreate2(dsetv_id, "reg_ref_attr", H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + if(H5Sclose(spacer_id) < 0) TEST_ERROR + if(H5Sclose(space_id) < 0) TEST_ERROR + if(H5Dclose(dsetv_id) < 0) TEST_ERROR + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(spacer_id); + H5Sclose(space_id); + H5Dclose(dsetv_id); + H5Aclose(aid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + + +/*------------------------------------------------------------------------- + * Function: create_reg_ref_dataset + * + * Purpose: Create a dataset with region references + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Friday, August 4, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +create_reg_ref_dataset(hid_t file_id, hid_t loc_id) +{ + const char dsetnamev[] = "dataset_pointed_by_ref_dset"; + const char dsetnamer[] = "dataset_with_reg_ref"; + const char dsetnamer1[] = "compact_dataset_with_reg_ref"; + const char dsetnamer2[] = "compressed_dataset_with_reg_ref"; + hid_t space_id = (-1); /* dataspace identifiers */ + hid_t spacer_id = (-1); + hid_t dsetv_id = (-1); /*dataset identifiers*/ + hid_t dsetr_id = (-1); + hsize_t dims[2] = {2,9}; + hsize_t dimsr[1] = {2}; + int rank = 2; + int rankr =1; + hsize_t chunk_size=1; + H5R_ref_t ref[2]; + int data[2][9] = {{1,1,2,3,3,4,5,5,6},{1,2,2,3,4,4,5,6,6}}; + hsize_t start[2]; + hsize_t count[2]; + hsize_t coord[3][2] = {{0, 0}, {1, 6}, {0, 8}}; + size_t num_points = 3; + hid_t pid = (-1); + + if((space_id = H5Screate_simple(rank, dims, NULL)) < 0) TEST_ERROR + if((spacer_id = H5Screate_simple(rankr, dimsr, NULL)) < 0) TEST_ERROR + if((dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data) < 0) TEST_ERROR + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer, H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + start[0] = 0; + start[1] = 3; + count[0] = 2; + count[1] = 3; + if(H5Sselect_hyperslab(space_id,H5S_SELECT_SET,start,NULL,count,NULL) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[0]) < 0) TEST_ERROR + if(H5Sselect_none(space_id) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[1]) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + /* create and set compact plist */ + if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR + if(H5Pset_layout(pid, H5D_COMPACT) < 0) TEST_ERROR + + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer1, H5T_STD_REF, spacer_id, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Pclose(pid) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + /* create and set comp & chunk plist */ + if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR + if(H5Pset_chunk(pid, 1, &chunk_size) < 0) TEST_ERROR + if(H5Pset_deflate(pid, 9) < 0) TEST_ERROR + + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer2, H5T_STD_REF, spacer_id, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Pclose(pid) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + if(H5Sclose(space_id) < 0) TEST_ERROR + if(H5Sclose(spacer_id) < 0) TEST_ERROR + if(H5Dclose(dsetv_id) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + return 0; + + +error: + H5E_BEGIN_TRY { + H5Sclose(space_id); + H5Sclose(spacer_id); + H5Dclose(dsetr_id); + H5Dclose(dsetv_id); + H5Pclose(pid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + +/*------------------------------------------------------------------------- + * Function: test_copy_attach_attributes + * + * Purpose: Attach NUM_ATTRIBUTES attributes to the object to be copied + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Friday, September 30, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_attach_attributes(hid_t loc_id, hid_t type_id) +{ + hid_t aid = -1, sid = -1; + char attr_name[ATTR_NAME_LEN]; + int attr_data[2]; + hsize_t dim1 = 2; + hid_t acpl = -1; + unsigned u; + int ret_value = -1; + + if((sid = H5Screate_simple(1, &dim1, NULL)) < 0 ) + goto done; + + /* Create attribute creation plist */ + if((acpl = H5Pcreate(H5P_ATTRIBUTE_CREATE)) < 0) + goto done; + + for(u = 0; u < num_attributes_g; u++) { + HDsprintf(attr_name, "%u attr", u); + + /* Set attribute data */ + attr_data[0] = (int)(100 * u); + attr_data[1] = (int)(200 * u); + + /* Set attribute character set (alternate) */ + if(u % 2) { + if(H5Pset_char_encoding(acpl, H5T_CSET_ASCII) < 0) + goto done; + } /* end if */ + else + if(H5Pset_char_encoding(acpl, H5T_CSET_UTF8) < 0) + goto done; + + if((aid = H5Acreate2(loc_id, attr_name, type_id, sid, acpl, H5P_DEFAULT)) < 0) + goto done; + + if(H5Awrite(aid, H5T_NATIVE_INT, attr_data) < 0) + goto done; + + if(aid > 0) + H5Aclose(aid); + + aid = -1; + } + + ret_value = 0; + +done: + if(sid > 0) + H5Sclose(sid); + if(aid > 0) + H5Aclose(aid); + if(acpl > 0) + H5Pclose(acpl); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: compare_attribute + * + * Purpose: Compare two attributes to check that they are equal + * + * Return: TRUE if attributes are equal/FALSE if they are different + * + * Programmer: Peter Cao + * Saturday, December 17, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_attribute(hid_t aid, hid_t aid2, hid_t pid, const void *wbuf, hid_t obj_owner) +{ + hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + size_t elmt_size; /* Size of datatype */ + htri_t is_committed; /* If the datatype is committed */ + htri_t is_committed2; /* If the datatype is committed */ + H5A_info_t ainfo; /* Attribute info */ + H5A_info_t ainfo2; /* Attribute info */ + hssize_t nelmts; /* # of elements in dataspace */ + void *rbuf = NULL; /* Buffer for reading raw data */ + void *rbuf2 = NULL; /* Buffer for reading raw data */ + + /* Check the character sets are equal */ + if(H5Aget_info(aid, &ainfo) < 0) TEST_ERROR + if(H5Aget_info(aid2, &ainfo2) < 0) TEST_ERROR + if(ainfo.cset != ainfo2.cset) TEST_ERROR + + /* Check the creation orders are equal (if appropriate) */ + if(ainfo.corder_valid != ainfo2.corder_valid) TEST_ERROR + if(ainfo.corder_valid) + if(ainfo.corder != ainfo2.corder) TEST_ERROR + + /* Check the datatypes are equal */ + + /* Open the datatype for the source attribute */ + if((tid = H5Aget_type(aid)) < 0) TEST_ERROR + + /* Open the datatype for the destination attribute */ + if((tid2 = H5Aget_type(aid2)) < 0) TEST_ERROR + + /* Check that both datatypes are committed/not committed */ + if((is_committed = H5Tcommitted(tid)) < 0) TEST_ERROR + if((is_committed2 = H5Tcommitted(tid2)) < 0) TEST_ERROR + if(is_committed != is_committed2) TEST_ERROR + + /* Compare the datatypes */ + if(H5Tequal(tid, tid2) != TRUE) TEST_ERROR + + /* Determine the size of datatype (for later) */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + /* Check the dataspaces are equal */ + + /* Open the dataspace for the source attribute */ + if((sid = H5Aget_space(aid)) < 0) TEST_ERROR + + /* Open the dataspace for the destination attribute */ + if((sid2 = H5Aget_space(aid2)) < 0) TEST_ERROR + + /* Compare the dataspaces */ + if(H5Sextent_equal(sid, sid2) != TRUE) TEST_ERROR + + /* Determine the number of elements in dataspace (for later) */ + if((nelmts = H5Sget_simple_extent_npoints(sid2)) < 0) TEST_ERROR + + /* Check the raw data is equal */ + + /* Allocate & initialize space for the raw data buffers */ + if((rbuf = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + if((rbuf2 = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + + /* Read data from the source attribute */ + if(H5Aread(aid, tid, rbuf) < 0) TEST_ERROR + + /* Read data from the destination attribute */ + if(H5Aread(aid2, tid2, rbuf2) < 0) TEST_ERROR + + /* Check raw data read in against data written out */ + if(wbuf) { + if(!compare_data(aid, (hid_t)0, pid, tid, (size_t)nelmts, wbuf, rbuf, obj_owner)) TEST_ERROR + if(!compare_data(aid2, (hid_t)0, pid, tid2, (size_t)nelmts, wbuf, rbuf2, obj_owner)) TEST_ERROR + } /* end if */ + /* Don't have written data, just compare data between the two attributes */ + else + if(!compare_data(aid, aid2, pid, tid, (size_t)nelmts, rbuf, rbuf2, obj_owner)) TEST_ERROR + + /* Reclaim vlen data, if necessary */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE || H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE || H5Tdetect_class(tid2, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Release raw data buffers */ + HDfree(rbuf); + rbuf = NULL; + HDfree(rbuf2); + rbuf2 = NULL; + + /* close the source dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + + /* close the destination dataspace */ + if(H5Sclose(sid2) < 0) TEST_ERROR + + /* close the source datatype */ + if(H5Tclose(tid) < 0) TEST_ERROR + + /* close the destination datatype */ + if(H5Tclose(tid2) < 0) TEST_ERROR + + return TRUE; + +error: + if(rbuf) + HDfree(rbuf); + if(rbuf2) + HDfree(rbuf2); + H5E_BEGIN_TRY { + H5Sclose(sid2); + H5Sclose(sid); + H5Tclose(tid2); + H5Tclose(tid); + } H5E_END_TRY; + return FALSE; +} /* end compare_attribute() */ + + +/*------------------------------------------------------------------------- + * Function: compare_std_attributes + * + * Purpose: Compare "standard" attributes on two objects to check that they are equal + * + * Return: TRUE if objects have same attributes/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, October 31, 2005 + * + * Note: This isn't very general, the attributes are assumed to be + * those written in test_copy_attach_attributes(). + * + *------------------------------------------------------------------------- + */ +static int +compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) +{ + hid_t aid = -1, aid2 = -1; /* Attribute IDs */ + H5O_info_t oinfo1, oinfo2; /* Object info */ + unsigned cpy_flags; /* Object copy flags */ + + /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ + if(pid != H5P_DEFAULT) { + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + } /* end if */ + else + cpy_flags = 0; + + /* Check the number of attributes on source dataset */ + if(H5Oget_info2(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + + /* Check the number of attributes on destination dataset */ + if(H5Oget_info2(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + + if(cpy_flags & H5O_COPY_WITHOUT_ATTR_FLAG) { + /* Check that the destination has no attributes */ + if(oinfo2.num_attrs != 0) TEST_ERROR + } /* end if */ + else { + char attr_name[ATTR_NAME_LEN]; /* Attribute name */ + unsigned i; /* Local index variable */ + + /* Compare the number of attributes */ + if(oinfo1.num_attrs != oinfo2.num_attrs) TEST_ERROR + + /* Check the attributes are equal */ + for(i = 0; i < (unsigned)oinfo1.num_attrs; i++) { + if((aid = H5Aopen_by_idx(oid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)i, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Aget_name(aid, (size_t)ATTR_NAME_LEN, attr_name) < 0) TEST_ERROR + + if((aid2 = H5Aopen(oid2, attr_name, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check the attributes are equal */ + if(!compare_attribute(aid, aid2, pid, NULL, oid)) TEST_ERROR + + /* Close the attributes */ + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Aclose(aid2) < 0) TEST_ERROR + } /* end for */ + } /* end if */ + + /* Objects should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + H5Aclose(aid2); + H5Aclose(aid); + } H5E_END_TRY; + return FALSE; +} /* end compare_std_attributes() */ + + +/*------------------------------------------------------------------------- + * Function: compare_data + * + * Purpose: Compare two buffers of data to check that they are equal + * + * Return: TRUE if buffer are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, + const void *buf1, const void *buf2, hid_t obj_owner) +{ + size_t elmt_size; /* Size of an element */ + + /* Check size of each element */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + /* If the type is a compound containing a vlen, loop over all elements for + * each compound member. Compounds containing reference are not supported + * yet. */ + if((H5Tget_class(tid) == H5T_COMPOUND) + && (H5Tdetect_class(tid, H5T_VLEN) == TRUE)) { + hid_t memb_id; /* Member id */ + const uint8_t *memb1; /* Pointer to current member */ + const uint8_t *memb2; /* Pointer to current member */ + int nmembs; /* Number of members */ + size_t memb_off; /* Member offset */ + size_t memb_size; /* Member size */ + unsigned memb_idx; /* Member index */ + size_t elmt; /* Current element */ + + /* Get number of members in compound */ + if((nmembs = H5Tget_nmembers(tid)) < 0) TEST_ERROR + + /* Loop over members */ + for(memb_idx=0; memb_idx<(unsigned)nmembs; memb_idx++) { + /* Get member offset. Note that we cannot check for an error here. + */ + memb_off = H5Tget_member_offset(tid, memb_idx); + + /* Get member id */ + if((memb_id = H5Tget_member_type(tid, memb_idx)) < 0) TEST_ERROR + + /* Get member size */ + if((memb_size = H5Tget_size(memb_id)) == 0) TEST_ERROR + + /* Set up pointers to member in the first element */ + memb1 = (const uint8_t *)buf1 + memb_off; + memb2 = (const uint8_t *)buf2 + memb_off; + + /* Check if this member contains (or is) a vlen */ + if(H5Tget_class(memb_id) == H5T_VLEN) { + hid_t base_id; /* vlen base type id */ + + /* Get base type of vlen datatype */ + if((base_id = H5Tget_super(memb_id)) < 0) TEST_ERROR + + /* Iterate over all elements, recursively calling this function + * for each */ + for(elmt=0; elmtlen + != ((const hvl_t *)((const void *)memb2))->len) + TEST_ERROR + + /* Check vlen data */ + if(!compare_data(parent1, parent2, pid, base_id, + ((const hvl_t *)((const void *)memb1))->len, + ((const hvl_t *)((const void *)memb1))->p, + ((const hvl_t *)((const void *)memb2))->p, obj_owner)) + TEST_ERROR + + /* Update member pointers */ + memb1 += elmt_size; + memb2 += elmt_size; + } /* end for */ + } else { + /* vlens cannot currently be nested below the top layer of a + * compound */ + HDassert(H5Tdetect_class(memb_id, H5T_VLEN) == FALSE); + + /* Iterate over all elements, calling memcmp() for each */ + for(elmt=0; elmtlen != vl_buf2->len) TEST_ERROR + + /* Check vlen data */ + if(!compare_data(parent1, parent2, pid, base_tid, vl_buf1->len, vl_buf1->p, vl_buf2->p, obj_owner)) TEST_ERROR + } /* end for */ + + if(H5Tclose(base_tid) < 0) TEST_ERROR + } /* end if */ + else if(H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) { + size_t u; /* Local index variable */ + + /* Check for "simple" reference datatype */ + if(H5Tget_class(tid) != H5T_REFERENCE) TEST_ERROR + + /* Check for object or region reference */ + if(H5Tequal(tid, H5T_STD_REF) > 0) { + const H5R_ref_t *ref_buf1, *ref_buf2; /* Aliases for buffers to compare */ + + /* Loop over elements in buffers */ + ref_buf1 = (const H5R_ref_t *)buf1; + ref_buf2 = (const H5R_ref_t *)buf2; + for(u = 0; u < nelmts; u++, ref_buf1++, ref_buf2++) { + hid_t obj1_id, obj2_id; /* IDs for objects referenced */ + H5O_type_t obj1_type, obj2_type; /* Types of objects referenced */ + + /* Check for types of objects handled */ + if(H5Rget_obj_type3(ref_buf1, H5P_DEFAULT, &obj1_type) < 0) TEST_ERROR + if(H5Rget_obj_type3(ref_buf2, H5P_DEFAULT, &obj2_type) < 0) TEST_ERROR + if(obj1_type != obj2_type) TEST_ERROR + + /* Open referenced objects */ + if((obj1_id = H5Ropen_object(ref_buf1, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if((obj2_id = H5Ropen_object(ref_buf2, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* break the infinite loop when the ref_object points to itself */ + if(obj_owner > 0) { + H5O_info_t oinfo1, oinfo2; + + if(H5Oget_info2(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info2(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5F_addr_eq(oinfo1.addr, oinfo2.addr)) { + if(H5Oclose(obj1_id) < 0) TEST_ERROR + if(H5Oclose(obj2_id) < 0) TEST_ERROR + return TRUE; + } + } + + /* Check for types of objects handled */ + switch(obj1_type) { + case H5O_TYPE_DATASET: + if(compare_datasets(obj1_id, obj2_id, pid, NULL) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_GROUP: + if(compare_groups(obj1_id, obj2_id, pid, -1, 0) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_NAMED_DATATYPE: + if(H5Tequal(obj1_id, obj2_id) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_MAP: + /* Maps not supported in native VOL connector */ + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + TEST_ERROR + } /* end switch */ + + /* Close objects */ + if(H5Oclose(obj1_id) < 0) TEST_ERROR + if(H5Oclose(obj2_id) < 0) TEST_ERROR + + if(H5Rget_type(ref_buf1) == H5R_DATASET_REGION2) { + hid_t obj1_sid, obj2_sid; /* Dataspace IDs for objects referenced */ + + /* Get regions for referenced datasets */ + if((obj1_sid = H5Ropen_region(ref_buf1, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if((obj2_sid = H5Ropen_region(ref_buf2, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check if dataspaces are the same shape */ + if(H5Sselect_shape_same(obj1_sid, obj2_sid) < 0) TEST_ERROR + + /* Close dataspaces */ + if(H5Sclose(obj1_sid) < 0) TEST_ERROR + if(H5Sclose(obj2_sid) < 0) TEST_ERROR + } /* end if */ + } /* end for */ + } /* end if */ + else + TEST_ERROR + } /* end else */ + else + if(HDmemcmp(buf1, buf2, (elmt_size * nelmts))) TEST_ERROR + + /* Data should be the same. :-) */ + return TRUE; + +error: + return FALSE; +} /* end compare_data() */ + + +/*------------------------------------------------------------------------- + * Function: compare_datasets + * + * Purpose: Compare two datasets to check that they are equal + * + * Return: TRUE if datasets are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Tuesday, October 25, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf) +{ + hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + hid_t dcpl = -1, dcpl2 = -1; /* Dataset creation property list IDs */ + size_t elmt_size; /* Size of datatype */ + htri_t is_committed; /* If the datatype is committed */ + htri_t is_committed2; /* If the datatype is committed */ + int nfilters; /* Number of filters applied to dataset */ + hssize_t nelmts; /* # of elements in dataspace */ + void *rbuf = NULL; /* Buffer for reading raw data */ + void *rbuf2 = NULL; /* Buffer for reading raw data */ + H5D_space_status_t space_status; /* Dataset's raw dataspace status */ + H5D_space_status_t space_status2; /* Dataset's raw dataspace status */ + + /* Check the datatypes are equal */ + + /* Open the datatype for the source dataset */ + if((tid = H5Dget_type(did)) < 0) TEST_ERROR + + /* Open the datatype for the destination dataset */ + if((tid2 = H5Dget_type(did2)) < 0) TEST_ERROR + + /* Check that both datatypes are committed/not committed */ + if((is_committed = H5Tcommitted(tid)) < 0) TEST_ERROR + if((is_committed2 = H5Tcommitted(tid2)) < 0) TEST_ERROR + if(is_committed != is_committed2) TEST_ERROR + + /* Compare the datatypes */ + if(H5Tequal(tid, tid2) != TRUE) TEST_ERROR + + /* Determine the size of datatype (for later) */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + + /* Check the dataspaces are equal */ + + /* Open the dataspace for the source dataset */ + if((sid = H5Dget_space(did)) < 0) TEST_ERROR + + /* Open the dataspace for the destination dataset */ + if((sid2 = H5Dget_space(did2)) < 0) TEST_ERROR + + /* Compare the dataspaces */ + if(H5Sextent_equal(sid, sid2) != TRUE) TEST_ERROR + + /* Determine the number of elements in dataspace (for later) */ + if((nelmts = H5Sget_simple_extent_npoints(sid)) < 0) TEST_ERROR + + + /* Check the dataset creation property lists are equal */ + + /* Open the dataset creation property list for the source dataset */ + if((dcpl = H5Dget_create_plist(did)) < 0) TEST_ERROR + + /* Open the dataset creation property list for the destination dataset */ + if((dcpl2 = H5Dget_create_plist(did2)) < 0) TEST_ERROR + + /* Compare the rest of the dataset creation property lists */ + if(H5Pequal(dcpl, dcpl2) != TRUE) TEST_ERROR + + /* Get the number of filters on dataset (for later) */ + if((nfilters = H5Pget_nfilters(dcpl)) < 0) TEST_ERROR + + /* close the source dataset creation property list */ + if(H5Pclose(dcpl) < 0) TEST_ERROR + + /* close the destination dataset creation property list */ + if(H5Pclose(dcpl2) < 0) TEST_ERROR + + + /* Check the allocated storage is the same */ + + /* Check that the space allocation status is the same */ + if(H5Dget_space_status(did, &space_status) < 0) TEST_ERROR + if(H5Dget_space_status(did2, &space_status2) < 0) TEST_ERROR + if(space_status != space_status2) TEST_ERROR + + /* Check that the space used is the same */ + /* (Don't check if the dataset is filtered (i.e. compressed, etc.) and + * the datatype is VLEN, since the addresses for the vlen + * data in each dataset will (probably) be different and the storage + * size will thus vary) + */ + if(!(nfilters > 0 && (H5Tdetect_class(tid, H5T_VLEN) || + (H5Tdetect_class(tid, H5T_REFERENCE) && H5Tequal(tid, H5T_STD_REF))))) { + hsize_t storage_size = H5Dget_storage_size(did); /* Dataset's raw data storage size */ + hsize_t storage_size2 = H5Dget_storage_size(did2); /* 2nd Dataset's raw data storage size */ + + if(storage_size != storage_size2) TEST_ERROR + } /* end if */ + + /* Check the raw data is equal */ + + /* Allocate & initialize space for the raw data buffers */ + if((rbuf = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + if((rbuf2 = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + + /* Read data from datasets */ + if(H5Dread(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Check raw data read in against data written out */ + if(wbuf) { + if(!compare_data(did, (hid_t)0, pid, tid, (size_t)nelmts, wbuf, rbuf, did)) TEST_ERROR + if(!compare_data(did2, (hid_t)0, pid, tid2, (size_t)nelmts, wbuf, rbuf2, did2)) TEST_ERROR + } /* end if */ + /* Don't have written data, just compare data between the two datasets */ + else + if(!compare_data(did, did2, pid, tid, (size_t)nelmts, rbuf, rbuf2, did)) TEST_ERROR + + /* Reclaim vlen data, if necessary */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE || H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE || H5Tdetect_class(tid2, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Release raw data buffers */ + HDfree(rbuf); + rbuf = NULL; + HDfree(rbuf2); + rbuf2 = NULL; + + /* close the source dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + + /* close the destination dataspace */ + if(H5Sclose(sid2) < 0) TEST_ERROR + + /* close the source datatype */ + if(H5Tclose(tid) < 0) TEST_ERROR + + /* close the destination datatype */ + if(H5Tclose(tid2) < 0) TEST_ERROR + + + /* Check if the attributes are equal */ + if(compare_std_attributes(did, did2, pid) != TRUE) TEST_ERROR + + + /* Datasets should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + if(rbuf) + HDfree(rbuf); + if(rbuf2) + HDfree(rbuf2); + H5Pclose(dcpl2); + H5Pclose(dcpl); + H5Sclose(sid2); + H5Sclose(sid); + H5Tclose(tid2); + H5Tclose(tid); + } H5E_END_TRY; + return FALSE; +} /* end compare_datasets() */ + + +/*------------------------------------------------------------------------- + * Function: compare_groups + * + * Purpose: Compare two groups to check that they are "equal" + * + * Return: TRUE if group are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, October 31, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) +{ + H5G_info_t ginfo; /* Group info struct */ + H5G_info_t ginfo2; /* Group info struct */ + hsize_t idx; /* Index over the objects in group */ + unsigned cpy_flags; /* Object copy flags */ + + /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ + if(pid != H5P_DEFAULT) { + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + } /* end if */ + else + cpy_flags = 0; + + /* Check if both groups have the same # of objects */ + if(H5Gget_info(gid, &ginfo) < 0) TEST_ERROR + if(H5Gget_info(gid2, &ginfo2) < 0) TEST_ERROR + if((cpy_flags & H5O_COPY_SHALLOW_HIERARCHY_FLAG) && depth == 0) { + if(ginfo2.nlinks != 0) TEST_ERROR + } /* end if */ + else { + if(ginfo.nlinks != ginfo2.nlinks) TEST_ERROR + } /* end if */ + + /* Check contents of groups */ + if(ginfo2.nlinks > 0) { + char objname[NAME_BUF_SIZE]; /* Name of object in group */ + char objname2[NAME_BUF_SIZE]; /* Name of object in group */ + H5L_info_t linfo; /* Link information */ + H5L_info_t linfo2; /* Link information */ + + /* Loop over contents of groups */ + for(idx = 0; idx < ginfo.nlinks; idx++) { + /* Check name of objects */ + if(H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, idx, objname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_name_by_idx(gid2, ".", H5_INDEX_NAME, H5_ITER_INC, idx, objname2, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, objname2)) TEST_ERROR + + /* Get link info */ + if(H5Lget_info(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.type != linfo2.type) TEST_ERROR + + /* Extra checks for "real" objects */ + if(linfo.type == H5L_TYPE_HARD) { + hid_t oid, oid2; /* IDs of objects within group */ + H5O_info_t oinfo, oinfo2; /* Object info */ + + /* Compare some pieces of the object info */ + if(H5Oget_info_by_name2(gid, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(gid2, objname2, &oinfo2, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + + if(oinfo.type != oinfo2.type) TEST_ERROR + if(oinfo.rc != oinfo2.rc) TEST_ERROR + + /* If NULL messages are preserved, the number of messages + * should be the same in the destination. + * Otherwise, it should simply be true that the number + * of messages hasn't increased. + */ + if(H5O_COPY_PRESERVE_NULL_FLAG & copy_flags) { + if(oinfo.hdr.nmesgs != oinfo2.hdr.nmesgs) + ; + else + if(oinfo.hdr.nmesgs < oinfo2.hdr.nmesgs) TEST_ERROR + } + + /* Check for object already having been compared */ + if(addr_lookup(&oinfo)) + continue; + else + addr_insert(&oinfo); + + /* Open objects */ + if((oid = H5Oopen(gid, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((oid2 = H5Oopen(gid2, objname2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Compare objects within group */ + switch(oinfo.type) { + case H5O_TYPE_GROUP: + /* Compare groups */ + if(compare_groups(oid, oid2, pid, depth - 1, copy_flags) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_DATASET: + /* Compare datasets */ + if(compare_datasets(oid, oid2, pid, NULL) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_NAMED_DATATYPE: + /* Compare datatypes */ + if(H5Tequal(oid, oid2) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_MAP: + HDassert(0 && "maps not supported in native VOL connector"); + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + HDassert(0 && "Unknown type of object"); + break; + } /* end switch */ + + /* Close objects */ + if(H5Oclose(oid) < 0) TEST_ERROR + if(H5Oclose(oid2) < 0) TEST_ERROR + } /* end if */ + else { + /* Check that both links are the same size */ + if(linfo.u.val_size != linfo2.u.val_size) TEST_ERROR + + /* Compare link values */ + if(linfo.type == H5L_TYPE_SOFT || + (linfo.type >= H5L_TYPE_UD_MIN && linfo.type <= H5L_TYPE_MAX)) { + char linkval[NAME_BUF_SIZE]; /* Link value */ + char linkval2[NAME_BUF_SIZE]; /* Link value */ + + /* Get link values */ + HDassert(linfo.u.val_size <= NAME_BUF_SIZE); + if(H5Lget_val(gid, objname, linkval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_val(gid2, objname2, linkval2, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + + /* Compare link data */ + if(HDmemcmp(linkval, linkval2, linfo.u.val_size)) TEST_ERROR + } /* end else-if */ + else { +HDassert(0 && "Unknown type of link"); + } /* end else */ + } /* end else */ + } /* end for */ + } /* end if */ + + /* Check if the attributes are equal */ + if(compare_std_attributes(gid, gid2, pid) != TRUE) TEST_ERROR + + /* Groups should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + } H5E_END_TRY; + return FALSE; +} /* end compare_groups() */ + +/*------------------------------------------------------------------------- + * Function: test_copy_option + * + * Purpose: Create a group in SRC file and copy it to DST file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Peter Cao + * March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, + unsigned flag, hbool_t crt_intermediate_grp, const char* test_desciption) +{ + hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */ + hid_t sid = -1; /* Dataspace ID */ + hid_t did = -1; /* Dataset ID */ + hid_t gid=-1, gid2=-1, gid_ref=-1; /* Group IDs */ + hid_t gid_sub=-1, gid_sub_sub=-1; /* Sub-group ID */ + hid_t pid=-1, lcpl_id=-1; /* Property IDs */ + unsigned cpy_flags; /* Object copy flags */ + int depth = -1; /* Copy depth */ + hsize_t dim2d[2]; + int buf[DIM_SIZE_1][DIM_SIZE_2]; + int i, j; + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING(test_desciption); + + /* set initial data values */ + for (i=0; i 0) { + /* Create group to copy */ + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft(NAME_DATASET_SUB_SUB, fid_src, NAME_LINK_SOFT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Create group to compare with */ + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Lcreate_hard(fid_src, NAME_DATASET_SUB_SUB, H5L_SAME_LOC, NAME_LINK_SOFT2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + } /* end if */ + + if((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0) { + char ext_filename[NAME_BUF_SIZE]; + + h5_fixname(FILENAME[2], src_fapl, ext_filename, sizeof ext_filename); + + /* Create the external file and dataset */ + if((fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR + if((sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR + if((did = H5Dcreate2(fid_ext, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + if(H5Fclose(fid_ext) < 0) TEST_ERROR + + /* Create group to copy */ + if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) { + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + } /* end if */ + else + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Lcreate_external(ext_filename, NAME_DATASET_SIMPLE, fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create group to compare with */ + if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) { + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + } /* end if */ + else + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) TEST_ERROR + if((did = H5Dcreate2(fid_src, NAME_LINK_EXTERN2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + } /* end if */ + + if((flag & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) { + if((gid_ref = H5Gcreate2(fid_src, NAME_GROUP_REF, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* create an attribute of new object references */ + if(attach_ref_attr(fid_src, gid_ref) < 0) TEST_ERROR + + /* create an attribute of region references */ + if(attach_reg_ref_attr(fid_src, gid_ref) < 0) TEST_ERROR + + /* create a dataset of region references */ + if(create_reg_ref_dataset(fid_src, gid_ref) < 0) TEST_ERROR + + /* Close group holding reference objects */ + if(H5Gclose(gid_ref) < 0) TEST_ERROR + } /* end if */ + + /* close the SRC file */ + if(H5Fclose(fid_src) < 0) TEST_ERROR + + /* open the source file with read-only */ + /* (except when expanding soft links */ + if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) { + if((fid_src = H5Fopen(src_filename, H5F_ACC_RDWR, src_fapl)) < 0) TEST_ERROR + } /* end if */ + else + if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR + + /* create destination file */ + if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR + + /* Create an uncopied object in destination file so that addresses in source and destination + files aren't the same */ + if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* create property to pass copy options */ + if((pid = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR + + /* set options for object copy */ + if(H5Pset_copy_object(pid, flag) < 0) TEST_ERROR + + /* Verify object copy flags */ + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + if(cpy_flags != flag) TEST_ERROR + + /* copy the group from SRC to DST */ + if(crt_intermediate_grp) { + /* Create link creation plist to pass in intermediate group creation */ + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR + + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, "/new_g0/new_g00", pid, lcpl_id) < 0) TEST_ERROR + + if(H5Pclose(lcpl_id) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, "/new_g0/new_g00", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + } else if(((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + || ((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0)) { + if(H5Ocopy(fid_src, NAME_GROUP_LINK, fid_dst, NAME_GROUP_LINK, pid, H5P_DEFAULT) < 0) TEST_ERROR + + if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + /* Unlink dataset to copy from original location */ + /* (So group comparison works properly) */ + if(H5Ldelete(fid_src, NAME_DATASET_SUB_SUB, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + } else if(flag & (H5O_COPY_WITHOUT_ATTR_FLAG | H5O_COPY_PRESERVE_NULL_FLAG)) { + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + } else if(flag & H5O_COPY_SHALLOW_HIERARCHY_FLAG) { + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Set the copy depth */ + depth = 1; + } else if((flag & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) { + if(H5Ocopy(fid_src, NAME_GROUP_REF, fid_dst, NAME_GROUP_REF, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_REF, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_REF, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + } else { + /* Unknown flag */ + TEST_ERROR + } /* end else */ + + /* Check if the groups are equal */ + if(compare_groups(gid, gid2, pid, depth, flag) != TRUE) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* close the SRC file */ + if(H5Fclose(fid_src) < 0) TEST_ERROR + + /* close the DST file */ + if(H5Fclose(fid_dst) < 0) TEST_ERROR + + /* close properties */ + if(H5Pclose(pid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(lcpl_id); + H5Pclose(pid); + H5Sclose(sid); + H5Dclose(did); + H5Gclose(gid_ref); + H5Gclose(gid_sub); + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + H5Fclose(fid_ext); + } H5E_END_TRY; + return 1; +} /* end test_copy_option */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Test H5Ocopy() + * + * Tests a number of cases: messages can be stored in the + * new or old format, messages can be shared in either, + * both, or neither of the source and destination files. + * + * Return: EXIT_SUCCESS/EXIT_FAILURE + * + * Programmer: Peter Cao + * Friday, September 30, 2005 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + int nerrors = 0; + hid_t fapl, fapl2; + hid_t fcpl_shared, ocpl; + unsigned max_compact, min_dense; + int configuration; /* Configuration of tests. */ + int ExpressMode; + hbool_t same_file; /* Whether to run tests that only use one file */ + + /* Setup */ + h5_reset(); + fapl = h5_fileaccess(); + + ExpressMode = GetTestExpress(); + if (ExpressMode > 1) + HDprintf("***Express test mode on. Some tests may be skipped\n"); + + /* Copy the file access property list */ + if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Set the "use the latest version of the format" bounds for creating objects in the file */ + if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR + + /* Create an FCPL with sharing enabled */ + if((fcpl_shared = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR + if(H5Pset_shared_mesg_nindexes(fcpl_shared, 1) < 0) TEST_ERROR + if(H5Pset_shared_mesg_index(fcpl_shared, 0, H5O_SHMESG_ALL_FLAG, 10) < 0) TEST_ERROR + + /* Obtain the default attribute storage phase change values */ + if((ocpl = H5Pcreate(H5P_OBJECT_CREATE)) < 0) TEST_ERROR + if(H5Pget_attr_phase_change(ocpl, &max_compact, &min_dense) < 0) TEST_ERROR + if(H5Pclose(ocpl) < 0) TEST_ERROR + + /* Test in all configurations */ + for(configuration = 0; configuration <= MAX_CONFIGURATION; configuration++) { + hid_t src_fapl; + hid_t dst_fapl; + hid_t fcpl_src; + hid_t fcpl_dst; + + /* Start with same_file == TRUE. Use source file settings for these + * tests. Don't run with a non-default destination file setting, as + * destination settings have no effect. */ + same_file = TRUE; + + /* No need to test dense attributes with old format */ + if(!(configuration & CONFIG_SRC_NEW_FORMAT) && (configuration & CONFIG_DENSE)) + continue; + + /* TODO Region references currently do not support copy from new format to old format + * (this may be fixed once H5Sencode/decode and H5CXis fixed) */ + if((configuration & CONFIG_SRC_NEW_FORMAT) && !(configuration & CONFIG_DST_NEW_FORMAT)) + continue; + + /* Test with and without shared messages */ + if(configuration & CONFIG_SHARE_SRC) { + HDputs("\nTesting with shared src messages:"); + fcpl_src = fcpl_shared; + } + else { + HDputs("\nTesting without shared src messages:"); + fcpl_src = H5P_DEFAULT; + } + if(configuration & CONFIG_SHARE_DST) { + HDputs("Testing with shared dst messages:"); + fcpl_dst = fcpl_shared; + same_file = FALSE; + } + else { + HDputs("Testing without shared dst messages:"); + fcpl_dst = H5P_DEFAULT; + } + + /* Set the FAPL for the source file's type of format */ + if(configuration & CONFIG_SRC_NEW_FORMAT) { + HDputs("Testing with latest format for source file:"); + src_fapl = fapl2; + + /* Test with and without dense attributes */ + if(configuration & CONFIG_DENSE) { + HDputs("Testing with dense attributes:"); + num_attributes_g = max_compact + 1; + } + else { + HDputs("Testing without dense attributes:"); + num_attributes_g = MAX(min_dense, 2) - 2; + } + } /* end if */ + else { + HDputs("Testing with oldest file format for source file:"); + src_fapl = fapl; + num_attributes_g = 4; + } /* end else */ + + /* Set the FAPL for the destination file's type of format */ + if(configuration & CONFIG_DST_NEW_FORMAT) { + HDputs("Testing with latest format for destination file:"); + dst_fapl = fapl2; + same_file = FALSE; + } /* end if */ + else { + HDputs("Testing with oldest file format for destination file:"); + dst_fapl = fapl; + } /* end else */ + + /* The tests... */ + nerrors += test_copy_option(fcpl_src, fcpl_dst, src_fapl, dst_fapl, + H5O_COPY_EXPAND_REFERENCE_FLAG, + FALSE, "H5Ocopy(): expand object reference"); + } /* end for */ + + /* Reset file address checking info */ + addr_reset(); + + /* Verify symbol table messages are cached */ + nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); + + /* Results */ + if(nerrors) { + HDprintf("***** %d OBJECT COPY TEST%s FAILED! *****\n", + nerrors, (1 == nerrors ? "" : "S")); + HDexit(EXIT_FAILURE); + } /* end if */ + + HDputs ("All object copying tests passed."); + + /* close property list. + * NOTE: if this property list is not closed and the test is + * run with the split or multi driver, an interesting + * problem is exposed in the property list shutdown code. + * + * Namely, since the split/multi driver copies property + * lists for internal use, there's a (high) chance that + * leaving the FAPL open and having the library's shutdown + * code close it will cause the underlying property lists + * to be cleaned up first, causing the actual property list + * close operation to fail (since it won't be able to close + * the already closed underlying property list). + * + * The could be addressed by converting the split/multi to + * use non-public API routines, or putting some way into the + * public H5I routines to indicate ordering at shutdown. + * + * For now, we just make certain to close the property list. + * (QAK - 2016/04/06) + * + */ + H5Pclose(fapl2); + + h5_cleanup(FILENAME, fapl); + + HDexit(EXIT_SUCCESS); + +error: + HDexit(EXIT_FAILURE); +} /* main */ + diff --git a/test/testhdf5.c b/test/testhdf5.c index e136086..72acf6c 100644 --- a/test/testhdf5.c +++ b/test/testhdf5.c @@ -57,7 +57,8 @@ main(int argc, char *argv[]) AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL); AddTest("select", test_select, cleanup_select, "Selections", NULL); AddTest("time", test_time, cleanup_time, "Time Datatypes", NULL); - AddTest("reference", test_reference, cleanup_reference, "References", NULL); + AddTest("ref_deprec", test_reference_deprec, cleanup_reference_deprec, "Deprecated References", NULL); + AddTest("ref", test_reference, cleanup_reference, "References", NULL); AddTest("vltypes", test_vltypes, cleanup_vltypes, "Variable-Length Datatypes", NULL); AddTest("vlstrings", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL); AddTest("iterate", test_iterate, cleanup_iterate, "Group & Attribute Iteration", NULL); diff --git a/test/testhdf5.h b/test/testhdf5.h index ef3b784..6b13cae 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -192,6 +192,7 @@ void test_attr(void); void test_select(void); void test_time(void); void test_reference(void); +void test_reference_deprec(void); void test_vltypes(void); void test_vlstrings(void); void test_iterate(void); @@ -215,6 +216,7 @@ void cleanup_attr(void); void cleanup_select(void); void cleanup_time(void); void cleanup_reference(void); +void cleanup_reference_deprec(void); void cleanup_vltypes(void); void cleanup_vlstrings(void); void cleanup_iterate(void); diff --git a/test/trefer.c b/test/trefer.c index 7158984..7d87ea9 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -21,9 +21,16 @@ #include "testhdf5.h" -#define FILE1 "trefer1.h5" -#define FILE2 "trefer2.h5" -#define FILE3 "trefer3.h5" +#define FILE_REF_PARAM "trefer_param.h5" +#define FILE_REF_OBJ "trefer_obj.h5" +#define FILE_REF_REG "trefer_reg.h5" +#define FILE_REF_REG_1D "trefer_reg_1d.h5" +#define FILE_REF_OBJ_DEL "trefer_obj_del.h5" +#define FILE_REF_GRP "trefer_grp.h5" +#define FILE_REF_ATTR "trefer_attr.h5" +#define FILE_REF_EXT1 "trefer_ext1.h5" +#define FILE_REF_EXT2 "trefer_ext2.h5" +#define FILE_REF_COMPAT "trefer_compat.h5" /* 1-D dataset with fixed dimensions */ #define SPACE1_RANK 1 @@ -55,6 +62,10 @@ typedef struct s1_t { #define DSETNAME2 "dset2" #define NAME_SIZE 16 +#define MAX_ITER_CREATE 1000 +#define MAX_ITER_WRITE MAX_ITER_CREATE +#define MAX_ITER_READ MAX_ITER_CREATE + /**************************************************************** ** @@ -65,47 +76,57 @@ typedef struct s1_t { static void test_reference_params(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t group; /* Group ID */ - hid_t sid1; /* Dataspace ID */ - hid_t tid1; /* Datatype ID */ - hid_t dapl_id; /* Dataset access property list */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hid_t aapl_id; /* Attribute access property list */ + hid_t dapl_id; /* Dataset access property list */ hsize_t dims1[] = {SPACE1_DIM1}; - hobj_ref_t *wbuf, /* buffer to write to disk */ - *rbuf, /* buffer read from disk */ - *tbuf; /* temp. buffer read from disk */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + H5R_type_t type; /* Reference type */ unsigned *tu32; /* Temporary pointer to uint32 data */ - int i; /* counting variables */ - const char *write_comment = "Foo!"; /* Comments for group */ - hid_t ret_id; /* Generic hid_t return value */ - ssize_t name_size; /* Size of reference name */ - herr_t ret; /* Generic return value */ + int i; /* Counters */ + const char *write_comment = "Foo!"; /* Comments for group */ + hid_t ret_id; /* Generic hid_t return value */ + ssize_t name_size; /* Size of reference name */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Reference Parameters\n")); /* Allocate write & read buffers */ - wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_PARAM, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create attribute access property list */ + aapl_id = H5Pcreate(H5P_ATTRIBUTE_ACCESS); + CHECK(aapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a group */ group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); /* Set group's comment */ ret = H5Oset_comment(group, write_comment); @@ -113,10 +134,7 @@ test_reference_params(void) /* Create a dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); - - for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) - *tu32++ = (unsigned)i * 3; + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); @@ -128,7 +146,19 @@ test_reference_params(void) /* Create another dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -136,7 +166,7 @@ test_reference_params(void) /* Create a datatype to refer to */ tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); @@ -161,58 +191,88 @@ test_reference_params(void) CHECK(ret, FAIL, "H5Gclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); - - /* Test parameters to H5Rcreate */ - ret = H5Rcreate(NULL, fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate ref"); - ret = H5Rcreate(&wbuf[0], (hid_t)-1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate loc_id"); - ret = H5Rcreate(&wbuf[0], fid1, NULL, H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate name"); - ret = H5Rcreate(&wbuf[0], fid1, "", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate null name"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate type"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate region space"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)0); - VERIFY(ret, FAIL, "H5Rcreate space"); - - /* Test parameters to H5Rdereference */ - dset2 = H5Rdereference2((hid_t)-1, H5P_DEFAULT, H5R_OBJECT, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 loc_id"); - dset2 = H5Rdereference2(dataset, (hid_t)-1, H5R_OBJECT, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 oapl_id"); - dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, NULL); - VERIFY(dset2, FAIL, "H5Rdereference2 ref"); - dset2 = H5Rdereference2(dataset, dapl_id, H5R_MAXTYPE, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 type"); - - /* Test parameters to H5Rget_obj_type2 */ - ret = H5Rget_obj_type2((hid_t)-1, H5R_OBJECT, &rbuf[0], NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 loc_id"); - ret = H5Rget_obj_type2(fid1, H5R_OBJECT, NULL, NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 ref"); - ret = H5Rget_obj_type2(fid1, H5R_MAXTYPE, &rbuf[0], NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 type"); - - /* Test parameters to H5Rget_name */ - name_size = H5Rget_name((hid_t)-1, H5R_DATASET_REGION, &rbuf[0], NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name loc_id"); - name_size = H5Rget_name(fid1, H5R_DATASET_REGION, NULL, NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name ref"); - name_size = H5Rget_name(fid1, H5R_MAXTYPE, &rbuf[0], NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name type"); - - /* Test parameters to H5Rget_region */ - ret_id = H5Rget_region((hid_t)-1, H5R_OBJECT, &rbuf[0]); - VERIFY(ret_id, FAIL, "H5Rget_region loc_id"); - ret_id = H5Rget_region(fid1, H5R_OBJECT, NULL); - VERIFY(ret_id, FAIL, "H5Rget_region ref"); - ret_id = H5Rget_region(fid1, H5R_OBJECT, &rbuf[0]); - VERIFY(ret_id, FAIL, "H5Rget_region type"); + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dcreate2"); + + /* Test parameters to H5Rcreate_object */ + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", NULL); + VERIFY(ret, FAIL, "H5Rcreate_object ref"); + ret = H5Rcreate_object(H5I_INVALID_HID, "/Group1/Dataset1", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object loc_id"); + ret = H5Rcreate_object(fid1, NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object name"); + ret = H5Rcreate_object(fid1, "", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object null name"); + + /* Test parameters to H5Rcreate_region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, NULL); + VERIFY(ret, FAIL, "H5Rcreate_region ref"); + ret = H5Rcreate_region(H5I_INVALID_HID, "/Group1/Dataset1", sid1, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region loc_id"); + ret = H5Rcreate_region(fid1, NULL, sid1, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region name"); + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", H5I_INVALID_HID, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region dataspace"); + + /* Test parameters to H5Rcreate_attr */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", "Attr", NULL); + VERIFY(ret, FAIL, "H5Rcreate_attr ref"); + ret = H5Rcreate_attr(H5I_INVALID_HID, "/Group1/Dataset2", "Attr", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr loc_id"); + ret = H5Rcreate_attr(fid1, NULL, "Attr", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr name"); + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr attr_name"); + + /* Test parameters to H5Rdestroy */ + ret = H5Rdestroy(NULL); + VERIFY(ret, FAIL, "H5Rdestroy"); + + /* Test parameters to H5Rget_type */ + type = H5Rget_type(NULL); + VERIFY(type, H5R_BADTYPE, "H5Rget_type ref"); + + /* Test parameters to H5Requal */ + ret = H5Requal(NULL, (const H5R_ref_t *)&rbuf[0]); + VERIFY(ret, FAIL, "H5Requal ref1"); + ret = H5Requal((const H5R_ref_t *)&rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Requal ref2"); + + /* Test parameters to H5Rcopy */ + ret = H5Rcopy(NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcopy src_ref"); + ret = H5Rcopy((const H5R_ref_t *)&rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rcopy dest_ref"); + + /* Test parameters to H5Ropen_object */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5I_INVALID_HID, H5I_INVALID_HID); + VERIFY(dset2, FAIL, "H5Ropen_object oapl_id"); + dset2 = H5Ropen_object(NULL, H5P_DEFAULT, dapl_id); + VERIFY(dset2, FAIL, "H5Ropen_object ref"); + + /* Test parameters to H5Ropen_region */ + ret_id = H5Ropen_region(NULL, H5I_INVALID_HID, H5I_INVALID_HID); + VERIFY(ret_id, H5I_INVALID_HID, "H5Ropen_region ref"); + + /* Test parameters to H5Ropen_attr */ + ret_id = H5Ropen_attr(NULL, H5P_DEFAULT, aapl_id); + VERIFY(ret_id, H5I_INVALID_HID, "H5Ropen_attr ref"); + + /* Test parameters to H5Rget_obj_type3 */ + ret = H5Rget_obj_type3(NULL, H5P_DEFAULT, NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type3 ref"); + + /* Test parameters to H5Rget_file_name */ + name_size = H5Rget_file_name(NULL, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_file_name ref"); + + /* Test parameters to H5Rget_obj_name */ + name_size = H5Rget_obj_name(NULL, H5P_DEFAULT, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_obj_name ref"); + + /* Test parameters to H5Rget_attr_name */ + name_size = H5Rget_attr_name(NULL, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_attr_name ref"); /* Close disk dataspace */ ret = H5Sclose(sid1); @@ -222,6 +282,10 @@ test_reference_params(void) ret = H5Pclose(dapl_id); CHECK(ret, FAIL, "H5Pclose"); + /* Close attribute access property list */ + ret = H5Pclose(aapl_id); + CHECK(ret, FAIL, "H5Pclose"); + /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); @@ -234,7 +298,7 @@ test_reference_params(void) HDfree(wbuf); HDfree(rbuf); HDfree(tbuf); -} /* test_reference_obj() */ +} /* test_reference_params() */ /**************************************************************** ** @@ -245,60 +309,52 @@ test_reference_params(void) static void test_reference_obj(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t group; /* Group ID */ - hid_t sid1; /* Dataspace ID */ - hid_t tid1; /* Datatype ID */ - hsize_t dims1[] = {SPACE1_DIM1}; - hid_t dapl_id; /* Dataset access property list */ - hobj_ref_t *wbuf, /* buffer to write to disk */ - *rbuf, /* buffer read from disk */ - *tbuf; /* temp. buffer read from disk */ - hobj_ref_t nvrbuf[3]={0,101,1000000000}; /* buffer with non-valid refs */ - unsigned *tu32; /* Temporary pointer to uint32 data */ - int i, j; /* counting variables */ - const char *write_comment="Foo!"; /* Comments for group */ - char read_comment[10]; - H5O_type_t obj_type; /* Object type */ - ssize_t size; /* Comment length */ - herr_t ret; /* Generic return value */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* Counters */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Object Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_OBJ, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a group */ group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); - - /* Set group's comment */ - ret = H5Oset_comment(group, write_comment); - CHECK(ret, FAIL, "H5Oset_comment"); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); /* Create a dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); - - for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) - *tu32++ = (unsigned)i * 3; + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); @@ -318,7 +374,7 @@ test_reference_obj(void) /* Create a datatype to refer to */ tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); @@ -343,39 +399,39 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Gclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[1], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Dataset2", &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Create reference to group */ - ret = H5Rcreate(&wbuf[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[2], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1", &wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); /* Create reference to named datatype */ - ret = H5Rcreate(&wbuf[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[3], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Datatype1", &wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); /* Write selection to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); /* Close disk dataspace */ @@ -391,27 +447,27 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_OBJ, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); /* Open dataset object */ - dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, &rbuf[0]); - CHECK(dset2, FAIL, "H5Rdereference2"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset2); - CHECK(sid1, FAIL, "H5Dget_space"); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 4, "H5Sget_simple_extent_npoints"); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); /* Read from disk */ ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); @@ -425,24 +481,16 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Dclose"); /* Open group object. GAPL isn't supported yet. But it's harmless to pass in */ - group = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[2]); - CHECK(group, FAIL, "H5Rdereference2"); - - /* Get group's comment */ - size = H5Oget_comment(group, read_comment, (size_t)10); - CHECK(size, FAIL, "H5Oget_comment"); - - /* Check for correct comment value */ - if(HDstrcmp(write_comment, read_comment) != 0) - TestErrPrintf("Error! Incorrect group comment, wanted: %s, got: %s\n",write_comment,read_comment); + group = H5Ropen_object((const H5R_ref_t *)&rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Ropen_object"); /* Close group */ ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); /* Open datatype object. TAPL isn't supported yet. But it's harmless to pass in */ - tid1 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[3]); - CHECK(tid1, FAIL, "H5Rdereference2"); + tid1 = H5Ropen_object((const H5R_ref_t *)&rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(tid1, H5I_INVALID_HID, "H5Ropen_object"); /* Verify correct datatype */ { @@ -455,14 +503,6 @@ test_reference_obj(void) VERIFY(ret, 3, "H5Tget_nmembers"); } - /* Attempting to retrieve type of object using non-valid refs */ - for(j = 0; j < 3; j++) { - H5E_BEGIN_TRY { - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &nvrbuf[j], &obj_type); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Rget_obj_type2"); - } /* end for */ - /* Close datatype */ ret = H5Tclose(tid1); CHECK(ret, FAIL, "H5Tclose"); @@ -479,6 +519,14 @@ test_reference_obj(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(j = 0; j < SPACE1_DIM1; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -498,13 +546,13 @@ test_reference_obj(void) static void test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) { - hid_t fid1; /* HDF5 File IDs */ - hid_t fapl = -1; /* File access property list */ - hid_t dset1, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t sid1, /* Dataspace ID #1 */ - sid2; /* Dataspace ID #2 */ - hid_t dapl_id; /* Dataset access property list */ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid2; /* Dataspace ID #2 */ + hid_t dapl_id; /* Dataset access property list */ hsize_t dims1[] = {SPACE1_DIM1}, dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ @@ -512,62 +560,60 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ - hsize_t *coords; /* Coordinate buffer */ - hsize_t low[SPACE2_RANK]; /* Selection bounds */ - hsize_t high[SPACE2_RANK]; /* Selection bounds */ - hdset_reg_ref_t *wbuf, /* buffer to write to disk */ - *rbuf; /* buffer read from disk */ - hdset_reg_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ - uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ - *drbuf; /* Buffer for reading numeric data from disk */ - uint8_t *tu8; /* Temporary pointer to uint8 data */ - H5O_type_t obj_type; /* Type of object */ - int i, j; /* counting variables */ - hssize_t hssize_ret; /* hssize_t return value */ - htri_t tri_ret; /* htri_t return value */ - herr_t ret; /* Generic return value */ - hdset_reg_ref_t undef_reg[1]; /* test for undefined reference */ - hid_t dset_NA; /* Dataset id for undefined reference */ - hid_t space_NA; /* Dataspace id for undefined reference */ - hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ - hdset_reg_ref_t wdata_NA[1], /* Write buffer */ - rdata_NA[1]; /* Read buffer */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE2_RANK]; /* Selection bounds */ + hsize_t high[SPACE2_RANK]; /* Selection bounds */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + H5R_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Type of object */ + int i, j; /* Counters */ + hssize_t hssize_ret; /* hssize_t return value */ + htri_t tri_ret; /* htri_t return value */ + herr_t ret; /* Generic return value */ + hid_t dset_NA; /* Dataset id for undefined reference */ + hid_t space_NA; /* Dataspace id for undefined reference */ + hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ + H5R_ref_t rdata_NA[1]; /* Read buffer */ /* Output message about test being performed */ MESSAGE(5, ("Testing Dataset Region Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); - rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); - dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE2_DIM1 * SPACE2_DIM2); + wbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + dwbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); + for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) + *tu8++ = (uint8_t)(i * 3); + /* Create file access property list */ fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); /* Set the low/high version bounds in fapl */ ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create file with the fapl */ - fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_REG, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); - CHECK(sid2, FAIL, "H5Screate_simple"); + CHECK(sid2, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a dataset */ dset2 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset2, FAIL, "H5Dcreate2"); - - for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) - *tu8++ = (uint8_t)(i * 3); + CHECK(dset2, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); @@ -579,11 +625,11 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Create dataspace for the reference dataset */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset */ - dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset1, H5I_INVALID_HID, "H5Dcreate2"); /* Create references */ @@ -599,11 +645,11 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(ret, 36, "H5Sget_select_npoints"); /* Store first dataset region */ - ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Select sequence of ten points for second reference */ coord1[0][0] = 6; coord1[0][1] = 9; @@ -620,17 +666,21 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_npoints"); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_npoints"); /* Store second dataset region */ - ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_region"); /* Select unlimited hyperslab for third reference */ - start[0] = 1; start[1] = 8; - stride[0] = 4; stride[1] = 1; - count[0] = H5S_UNLIMITED; count[1] = 1; - block[0] = 2; block[1] = 2; + start[0] = 1; + start[1] = 8; + stride[0] = 4; + stride[1] = 1; + count[0] = H5S_UNLIMITED; + count[1] = 1; + block[0] = 2; + block[1] = 2; ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); @@ -638,41 +688,39 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); /* Store third dataset region */ + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Store fourth dataset region */ + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + /* Write selection to disk */ H5E_BEGIN_TRY { - ret = H5Rcreate(&wbuf[2], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + ret = H5Dwrite(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); } H5E_END_TRY; if(libver_high < H5F_LIBVER_V110) - VERIFY(ret, FAIL, "H5Rcreate"); + VERIFY(ret, FAIL, "H5Dwrite"); else - CHECK(ret, FAIL, "H5Rcreate"); - - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); - - /* Write selection to disk */ - ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); - CHECK(ret, FAIL, "H5Dwrite"); + CHECK(ret, FAIL, "H5Dwrite"); /* * Store a dataset region reference which will not get written to disk */ - /* Create reference to an element in dset1 */ - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); - CHECK(ret, FAIL, "H5Sselect_elements"); - ret = H5Rcreate(&wdata_NA[0], fid1, "/Dataset1", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); - /* Create the dataspace of the region references */ space_NA = H5Screate_simple(1, dims_NA, NULL); - CHECK(space_NA, FAIL, "H5Screate_simple"); + CHECK(space_NA, H5I_INVALID_HID, "H5Screate_simple"); /* Create the dataset and write the region references to it */ - dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF_DSETREG, space_NA, H5P_DEFAULT, + dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF, space_NA, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset_NA, FAIL, "H5Dcreate"); + CHECK(dset_NA, H5I_INVALID_HID, "H5Dcreate"); /* Close and release resources for undefined region reference tests */ ret = H5Dclose(dset_NA); @@ -697,8 +745,8 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_REG, H5F_ACC_RDWR, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* * Start the test of an undefined reference @@ -706,25 +754,25 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Open the dataset of the undefined references */ dset_NA = H5Dopen2(fid1, "DS_NA", H5P_DEFAULT); - CHECK(dset_NA, FAIL, "H5Dopen2"); + CHECK(dset_NA, H5I_INVALID_HID, "H5Dopen2"); /* Read the data */ - ret = H5Dread(dset_NA, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); + ret = H5Dread(dset_NA, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); CHECK(ret, FAIL, "H5Dread"); /* * Dereference an undefined reference (should fail) */ H5E_BEGIN_TRY { - dset2 = H5Rdereference2(dset_NA, H5P_DEFAULT, H5R_DATASET_REGION, &rdata_NA[0]); + dset2 = H5Ropen_object((const H5R_ref_t *)&rdata_NA[0], H5P_DEFAULT, H5P_DEFAULT); } H5E_END_TRY; - VERIFY(dset2, FAIL, "H5Rdereference2"); + VERIFY(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Close and release resources. */ ret = H5Dclose(dset_NA); CHECK(ret, FAIL, "H5Dclose"); - /* This close should fail since H5Rdereference2 never created + /* This close should fail since H5Ropen_object never created * the id of the referenced object. */ H5E_BEGIN_TRY { ret = H5Dclose(dset2); @@ -737,115 +785,116 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Open the dataset */ dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dopen2"); + CHECK(dset1, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); - CHECK(ret, FAIL, "H5Dread"); - - /* Try to read an unaddressed dataset */ - dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, undef_reg); - VERIFY(dset2, FAIL, "H5Rdereference2 haddr_undef"); + H5E_BEGIN_TRY { + ret = H5Dread(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + } H5E_END_TRY; - /* Try to open objects */ - dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); - CHECK(dset2, FAIL, "H5Rdereference2"); + if(libver_high < H5F_LIBVER_V110) + VERIFY(ret, FAIL, "H5Dread"); + else { + CHECK(ret, FAIL, "H5Dread"); - /* Check what H5Rget_obj_type2 function returns */ - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + /* Try to open objects */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); - /* Check information in referenced dataset */ - sid1 = H5Dget_space(dset2); - CHECK(sid1, FAIL, "H5Dget_space"); + /* Check what H5Rget_obj_type3 function returns */ + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); - /* Read from disk */ - ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); - CHECK(ret, FAIL, "H5Dread"); + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, (SPACE2_DIM1 * SPACE2_DIM2), "H5Sget_simple_extent_npoints"); - for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) - VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + /* Read from disk */ + ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); - /* Get the hyperslab selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); - CHECK(sid2, FAIL, "H5Rget_region"); + for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); - /* Verify correct hyperslab selected */ - ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 36, "H5Sget_select_npoints"); - ret = (int)H5Sget_select_hyper_nblocks(sid2); - VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); - coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ - ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); - CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); - VERIFY(coords[0], 2, "Hyperslab Coordinates"); - VERIFY(coords[1], 2, "Hyperslab Coordinates"); - VERIFY(coords[2], 7, "Hyperslab Coordinates"); - VERIFY(coords[3], 7, "Hyperslab Coordinates"); - HDfree(coords); - ret = H5Sget_select_bounds(sid2, low, high); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low[0], 2, "Selection Bounds"); - VERIFY(low[1], 2, "Selection Bounds"); - VERIFY(high[0], 7, "Selection Bounds"); - VERIFY(high[1], 7, "Selection Bounds"); + /* Get the hyperslab selection */ + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); - /* Close region space */ - ret = H5Sclose(sid2); - CHECK(ret, FAIL, "H5Sclose"); + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid2); + VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 2, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 7, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(low[1], 2, "Selection Bounds"); + VERIFY(high[0], 7, "Selection Bounds"); + VERIFY(high[1], 7, "Selection Bounds"); - /* Get the element selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); - CHECK(sid2, FAIL, "H5Rget_region"); + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); - /* Verify correct elements selected */ - ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_npoints"); - ret = (int)H5Sget_select_elem_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_elem_npoints"); - coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ - ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); - CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); - VERIFY(coords[0], coord1[0][0], "Element Coordinates"); - VERIFY(coords[1], coord1[0][1], "Element Coordinates"); - VERIFY(coords[2], coord1[1][0], "Element Coordinates"); - VERIFY(coords[3], coord1[1][1], "Element Coordinates"); - VERIFY(coords[4], coord1[2][0], "Element Coordinates"); - VERIFY(coords[5], coord1[2][1], "Element Coordinates"); - VERIFY(coords[6], coord1[3][0], "Element Coordinates"); - VERIFY(coords[7], coord1[3][1], "Element Coordinates"); - VERIFY(coords[8], coord1[4][0], "Element Coordinates"); - VERIFY(coords[9], coord1[4][1], "Element Coordinates"); - VERIFY(coords[10], coord1[5][0], "Element Coordinates"); - VERIFY(coords[11], coord1[5][1], "Element Coordinates"); - VERIFY(coords[12], coord1[6][0], "Element Coordinates"); - VERIFY(coords[13], coord1[6][1], "Element Coordinates"); - VERIFY(coords[14], coord1[7][0], "Element Coordinates"); - VERIFY(coords[15], coord1[7][1], "Element Coordinates"); - VERIFY(coords[16], coord1[8][0], "Element Coordinates"); - VERIFY(coords[17], coord1[8][1], "Element Coordinates"); - VERIFY(coords[18], coord1[9][0], "Element Coordinates"); - VERIFY(coords[19], coord1[9][1], "Element Coordinates"); - HDfree(coords); - ret = H5Sget_select_bounds(sid2, low, high); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low[0], 0, "Selection Bounds"); - VERIFY(low[1], 0, "Selection Bounds"); - VERIFY(high[0], 9, "Selection Bounds"); - VERIFY(high[1], 9, "Selection Bounds"); + /* Get the element selection */ + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid2); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[0][1], "Element Coordinates"); + VERIFY(coords[2], coord1[1][0], "Element Coordinates"); + VERIFY(coords[3], coord1[1][1], "Element Coordinates"); + VERIFY(coords[4], coord1[2][0], "Element Coordinates"); + VERIFY(coords[5], coord1[2][1], "Element Coordinates"); + VERIFY(coords[6], coord1[3][0], "Element Coordinates"); + VERIFY(coords[7], coord1[3][1], "Element Coordinates"); + VERIFY(coords[8], coord1[4][0], "Element Coordinates"); + VERIFY(coords[9], coord1[4][1], "Element Coordinates"); + VERIFY(coords[10], coord1[5][0], "Element Coordinates"); + VERIFY(coords[11], coord1[5][1], "Element Coordinates"); + VERIFY(coords[12], coord1[6][0], "Element Coordinates"); + VERIFY(coords[13], coord1[6][1], "Element Coordinates"); + VERIFY(coords[14], coord1[7][0], "Element Coordinates"); + VERIFY(coords[15], coord1[7][1], "Element Coordinates"); + VERIFY(coords[16], coord1[8][0], "Element Coordinates"); + VERIFY(coords[17], coord1[8][1], "Element Coordinates"); + VERIFY(coords[18], coord1[9][0], "Element Coordinates"); + VERIFY(coords[19], coord1[9][1], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 0, "Selection Bounds"); + VERIFY(low[1], 0, "Selection Bounds"); + VERIFY(high[0], 9, "Selection Bounds"); + VERIFY(high[1], 9, "Selection Bounds"); - /* Close region space */ - ret = H5Sclose(sid2); - CHECK(ret, FAIL, "H5Sclose"); + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); - if(libver_high >= H5F_LIBVER_V110) { /* Get the unlimited selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[2]); - CHECK(sid2, FAIL, "H5Rget_region"); + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct hyperslab selected */ hssize_ret = H5Sget_select_npoints(sid2); @@ -867,23 +916,23 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Close region space */ ret = H5Sclose(sid2); CHECK(ret, FAIL, "H5Sclose"); - } - - /* Close first space */ - ret = H5Sclose(sid1); - CHECK(ret, FAIL, "H5Sclose"); - /* Close dereferenced Dataset */ - ret = H5Dclose(dset2); - CHECK(ret, FAIL, "H5Dclose"); + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); - /* Attempting to retrieve type of object using non-valid refs */ - for(j = 0; j < 3; j++) { - H5E_BEGIN_TRY { - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &nvrbuf[j], &obj_type); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Rget_obj_type2"); - } /* end for */ + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type3((const H5R_ref_t *)&nvrbuf[j], H5P_DEFAULT, &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type3"); + } /* end for */ + } /* Close Dataset */ ret = H5Dclose(dset1); @@ -897,6 +946,16 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(j = 0; j < SPACE1_DIM1; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + if(libver_high >= H5F_LIBVER_V110) { + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -917,14 +976,14 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) static void test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) { - hid_t fid1; /* HDF5 File IDs */ - hid_t fapl = -1; /* File access property list */ - hid_t dset1, /* Dataset ID */ - dset3; /* Dereferenced dataset ID */ - hid_t sid1, /* Dataspace ID #1 */ - sid3; /* Dataspace ID #3 */ - hid_t dapl_id; /* Dataset access property list */ - hsize_t dims1[] = {SPACE1_DIM1}, + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset3; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid3; /* Dataspace ID #3 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {2}, /* Must be 2 */ dims3[] = {SPACE3_DIM1}; hsize_t start[SPACE3_RANK]; /* Starting location of hyperslab */ hsize_t stride[SPACE3_RANK]; /* Stride of hyperslab */ @@ -934,50 +993,50 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t *coords; /* Coordinate buffer */ hsize_t low[SPACE3_RANK]; /* Selection bounds */ hsize_t high[SPACE3_RANK]; /* Selection bounds */ - hdset_reg_ref_t *wbuf, /* buffer to write to disk */ - *rbuf; /* buffer read from disk */ - uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ - *drbuf; /* Buffer for reading numeric data from disk */ - uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ H5O_type_t obj_type; /* Object type */ - int i; /* counting variables */ - herr_t ret; /* Generic return value */ + int i; /* Counter */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing 1-D Dataset Region Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); - rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); - dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE3_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), (size_t)SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), (size_t)SPACE1_DIM1); + dwbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); + for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) + *tu8++ = (uint8_t)(i * 3); + /* Create the file access property list */ fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); /* Set the low/high version bounds in fapl */ ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create file with the fapl */ - fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_REG_1D, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid3 = H5Screate_simple(SPACE3_RANK, dims3, NULL); - CHECK(sid3, FAIL, "H5Screate_simple"); + CHECK(sid3, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a dataset */ dset3 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset3, FAIL, "H5Dcreate2"); - - for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) - *tu8++ = (uint8_t)(i * 3); + CHECK(dset3, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); @@ -989,31 +1048,31 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Create dataspace for the reference dataset */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset */ - dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dcreate2"); /* Create references */ /* Select 15 2x1 hyperslabs for first reference */ - start[0] = 2; + start[0] = 2; stride[0] = 5; - count[0] = 15; - block[0] = 2; + count[0] = 15; + block[0] = 2; ret = H5Sselect_hyperslab(sid3, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); ret = (int)H5Sget_select_npoints(sid3); - VERIFY(ret, 30, "H5Sget_select_npoints"); + VERIFY(ret, (block[0] * count[0]), "H5Sget_select_npoints"); /* Store first dataset region */ - ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid3, &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Select sequence of ten points for second reference */ coord1[0][0] = 16; @@ -1030,14 +1089,14 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid3); - VERIFY(ret, 10, "H5Sget_select_npoints"); + VERIFY(ret, POINT1_NPOINTS, "H5Sget_select_npoints"); /* Store second dataset region */ - ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid3, &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_region"); /* Write selection to disk */ - ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + ret = H5Dwrite(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); /* Close disk dataspace */ @@ -1057,32 +1116,32 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_REG_1D, H5F_ACC_RDWR, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dopen2"); + CHECK(dset1, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + ret = H5Dread(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); /* Try to open objects */ - dset3 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); - CHECK(dset3, FAIL, "H5Rdereference2"); + dset3 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset3, H5I_INVALID_HID, "H5Ropen_object"); - /* Check what H5Rget_obj_type2 function returns */ - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + /* Check what H5Rget_obj_type3 function returns */ + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset3); - CHECK(sid1, FAIL, "H5Dget_space"); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + VERIFY(ret, SPACE3_DIM1, "H5Sget_simple_extent_npoints"); /* Read from disk */ ret = H5Dread(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); @@ -1092,8 +1151,8 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(*tu8, (uint8_t)(i * 3), "Data"); /* Get the hyperslab selection */ - sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); - CHECK(sid3, FAIL, "H5Rget_region"); + sid3 = H5Ropen_region((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid3, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct hyperslab selected */ ret = (int)H5Sget_select_npoints(sid3); @@ -1144,8 +1203,8 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sclose"); /* Get the element selection */ - sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); - CHECK(sid3, FAIL, "H5Rget_region"); + sid3 = H5Ropen_region((const H5R_ref_t *)&rbuf[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid3, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct elements selected */ ret = (int)H5Sget_select_npoints(sid3); @@ -1199,6 +1258,14 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(i = 0; i < 2; i++) { + ret = H5Rdestroy(&wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -1215,44 +1282,43 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) static void test_reference_obj_deleted(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t sid1; /* Dataspace ID */ - hobj_ref_t oref; /* Object Reference to test */ - H5O_type_t obj_type; /* Object type */ - haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ - herr_t ret; /* Generic return value */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID */ + H5R_ref_t oref; /* Object Reference to test */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ /* Create file */ - fid1 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_OBJ_DEL, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create scalar dataspace for datasets */ sid1 = H5Screate_simple(0, NULL, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset to reference (deleted later) */ dataset = H5Dcreate2(fid1, "Dataset1", H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to dataset */ - ret = H5Rcreate(&oref, fid1, "/Dataset1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &oref, &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Dataset1", &oref); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&oref, H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Write selection to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); CHECK(ret, FAIL, "H5Dwrite"); /* Close Dataset */ @@ -1271,31 +1337,25 @@ test_reference_obj_deleted(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy reference */ + ret = H5Rdestroy(&oref); + CHECK(ret, FAIL, "H5Rdestroy"); + /* Re-open the file */ - fid1 = H5Fopen(FILE3, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_OBJ_DEL, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dataset = H5Dopen2(fid1, "/Dataset2", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); - - /* Open undefined reference */ - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &addr); - VERIFY(dset2, FAIL, "H5Rdereference2"); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - HDmemset(&oref, 0, sizeof(hobj_ref_t)); - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); CHECK(ret, FAIL, "H5Dread"); /* Open deleted dataset object */ - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); - VERIFY(dset2, FAIL, "H5Rdereference2"); - - /* Open nonsense reference */ - HDmemset(&oref, 0, sizeof(hobj_ref_t)); - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); - VERIFY(dset2, FAIL, "H5Rdereference2"); + dset2 = H5Ropen_object((const H5R_ref_t *)&oref, H5P_DEFAULT, H5P_DEFAULT); + VERIFY(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1304,6 +1364,10 @@ test_reference_obj_deleted(void) /* Close file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy reference */ + ret = H5Rdestroy(&oref); + CHECK(ret, FAIL, "H5Rdestroy"); } /* test_reference_obj_deleted() */ /**************************************************************** @@ -1359,8 +1423,8 @@ test_reference_group(void) hid_t gid = -1, gid2 = -1; /* Group IDs */ hid_t did; /* Dataset ID */ hid_t sid; /* Dataspace ID */ - hobj_ref_t wref; /* Reference to write */ - hobj_ref_t rref; /* Reference to read */ + H5R_ref_t wref; /* Reference to write */ + H5R_ref_t rref; /* Reference to read */ H5G_info_t ginfo; /* Group info struct */ char objname[NAME_SIZE]; /* Buffer to store name */ H5O_info_t oinfo; /* Object info struct */ @@ -1369,47 +1433,47 @@ test_reference_group(void) herr_t ret; /* Create file with a group and a dataset containing an object reference to the group */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); + fid = H5Fcreate(FILE_REF_GRP, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace to use for dataset */ sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); + CHECK(sid, H5I_INVALID_HID, "H5Screate"); /* Create group to refer to */ gid = H5Gcreate2(fid, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid, FAIL, "H5Gcreate2"); + CHECK(gid, H5I_INVALID_HID, "H5Gcreate2"); /* Create nested groups */ gid2 = H5Gcreate2(gid, GROUPNAME2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid2, FAIL, "H5Gcreate2"); + CHECK(gid2, H5I_INVALID_HID, "H5Gcreate2"); ret = H5Gclose(gid2); CHECK(ret, FAIL, "H5Gclose"); gid2 = H5Gcreate2(gid, GROUPNAME3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid2, FAIL, "H5Gcreate2"); + CHECK(gid2, H5I_INVALID_HID, "H5Gcreate2"); ret = H5Gclose(gid2); CHECK(ret, FAIL, "H5Gclose"); /* Create bottom dataset */ did = H5Dcreate2(gid, DSETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - assert(did > 0); + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); ret = H5Dclose(did); - assert(ret >= 0); + CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(gid); CHECK(ret, FAIL, "H5Gclose"); /* Create dataset */ - did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF_OBJ, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dcreate2"); + did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to group */ - ret = H5Rcreate(&wref, fid, GROUPNAME, H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_object(fid, GROUPNAME, &wref); + CHECK(ret, FAIL, "H5Rcreate_object"); /* Write reference to disk */ - ret = H5Dwrite(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); + ret = H5Dwrite(did, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); CHECK(ret, FAIL, "H5Dwrite"); /* Close objects */ @@ -1420,22 +1484,25 @@ test_reference_group(void) ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy reference */ + ret = H5Rdestroy(&wref); + CHECK(ret, FAIL, "H5Rdestroy"); /* Re-open file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); + fid = H5Fopen(FILE_REF_GRP, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fopen"); /* Re-open dataset */ did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dopen2"); + CHECK(did, H5I_INVALID_HID, "H5Dopen2"); /* Read in the reference */ - ret = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); + ret = H5Dread(did, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); CHECK(ret, FAIL, "H5Dread"); /* Dereference to get the group */ - gid = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &rref); - CHECK(gid, FAIL, "H5Rdereference2"); + gid = H5Ropen_object((const H5R_ref_t *)&rref, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, H5I_INVALID_HID, "H5Ropen_object"); /* Iterate through objects in dereferenced group */ ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); @@ -1447,7 +1514,7 @@ test_reference_group(void) VERIFY(ginfo.nlinks, 3, "H5Gget_info"); size = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, objname, (size_t)NAME_SIZE, H5P_DEFAULT); - CHECK(size, FAIL, "H5Lget_name_by_idx"); + CHECK(size, (-1), "H5Lget_name_by_idx"); VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); @@ -1469,240 +1536,794 @@ test_reference_group(void) CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy reference */ + ret = H5Rdestroy(&rref); + CHECK(ret, FAIL, "H5Rdestroy"); } /* test_reference_group() */ -#ifndef H5_NO_DEPRECATED_SYMBOLS /**************************************************************** ** -** test_reference_compat(): Test basic H5R (reference) object reference code. -** Tests deprecated API routines +** test_reference_attr(): Test basic H5R (reference) attribute reference code. +** Tests references to attributes on various kinds of objects ** ****************************************************************/ static void -test_reference_compat(void) +test_reference_attr(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, dset2; /* Dataset ID */ - hid_t group, group2; /* Group ID */ - hid_t sid1, /* Dataspace IDs */ - sid2; - hid_t tid1, tid2; /* Datatype ID */ - hsize_t dims1[] = {SPACE1_DIM1}, - dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; - hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ - hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ - hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ - hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ - hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ - hobj_ref_t *wbuf_obj, /* Buffer to write to disk */ - *rbuf_obj; /* Buffer read from disk */ - hdset_reg_ref_t *wbuf_reg, /* Buffer to write to disk */ - *rbuf_reg; /* Buffer read from disk */ - H5G_obj_t obj_type; /* Object type */ - herr_t ret; /* Generic return value */ + hid_t fid; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t ref_wbuf[SPACE1_DIM1], /* Buffer to write to disk */ + ref_rbuf[SPACE1_DIM1]; /* Buffer read from disk */ + unsigned wbuf[SPACE1_DIM1], rbuf[SPACE1_DIM1]; + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* Local index variables */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ - MESSAGE(5, ("Testing Deprecated Object Reference Functions\n")); - - /* Allocate write & read buffers */ - wbuf_obj = (hobj_ref_t *)HDcalloc(sizeof(hobj_ref_t), SPACE1_DIM1); - rbuf_obj = (hobj_ref_t *)HDmalloc(sizeof(hobj_ref_t) * SPACE1_DIM1); - wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), SPACE1_DIM1); - rbuf_reg = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + MESSAGE(5, ("Testing Attribute Reference Functions\n")); /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid = H5Fcreate(FILE_REF_ATTR, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ - sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); - /* Create another dataspace for datasets */ - sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); - CHECK(sid2, FAIL, "H5Screate_simple"); + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a group */ - group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); + group = H5Gcreate2(fid, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(group, "Attr2", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 1); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); /* Create a dataset (inside Group1) */ - dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)(i * 3); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Create another dataset (inside Group1) */ - dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Create a datatype to refer to */ - tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ - ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + ret = H5Tinsert(tid, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); - ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + ret = H5Tinsert(tid, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); CHECK(ret, FAIL, "H5Tinsert"); - ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + ret = H5Tinsert(tid, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); CHECK(ret, FAIL, "H5Tinsert"); /* Save datatype for later */ - ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + ret = H5Tcommit2(group, "Datatype1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tcommit2"); + /* Create an attribute for the datatype */ + attr = H5Acreate2(tid, "Attr3", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 2); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + /* Close datatype */ - ret = H5Tclose(tid1); + ret = H5Tclose(tid); CHECK(ret, FAIL, "H5Tclose"); /* Close group */ ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); + /* Create a dataset */ + dataset = H5Dcreate2(fid, "Dataset3", H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create reference to dataset1 attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Dataset1", "Attr1", &ref_wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to dataset2 attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Dataset2", "Attr1", &ref_wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to group attribute */ + ret = H5Rcreate_attr(fid, "/Group1", "Attr2", &ref_wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); + + /* Create reference to named datatype attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Datatype1", "Attr3", &ref_wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); - /* Create a dataset with object reference datatype */ - dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); - - /* Create reference to dataset */ - ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - - /* Create reference to dataset */ - ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - - /* Create reference to group */ - ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - - /* Create reference to named datatype */ - ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - - /* Write references to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_obj); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_wbuf); CHECK(ret, FAIL, "H5Dwrite"); + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); - /* Create a dataset with region reference datatype */ - dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + /* Re-open the file */ + fid = H5Fopen(FILE_REF_ATTR, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); - /* Select 6x6 hyperslab for first reference */ - start[0] = 2; start[1] = 2; - stride[0] = 1; stride[1] = 1; - count[0] = 1; count[1] = 1; - block[0] = 6; block[1] = 6; - ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); + /* Open the dataset */ + dataset = H5Dopen2(fid, "/Dataset3", H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); - /* Create first dataset region */ - ret = H5Rcreate(&wbuf_reg[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_rbuf); + CHECK(ret, FAIL, "H5Dread"); - /* Select sequence of ten points for second reference */ - coord1[0][0] = 6; coord1[0][1] = 9; - coord1[1][0] = 2; coord1[1][1] = 2; - coord1[2][0] = 8; coord1[2][1] = 4; - coord1[3][0] = 1; coord1[3][1] = 6; - coord1[4][0] = 2; coord1[4][1] = 8; - coord1[5][0] = 3; coord1[5][1] = 2; - coord1[6][0] = 0; coord1[6][1] = 4; - coord1[7][0] = 9; coord1[7][1] = 0; - coord1[8][0] = 7; coord1[8][1] = 1; - coord1[9][0] = 3; coord1[9][1] = 3; - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); - CHECK(ret, FAIL, "H5Sselect_elements"); + /* Open attribute on dataset object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); - /* Create second dataset region */ - ret = H5Rcreate(&wbuf_reg[1], fid1, "/Group1/Dataset2", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); + /* Check information in referenced dataset */ + sid = H5Aget_space(attr); + CHECK(sid, H5I_INVALID_HID, "H5Aget_space"); - /* Write selection to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); - CHECK(ret, FAIL, "H5Dwrite"); + ret = (int)H5Sget_simple_extent_npoints(sid); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); - /* Close Dataset */ - ret = H5Dclose(dataset); - CHECK(ret, FAIL, "H5Dclose"); + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i * 3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on group object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 1), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on named datatype object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 2), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + for (i = 0; i < SPACE1_DIM1; i++) { + ret = H5Rdestroy(&ref_wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&ref_rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } +} /* test_reference_attr() */ + +/**************************************************************** +** +** test_reference_external(): +** Tests external references on various kinds of objects +** +****************************************************************/ +static void +test_reference_external(void) +{ + hid_t fid1, fid2; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t ref_wbuf[SPACE1_DIM1], /* Buffer to write to disk */ + ref_rbuf[SPACE1_DIM1]; /* Buffer read from disk */ + unsigned wbuf[SPACE1_DIM1], rbuf[SPACE1_DIM1]; + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* Local index variables */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing External References Functions\n")); + + /* Create file */ + fid1 = H5Fcreate(FILE_REF_EXT1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(group, "Attr2", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 1); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)(i * 3); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Create an attribute for the datatype */ + attr = H5Acreate2(tid, "Attr3", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 2); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create reference to dataset1 attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset1", "Attr1", &ref_wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to dataset2 attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", "Attr1", &ref_wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to group attribute */ + ret = H5Rcreate_attr(fid1, "/Group1", "Attr2", &ref_wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); + + /* Create reference to named datatype attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Datatype1", "Attr3", &ref_wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create file */ + fid2 = H5Fcreate(FILE_REF_EXT2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid2, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid2, "Dataset3", H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + /* Re-open the file */ + fid2 = H5Fopen(FILE_REF_EXT2, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid2, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid2, "/Dataset3", H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open attribute on dataset object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Check information in referenced dataset */ + sid = H5Aget_space(attr); + CHECK(sid, H5I_INVALID_HID, "H5Aget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i * 3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on group object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 1), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on named datatype object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 2), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + for (i = 0; i < SPACE1_DIM1; i++) { + ret = H5Rdestroy(&ref_wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&ref_rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } +} /* test_reference_external() */ + +/**************************************************************** +** +** test_reference_compat_conv(): Test basic H5R (reference) object reference code. +** Tests deprecated API routines and type conversion. +** +****************************************************************/ +static void +test_reference_compat_conv(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, dset2; /* Dataset ID */ + hid_t group, group2; /* Group ID */ + hid_t sid1, sid2, sid3; /* Dataspace IDs */ + hid_t tid1, tid2; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}, + dims3[] = {2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK];/* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hobj_ref_t *wbuf_obj; /* Buffer to write to disk */ + H5R_ref_t *rbuf_obj; /* Buffer read from disk */ + hdset_reg_ref_t *wbuf_reg; /* Buffer to write to disk */ + H5R_ref_t *rbuf_reg; /* Buffer read from disk */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + unsigned int i; /* Counter */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated Object Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf_obj = (hobj_ref_t *)HDcalloc(sizeof(hobj_ref_t), SPACE1_DIM1); + rbuf_obj = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), 2); + rbuf_reg = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), 2); + + /* Create file */ + fid1 = H5Fcreate(FILE_REF_COMPAT, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create another dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + CHECK(sid2, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create another dataspace for datasets */ + sid3 = H5Screate_simple(SPACE1_RANK, dims3, NULL); + CHECK(sid3, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset with object reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to group */ + ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to named datatype */ + ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write references to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_obj); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset with region reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; + start[1] = 2; + stride[0] = 1; + stride[1] = 1; + count[0] = 1; + count[1] = 1; + block[0] = 6; + block[1] = 6; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Create first dataset region */ + ret = H5Rcreate(&wbuf_reg[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 6; coord1[0][1] = 9; + coord1[1][0] = 2; coord1[1][1] = 2; + coord1[2][0] = 8; coord1[2][1] = 4; + coord1[3][0] = 1; coord1[3][1] = 6; + coord1[4][0] = 2; coord1[4][1] = 8; + coord1[5][0] = 3; coord1[5][1] = 2; + coord1[6][0] = 0; coord1[6][1] = 4; + coord1[7][0] = 9; coord1[7][1] = 0; + coord1[8][0] = 7; coord1[8][1] = 1; + coord1[9][0] = 3; coord1[9][1] = 3; + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Create second dataset region */ + ret = H5Rcreate(&wbuf_reg[1], fid1, "/Group1/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); /* Close disk dataspaces */ ret = H5Sclose(sid1); CHECK(ret, FAIL, "H5Sclose"); ret = H5Sclose(sid2); CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); /* Close file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); - /* Re-open the file */ - fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + fid1 = H5Fopen(FILE_REF_COMPAT, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fopen"); /* Open the object reference dataset */ dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(dataset, FAIL, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); CHECK(ret, FAIL, "H5Dread"); /* Verify type of objects pointed at */ - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[0]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[1]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[2]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_GROUP, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[3]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_TYPE, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); /* Make sure the referenced objects can be opened */ - dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[0]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[1]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - group2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[2]); - CHECK(group2, FAIL, "H5Rdereference1"); + group2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(group2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Gclose(group2); CHECK(ret, FAIL, "H5Gclose"); - tid2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[3]); - CHECK(tid2, FAIL, "H5Rdereference1"); + tid2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(tid2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Tclose(tid2); CHECK(ret, FAIL, "H5Tclose"); @@ -1714,36 +2335,30 @@ test_reference_compat(void) /* Open the dataset region reference dataset */ dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); CHECK(ret, FAIL, "H5Dread"); /* Verify type of objects pointed at */ - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); - - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); - - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[2]); - VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_reg[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[3]); - VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_reg[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Make sure the referenced objects can be opened */ - dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_reg[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_reg[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); @@ -1756,13 +2371,424 @@ test_reference_compat(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(i = 0; i < dims1[0]; i++) { + ret = H5Rdestroy(&rbuf_obj[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + for(i = 0; i < dims3[0]; i++) { + ret = H5Rdestroy(&rbuf_reg[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf_obj); HDfree(rbuf_obj); HDfree(wbuf_reg); HDfree(rbuf_reg); } /* test_reference_compat() */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/**************************************************************** +** +** test_reference_perf(): Test basic H5R (reference) object reference +** performance. +** +****************************************************************/ +static void +test_reference_perf(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + H5R_ref_t *wbuf_reg, /* buffer to write to disk */ + *rbuf_reg; /* buffer read from disk */ + hobj_ref_t *wbuf_deprec,/* deprecated references */ + *rbuf_deprec;/* deprecated references */ + hdset_reg_ref_t *wbuf_reg_deprec, /* deprecated references*/ + *rbuf_reg_deprec; /* deprecated references*/ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* Counters */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + double t1, t2, t; /* Timers */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Object Reference Performance\n")); + + /* Allocate write & read buffers */ + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_deprec = (hobj_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf_deprec = (hobj_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_reg = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf_reg = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_reg_deprec = (hdset_reg_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hdset_reg_ref_t)), SPACE1_DIM1); + rbuf_reg_deprec = (hdset_reg_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hdset_reg_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Create file */ + fid1 = H5Fcreate(FILE_REF_OBJ, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&wbuf[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Object reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Create reference to dataset */ + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Object reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + ret = H5Rcreate(&wbuf_deprec[0], fid1, "/Group1/Dataset1", H5R_OBJECT1, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_deprec[0], fid1, "/Group1/Dataset1", H5R_OBJECT1, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_deprec); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset5", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + /* Store first dataset region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, &wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Region reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Store first dataset region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, &wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Region reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset6", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + /* Store first dataset region */ + ret = H5Rcreate(&wbuf_reg_deprec[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION1, sid1); + CHECK(ret, FAIL, "H5Rcreate"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference create time: %lfs\n", t / MAX_ITER_CREATE); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg_deprec); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE_REF_OBJ, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&rbuf[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Object reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open dataset object */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, dims1[0], "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu32 = (unsigned *)tbuf, i = 0; i < (int)dims1[0]; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i*3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_deprec); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset5", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&rbuf_reg[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Region reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset6", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg_deprec); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy references */ + for(j = 0; j < (int)dims1[0]; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&wbuf_reg[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf_reg[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(wbuf_reg); + HDfree(rbuf_reg); + HDfree(wbuf_deprec); + HDfree(rbuf_deprec); + HDfree(wbuf_reg_deprec); + HDfree(rbuf_reg_deprec); + HDfree(tbuf); +} /* test_reference_perf() */ /**************************************************************** ** @@ -1794,11 +2820,13 @@ test_reference(void) } /* end high bound */ } /* end low bound */ - test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ - test_reference_group(); /* Test operations on dereferenced groups */ -#ifndef H5_NO_DEPRECATED_SYMBOLS - test_reference_compat(); /* Test operations with old API routines */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ + test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ + test_reference_group(); /* Test operations on dereferenced groups */ + test_reference_attr(); /* Test attribute references */ + test_reference_external(); /* Test external references */ + test_reference_compat_conv(); /* Test operations with old types */ + + test_reference_perf(); } /* test_reference() */ @@ -1820,8 +2848,14 @@ test_reference(void) void cleanup_reference(void) { - remove(FILE1); - remove(FILE2); - remove(FILE3); + HDremove(FILE_REF_PARAM); + HDremove(FILE_REF_OBJ); + HDremove(FILE_REF_REG); + HDremove(FILE_REF_REG_1D); + HDremove(FILE_REF_OBJ_DEL); + HDremove(FILE_REF_GRP); + HDremove(FILE_REF_ATTR); + HDremove(FILE_REF_EXT1); + HDremove(FILE_REF_EXT2); + HDremove(FILE_REF_COMPAT); } - diff --git a/test/trefer_deprec.c b/test/trefer_deprec.c new file mode 100644 index 0000000..949f41b --- /dev/null +++ b/test/trefer_deprec.c @@ -0,0 +1,1827 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*********************************************************** +* +* Test program: trefer_deprec +* +* Test the Reference functionality +* +*************************************************************/ + +#include "testhdf5.h" + +#define FILE1 "trefer1.h5" +#define FILE2 "trefer2.h5" +#define FILE3 "trefer3.h5" + +/* 1-D dataset with fixed dimensions */ +#define SPACE1_RANK 1 +#define SPACE1_DIM1 4 + +/* 2-D dataset with fixed dimensions */ +#define SPACE2_RANK 2 +#define SPACE2_DIM1 10 +#define SPACE2_DIM2 10 + +/* Larger 1-D dataset with fixed dimensions */ +#define SPACE3_RANK 1 +#define SPACE3_DIM1 100 + +/* Element selection information */ +#define POINT1_NPOINTS 10 + +/* Compound datatype */ +typedef struct s1_t { + unsigned int a; + unsigned int b; + float c; +} s1_t; + +#define GROUPNAME "/group" +#define GROUPNAME2 "group2" +#define GROUPNAME3 "group3" +#define DSETNAME "/dset" +#define DSETNAME2 "dset2" +#define NAME_SIZE 16 + + +/**************************************************************** +** +** test_reference_params(): Test basic H5R (reference) parameters +** for correct processing +** +****************************************************************/ +static void +test_reference_params(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}; + hobj_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* counting variables */ + const char *write_comment = "Foo!"; /* Comments for group */ + hid_t ret_id; /* Generic hid_t return value */ + ssize_t name_size; /* Size of reference name */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Reference Parameters\n")); + + /* Allocate write & read buffers */ + wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Set group's comment */ + ret = H5Oset_comment(group, write_comment); + CHECK(ret, FAIL, "H5Oset_comment"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dcreate2"); + + /* Test parameters to H5Rcreate */ + ret = H5Rcreate(NULL, fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate ref"); + ret = H5Rcreate(&wbuf[0], (hid_t)-1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate loc_id"); + ret = H5Rcreate(&wbuf[0], fid1, NULL, H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate name"); + ret = H5Rcreate(&wbuf[0], fid1, "", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate null name"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate type"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate region space"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)0); + VERIFY(ret, FAIL, "H5Rcreate space"); + + /* Test parameters to H5Rdereference */ + dset2 = H5Rdereference2((hid_t)-1, H5P_DEFAULT, H5R_OBJECT, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 loc_id"); + dset2 = H5Rdereference2(dataset, (hid_t)-1, H5R_OBJECT, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 oapl_id"); + dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, NULL); + VERIFY(dset2, FAIL, "H5Rdereference2 ref"); + dset2 = H5Rdereference2(dataset, dapl_id, H5R_MAXTYPE, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 type"); + + /* Test parameters to H5Rget_obj_type2 */ + ret = H5Rget_obj_type2((hid_t)-1, H5R_OBJECT, &rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 loc_id"); + ret = H5Rget_obj_type2(fid1, H5R_OBJECT, NULL, NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 ref"); + ret = H5Rget_obj_type2(fid1, H5R_MAXTYPE, &rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 type"); + + /* Test parameters to H5Rget_name */ + name_size = H5Rget_name((hid_t)-1, H5R_DATASET_REGION, &rbuf[0], NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name loc_id"); + name_size = H5Rget_name(fid1, H5R_DATASET_REGION, NULL, NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name ref"); + name_size = H5Rget_name(fid1, H5R_MAXTYPE, &rbuf[0], NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name type"); + + /* Test parameters to H5Rget_region */ + ret_id = H5Rget_region((hid_t)-1, H5R_OBJECT, &rbuf[0]); + VERIFY(ret_id, FAIL, "H5Rget_region loc_id"); + ret_id = H5Rget_region(fid1, H5R_OBJECT, NULL); + VERIFY(ret_id, FAIL, "H5Rget_region ref"); + ret_id = H5Rget_region(fid1, H5R_OBJECT, &rbuf[0]); + VERIFY(ret_id, FAIL, "H5Rget_region type"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(tbuf); +} /* test_reference_obj() */ + +/**************************************************************** +** +** test_reference_obj(): Test basic H5R (reference) object reference code. +** Tests references to various kinds of objects +** +****************************************************************/ +static void +test_reference_obj(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + hobj_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + hobj_ref_t nvrbuf[3]={0,101,1000000000}; /* buffer with non-valid refs */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* counting variables */ + const char *write_comment="Foo!"; /* Comments for group */ + char read_comment[10]; + H5O_type_t obj_type; /* Object type */ + ssize_t size; /* Comment length */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Object Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Set group's comment */ + ret = H5Oset_comment(group, write_comment); + CHECK(ret, FAIL, "H5Oset_comment"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[1], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Create reference to group */ + ret = H5Rcreate(&wbuf[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[2], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type2"); + + /* Create reference to named datatype */ + ret = H5Rcreate(&wbuf[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[3], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open dataset object */ + dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, &rbuf[0]); + CHECK(dset2, FAIL, "H5Rdereference2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 4, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu32 = (unsigned *)tbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i*3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open group object. GAPL isn't supported yet. But it's harmless to pass in */ + group = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[2]); + CHECK(group, FAIL, "H5Rdereference2"); + + /* Get group's comment */ + size = H5Oget_comment(group, read_comment, (size_t)10); + CHECK(size, FAIL, "H5Oget_comment"); + + /* Check for correct comment value */ + if(HDstrcmp(write_comment, read_comment) != 0) + TestErrPrintf("Error! Incorrect group comment, wanted: %s, got: %s\n",write_comment,read_comment); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Open datatype object. TAPL isn't supported yet. But it's harmless to pass in */ + tid1 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[3]); + CHECK(tid1, FAIL, "H5Rdereference2"); + + /* Verify correct datatype */ + { + H5T_class_t tclass; + + tclass = H5Tget_class(tid1); + VERIFY(tclass, H5T_COMPOUND, "H5Tget_class"); + + ret= H5Tget_nmembers(tid1); + VERIFY(ret, 3, "H5Tget_nmembers"); + } + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &nvrbuf[j], &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type2"); + } /* end for */ + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(tbuf); +} /* test_reference_obj() */ + +/**************************************************************** +** +** test_reference_region(): Test basic H5R (reference) object reference code. +** Tests references to various kinds of objects +** +** Note: The libver_low/libver_high parameters are added to create the file +** with the low and high bounds setting in fapl. +** Please see the RFC for "H5Sencode/H5Sdecode Format Change". +** +****************************************************************/ +static void +test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl = -1; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid2; /* Dataspace ID #2 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE2_RANK]; /* Selection bounds */ + hsize_t high[SPACE2_RANK]; /* Selection bounds */ + hdset_reg_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + hdset_reg_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Type of object */ + int i, j; /* counting variables */ + hssize_t hssize_ret; /* hssize_t return value */ + htri_t tri_ret; /* htri_t return value */ + herr_t ret; /* Generic return value */ + hdset_reg_ref_t undef_reg[1]; /* test for undefined reference */ + hid_t dset_NA; /* Dataset id for undefined reference */ + hid_t space_NA; /* Dataspace id for undefined reference */ + hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ + hdset_reg_ref_t wdata_NA[1], /* Write buffer */ + rdata_NA[1]; /* Read buffer */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Dataset Region Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); + rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE2_DIM1 * SPACE2_DIM2); + drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); + + /* Create file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Set the low/high version bounds in fapl */ + ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + + /* Create file with the fapl */ + fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + CHECK(sid2, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a dataset */ + dset2 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, FAIL, "H5Dcreate2"); + + for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) + *tu8++ = (uint8_t)(i * 3); + + /* Write selection to disk */ + ret = H5Dwrite(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create dataspace for the reference dataset */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset */ + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); + + /* Create references */ + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; start[1] = 2; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = 6; block[1] = 6; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + + /* Store first dataset region */ + ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 6; coord1[0][1] = 9; + coord1[1][0] = 2; coord1[1][1] = 2; + coord1[2][0] = 8; coord1[2][1] = 4; + coord1[3][0] = 1; coord1[3][1] = 6; + coord1[4][0] = 2; coord1[4][1] = 8; + coord1[5][0] = 3; coord1[5][1] = 2; + coord1[6][0] = 0; coord1[6][1] = 4; + coord1[7][0] = 9; coord1[7][1] = 0; + coord1[8][0] = 7; coord1[8][1] = 1; + coord1[9][0] = 3; coord1[9][1] = 3; + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_npoints"); + + /* Store second dataset region */ + ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Select unlimited hyperslab for third reference */ + start[0] = 1; start[1] = 8; + stride[0] = 4; stride[1] = 1; + count[0] = H5S_UNLIMITED; count[1] = 1; + block[0] = 2; block[1] = 2; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + + /* Store third dataset region */ + H5E_BEGIN_TRY { + ret = H5Rcreate(&wbuf[2], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + } H5E_END_TRY; + + if(libver_high < H5F_LIBVER_V110) + VERIFY(ret, FAIL, "H5Rcreate"); + else + CHECK(ret, FAIL, "H5Rcreate"); + + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* + * Store a dataset region reference which will not get written to disk + */ + + /* Create reference to an element in dset1 */ + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + ret = H5Rcreate(&wdata_NA[0], fid1, "/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create the dataspace of the region references */ + space_NA = H5Screate_simple(1, dims_NA, NULL); + CHECK(space_NA, FAIL, "H5Screate_simple"); + + /* Create the dataset and write the region references to it */ + dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF_DSETREG, space_NA, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dcreate"); + + /* Close and release resources for undefined region reference tests */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(space_NA); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close uint8 dataset dataspace */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); + CHECK(fid1, FAIL, "H5Fopen"); + + /* + * Start the test of an undefined reference + */ + + /* Open the dataset of the undefined references */ + dset_NA = H5Dopen2(fid1, "DS_NA", H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dopen2"); + + /* Read the data */ + ret = H5Dread(dset_NA, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); + CHECK(ret, FAIL, "H5Dread"); + + /* + * Dereference an undefined reference (should fail) + */ + H5E_BEGIN_TRY { + dset2 = H5Rdereference2(dset_NA, H5P_DEFAULT, H5R_DATASET_REGION, &rdata_NA[0]); + } H5E_END_TRY; + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Close and release resources. */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + + /* This close should fail since H5Rdereference2 never created + * the id of the referenced object. */ + H5E_BEGIN_TRY { + ret = H5Dclose(dset2); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dclose"); + + /* + * End the test of an undefined reference + */ + + /* Open the dataset */ + dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Try to read an unaddressed dataset */ + dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, undef_reg); + VERIFY(dset2, FAIL, "H5Rdereference2 haddr_undef"); + + /* Try to open objects */ + dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); + CHECK(dset2, FAIL, "H5Rdereference2"); + + /* Check what H5Rget_obj_type2 function returns */ + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + + /* Get the hyperslab selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid2); + VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 2, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 7, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(low[1], 2, "Selection Bounds"); + VERIFY(high[0], 7, "Selection Bounds"); + VERIFY(high[1], 7, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get the element selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[0][1], "Element Coordinates"); + VERIFY(coords[2], coord1[1][0], "Element Coordinates"); + VERIFY(coords[3], coord1[1][1], "Element Coordinates"); + VERIFY(coords[4], coord1[2][0], "Element Coordinates"); + VERIFY(coords[5], coord1[2][1], "Element Coordinates"); + VERIFY(coords[6], coord1[3][0], "Element Coordinates"); + VERIFY(coords[7], coord1[3][1], "Element Coordinates"); + VERIFY(coords[8], coord1[4][0], "Element Coordinates"); + VERIFY(coords[9], coord1[4][1], "Element Coordinates"); + VERIFY(coords[10], coord1[5][0], "Element Coordinates"); + VERIFY(coords[11], coord1[5][1], "Element Coordinates"); + VERIFY(coords[12], coord1[6][0], "Element Coordinates"); + VERIFY(coords[13], coord1[6][1], "Element Coordinates"); + VERIFY(coords[14], coord1[7][0], "Element Coordinates"); + VERIFY(coords[15], coord1[7][1], "Element Coordinates"); + VERIFY(coords[16], coord1[8][0], "Element Coordinates"); + VERIFY(coords[17], coord1[8][1], "Element Coordinates"); + VERIFY(coords[18], coord1[9][0], "Element Coordinates"); + VERIFY(coords[19], coord1[9][1], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 0, "Selection Bounds"); + VERIFY(low[1], 0, "Selection Bounds"); + VERIFY(high[0], 9, "Selection Bounds"); + VERIFY(high[1], 9, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + if(libver_high >= H5F_LIBVER_V110) { + /* Get the unlimited selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[2]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + tri_ret = H5Sis_regular_hyperslab(sid2); + CHECK(tri_ret, FAIL, "H5Sis_regular_hyperslab"); + VERIFY(tri_ret, TRUE, "H5Sis_regular_hyperslab Result"); + ret = H5Sget_regular_hyperslab(sid2, start, stride, count, block); + CHECK(ret, FAIL, "H5Sget_regular_hyperslab"); + VERIFY(start[0], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(start[1], (hsize_t)8, "Hyperslab Coordinates"); + VERIFY(stride[0], (hsize_t)4, "Hyperslab Coordinates"); + VERIFY(stride[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(count[0], H5S_UNLIMITED, "Hyperslab Coordinates"); + VERIFY(count[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(block[0], (hsize_t)2, "Hyperslab Coordinates"); + VERIFY(block[1], (hsize_t)2, "Hyperslab Coordinates"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + } + + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &nvrbuf[j], &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type2"); + } /* end for */ + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(dwbuf); + HDfree(drbuf); +} /* test_reference_region() */ + +/**************************************************************** +** +** test_reference_region_1D(): Test H5R (reference) object reference code. +** Tests 1-D references to various kinds of objects +** +** Note: The libver_low/libver_high parameters are added to create the file +** with the low and high bounds setting in fapl. +** Please see the RFC for "H5Sencode/H5Sdecode Format Change". +** +****************************************************************/ +static void +test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl = -1; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset3; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid3; /* Dataspace ID #3 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims3[] = {SPACE3_DIM1}; + hsize_t start[SPACE3_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE3_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE3_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE3_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE3_RANK]; /* Coordinates for point selection */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE3_RANK]; /* Selection bounds */ + hsize_t high[SPACE3_RANK]; /* Selection bounds */ + hdset_reg_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Object type */ + int i; /* counting variables */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing 1-D Dataset Region Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); + rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE3_DIM1); + drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); + + /* Create the file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Set the low/high version bounds in fapl */ + ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + + /* Create file with the fapl */ + fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid3 = H5Screate_simple(SPACE3_RANK, dims3, NULL); + CHECK(sid3, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a dataset */ + dset3 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset3, FAIL, "H5Dcreate2"); + + for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) + *tu8++ = (uint8_t)(i * 3); + + /* Write selection to disk */ + ret = H5Dwrite(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create dataspace for the reference dataset */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset */ + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dcreate2"); + + /* Create references */ + + /* Select 15 2x1 hyperslabs for first reference */ + start[0] = 2; + stride[0] = 5; + count[0] = 15; + block[0] = 2; + ret = H5Sselect_hyperslab(sid3, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 30, "H5Sget_select_npoints"); + + /* Store first dataset region */ + ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 16; + coord1[1][0] = 22; + coord1[2][0] = 38; + coord1[3][0] = 41; + coord1[4][0] = 52; + coord1[5][0] = 63; + coord1[6][0] = 70; + coord1[7][0] = 89; + coord1[8][0] = 97; + coord1[9][0] = 03; + ret = H5Sselect_elements(sid3, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_npoints"); + + /* Store second dataset region */ + ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write selection to disk */ + ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close uint8 dataset dataspace */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Try to open objects */ + dset3 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); + CHECK(dset3, FAIL, "H5Rdereference2"); + + /* Check what H5Rget_obj_type2 function returns */ + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset3); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu8 = (uint8_t *)drbuf, i = 0; i < SPACE3_DIM1; i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + + /* Get the hyperslab selection */ + sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); + CHECK(sid3, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 30, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid3); + VERIFY(ret, 15, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE3_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid3, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 3, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 8, "Hyperslab Coordinates"); + VERIFY(coords[4], 12, "Hyperslab Coordinates"); + VERIFY(coords[5], 13, "Hyperslab Coordinates"); + VERIFY(coords[6], 17, "Hyperslab Coordinates"); + VERIFY(coords[7], 18, "Hyperslab Coordinates"); + VERIFY(coords[8], 22, "Hyperslab Coordinates"); + VERIFY(coords[9], 23, "Hyperslab Coordinates"); + VERIFY(coords[10], 27, "Hyperslab Coordinates"); + VERIFY(coords[11], 28, "Hyperslab Coordinates"); + VERIFY(coords[12], 32, "Hyperslab Coordinates"); + VERIFY(coords[13], 33, "Hyperslab Coordinates"); + VERIFY(coords[14], 37, "Hyperslab Coordinates"); + VERIFY(coords[15], 38, "Hyperslab Coordinates"); + VERIFY(coords[16], 42, "Hyperslab Coordinates"); + VERIFY(coords[17], 43, "Hyperslab Coordinates"); + VERIFY(coords[18], 47, "Hyperslab Coordinates"); + VERIFY(coords[19], 48, "Hyperslab Coordinates"); + VERIFY(coords[20], 52, "Hyperslab Coordinates"); + VERIFY(coords[21], 53, "Hyperslab Coordinates"); + VERIFY(coords[22], 57, "Hyperslab Coordinates"); + VERIFY(coords[23], 58, "Hyperslab Coordinates"); + VERIFY(coords[24], 62, "Hyperslab Coordinates"); + VERIFY(coords[25], 63, "Hyperslab Coordinates"); + VERIFY(coords[26], 67, "Hyperslab Coordinates"); + VERIFY(coords[27], 68, "Hyperslab Coordinates"); + VERIFY(coords[28], 72, "Hyperslab Coordinates"); + VERIFY(coords[29], 73, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid3, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(high[0], 73, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get the element selection */ + sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); + CHECK(sid3, FAIL, "H5Rget_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE3_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid3, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[1][0], "Element Coordinates"); + VERIFY(coords[2], coord1[2][0], "Element Coordinates"); + VERIFY(coords[3], coord1[3][0], "Element Coordinates"); + VERIFY(coords[4], coord1[4][0], "Element Coordinates"); + VERIFY(coords[5], coord1[5][0], "Element Coordinates"); + VERIFY(coords[6], coord1[6][0], "Element Coordinates"); + VERIFY(coords[7], coord1[7][0], "Element Coordinates"); + VERIFY(coords[8], coord1[8][0], "Element Coordinates"); + VERIFY(coords[9], coord1[9][0], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid3, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 3, "Selection Bounds"); + VERIFY(high[0], 97, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(dwbuf); + HDfree(drbuf); +} /* test_reference_region_1D() */ + +/**************************************************************** +** +** test_reference_obj_deleted(): Test H5R (reference) object reference code. +** Tests for correct failures for deleted and non-existent objects +** +****************************************************************/ +static void +test_reference_obj_deleted(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID */ + hobj_ref_t oref; /* Object Reference to test */ + H5O_type_t obj_type; /* Object type */ + haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ + herr_t ret; /* Generic return value */ + + /* Create file */ + fid1 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create scalar dataspace for datasets */ + sid1 = H5Screate_simple(0, NULL, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset to reference (deleted later) */ + dataset = H5Dcreate2(fid1, "Dataset1", H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&oref, fid1, "/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &oref, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Delete referenced dataset */ + ret = H5Ldelete(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE3, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset2", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dopen2"); + + /* Open undefined reference */ + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &addr); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Read selection from disk */ + HDmemset(&oref, 0, sizeof(hobj_ref_t)); + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + CHECK(ret, FAIL, "H5Dread"); + + /* Open deleted dataset object */ + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Open nonsense reference */ + HDmemset(&oref, 0, sizeof(hobj_ref_t)); + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_reference_obj_deleted() */ + +/**************************************************************** +** +** test_deref_iter_op(): Iterator callback for test_reference_group_iterate() +** test. +** +****************************************************************/ +static herr_t +test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *info, + void *op_data) +{ + int *count = (int *)op_data; /* Pointer to name counter */ + herr_t ret_value; + + /* Simple check for correct names */ + if(*count == 0) { + if(HDstrcmp(name, DSETNAME2) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else if(*count == 1) { + if(HDstrcmp(name, GROUPNAME2) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else if(*count == 2) { + if(HDstrcmp(name, GROUPNAME3) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else + ret_value = -1; + + (*count)++; + + return(ret_value); +} /* end test_deref_iter_op() */ + +/**************************************************************** +** +** test_reference_group(): Test H5R (reference) object reference code. +** Tests for correct behavior of various routines on dereferenced group +** +****************************************************************/ +static void +test_reference_group(void) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + hid_t did; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hobj_ref_t wref; /* Reference to write */ + hobj_ref_t rref; /* Reference to read */ + H5G_info_t ginfo; /* Group info struct */ + char objname[NAME_SIZE]; /* Buffer to store name */ + H5O_info_t oinfo; /* Object info struct */ + int count = 0; /* Count within iterated group */ + ssize_t size; /* Name length */ + herr_t ret; + + /* Create file with a group and a dataset containing an object reference to the group */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataspace to use for dataset */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create group to refer to */ + gid = H5Gcreate2(fid, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Create nested groups */ + gid2 = H5Gcreate2(gid, GROUPNAME2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid2, FAIL, "H5Gcreate2"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + gid2 = H5Gcreate2(gid, GROUPNAME3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid2, FAIL, "H5Gcreate2"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create bottom dataset */ + did = H5Dcreate2(gid, DSETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + assert(did > 0); + ret = H5Dclose(did); + assert(ret >= 0); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create dataset */ + did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF_OBJ, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Create reference to group */ + ret = H5Rcreate(&wref, fid, GROUPNAME, H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write reference to disk */ + ret = H5Dwrite(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Re-open dataset */ + did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dopen2"); + + /* Read in the reference */ + ret = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); + CHECK(ret, FAIL, "H5Dread"); + + /* Dereference to get the group */ + gid = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &rref); + CHECK(gid, FAIL, "H5Rdereference2"); + + /* Iterate through objects in dereferenced group */ + ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); + CHECK(ret, FAIL, "H5Literate"); + + /* Various queries on the group opened */ + ret = H5Gget_info(gid, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + VERIFY(ginfo.nlinks, 3, "H5Gget_info"); + + size = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, objname, (size_t)NAME_SIZE, H5P_DEFAULT); + CHECK(size, FAIL, "H5Lget_name_by_idx"); + VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); + + ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx"); + VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx"); + + /* Unlink one of the objects in the dereferenced group */ + ret = H5Ldelete(gid, GROUPNAME2, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Delete dataset object in dereferenced group (with other dataset still open) */ + ret = H5Ldelete(gid, DSETNAME2, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_reference_group() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS +/**************************************************************** +** +** test_reference_compat(): Test basic H5R (reference) object reference code. +** Tests deprecated API routines +** +****************************************************************/ +static void +test_reference_compat(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, dset2; /* Dataset ID */ + hid_t group, group2; /* Group ID */ + hid_t sid1, /* Dataspace IDs */ + sid2; + hid_t tid1, tid2; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hobj_ref_t *wbuf_obj, /* Buffer to write to disk */ + *rbuf_obj; /* Buffer read from disk */ + hdset_reg_ref_t *wbuf_reg, /* Buffer to write to disk */ + *rbuf_reg; /* Buffer read from disk */ + H5G_obj_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated Object Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf_obj = (hobj_ref_t *)HDcalloc(sizeof(hobj_ref_t), SPACE1_DIM1); + rbuf_obj = (hobj_ref_t *)HDmalloc(sizeof(hobj_ref_t) * SPACE1_DIM1); + wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), SPACE1_DIM1); + rbuf_reg = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create another dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + CHECK(sid2, FAIL, "H5Screate_simple"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + + /* Create a dataset with object reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to group */ + ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to named datatype */ + ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write references to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_obj); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Create a dataset with region reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; start[1] = 2; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = 6; block[1] = 6; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Create first dataset region */ + ret = H5Rcreate(&wbuf_reg[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 6; coord1[0][1] = 9; + coord1[1][0] = 2; coord1[1][1] = 2; + coord1[2][0] = 8; coord1[2][1] = 4; + coord1[3][0] = 1; coord1[3][1] = 6; + coord1[4][0] = 2; coord1[4][1] = 8; + coord1[5][0] = 3; coord1[5][1] = 2; + coord1[6][0] = 0; coord1[6][1] = 4; + coord1[7][0] = 9; coord1[7][1] = 0; + coord1[8][0] = 7; coord1[8][1] = 1; + coord1[9][0] = 3; coord1[9][1] = 3; + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Create second dataset region */ + ret = H5Rcreate(&wbuf_reg[1], fid1, "/Group1/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Close disk dataspaces */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open the file */ + fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the object reference dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify type of objects pointed at */ + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[0]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[1]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[2]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_GROUP, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[3]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_TYPE, "H5Rget_obj_type1"); + + + /* Make sure the referenced objects can be opened */ + dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[0]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[1]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + group2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[2]); + CHECK(group2, FAIL, "H5Rdereference1"); + + ret = H5Gclose(group2); + CHECK(ret, FAIL, "H5Gclose"); + + tid2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[3]); + CHECK(tid2, FAIL, "H5Rdereference1"); + + ret = H5Tclose(tid2); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Open the dataset region reference dataset */ + dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify type of objects pointed at */ + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[2]); + VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[3]); + VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + + /* Make sure the referenced objects can be opened */ + dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf_obj); + HDfree(rbuf_obj); + HDfree(wbuf_reg); + HDfree(rbuf_reg); +} /* test_reference_compat() */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/**************************************************************** +** +** test_reference_deprec(): Main H5R reference testing routine. +** +****************************************************************/ +void +test_reference_deprec(void) +{ + H5F_libver_t low, high; /* Low and high bounds */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated References\n")); + + test_reference_params(); /* Test for correct parameter checking */ + test_reference_obj(); /* Test basic H5R object reference code */ + + /* Loop through all the combinations of low/high version bounds */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; H5_INC_ENUM(H5F_libver_t, low)) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; H5_INC_ENUM(H5F_libver_t, high)) { + + /* Invalid combinations, just continue */ + if(high == H5F_LIBVER_EARLIEST || high < low) + continue; + + test_reference_region(low, high); /* Test basic H5R dataset region reference code */ + test_reference_region_1D(low, high); /* Test H5R dataset region reference code for 1-D datasets */ + + } /* end high bound */ + } /* end low bound */ + + test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ + test_reference_group(); /* Test operations on dereferenced groups */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_reference_compat(); /* Test operations with old API routines */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +} /* test_reference() */ + + +/*------------------------------------------------------------------------- + * Function: cleanup_reference + * + * Purpose: Cleanup temporary test files + * + * Return: none + * + * Programmer: Quincey Koziol + * September 8, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +cleanup_reference_deprec(void) +{ + HDremove(FILE1); + HDremove(FILE2); + HDremove(FILE3); +} + -- cgit v0.12 From 383e7f78711f69909775e3210416b684a3ecb097 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Wed, 14 Aug 2019 11:41:53 -0500 Subject: Make wrappers, tests and tools use H5Treclaim() instead of H5Dvlen_reclaim() --- c++/src/H5DataSet.cpp | 8 +- c++/src/H5DxferProp.h | 4 +- fortran/src/H5Df.c | 16 ++-- hl/src/H5DS.c | 16 ++-- hl/src/H5PT.c | 2 +- src/H5Pdxpl.c | 4 +- test/dsets.c | 4 +- test/dtypes.c | 22 ++--- test/fillval.c | 16 ++-- test/genall5.c | 8 +- test/ntypes.c | 8 +- test/objcopy.c | 78 +++++++++--------- test/set_extent.c | 4 +- test/tarray.c | 20 ++--- test/tfile.c | 8 +- test/tmisc.c | 20 ++--- test/tunicode.c | 4 +- test/tvlstr.c | 18 ++--- test/tvltypes.c | 160 ++++++++++++++++++------------------- tools/lib/h5diff_attr.c | 8 +- tools/lib/h5diff_dset.c | 16 ++-- tools/lib/h5tools_dump.c | 6 +- tools/src/h5dump/h5dump_xml.c | 4 +- tools/src/h5ls/h5ls.c | 2 +- tools/src/h5repack/h5repack.c | 6 +- tools/src/h5repack/h5repack_copy.c | 6 +- tools/src/h5repack/h5repack_refs.c | 2 +- tools/test/h5copy/h5copygentest.c | 4 +- tools/test/h5diff/h5diffgentest.c | 24 +++--- tools/test/h5dump/h5dumpgentest.c | 32 ++++---- tools/test/h5repack/h5repacktst.c | 20 ++--- 31 files changed, 276 insertions(+), 274 deletions(-) diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp index db14577..a071289 100644 --- a/c++/src/H5DataSet.cpp +++ b/c++/src/H5DataSet.cpp @@ -369,10 +369,10 @@ void DataSet::vlenReclaim(const DataType& type, const DataSpace& space, const DS hid_t space_id = space.getId(); hid_t xfer_plist_id = xfer_plist.getId(); - herr_t ret_value = H5Dvlen_reclaim(type_id, space_id, xfer_plist_id, buf); + herr_t ret_value = H5Treclaim(type_id, space_id, xfer_plist_id, buf); if (ret_value < 0) { - throw DataSetIException("DataSet::vlenReclaim", "H5Dvlen_reclaim failed"); + throw DataSetIException("DataSet::vlenReclaim", "H5Treclaim failed"); } } @@ -397,10 +397,10 @@ void DataSet::vlenReclaim(void* buf, const DataType& type, const DataSpace& spac hid_t space_id = space.getId(); hid_t xfer_plist_id = xfer_plist.getId(); - herr_t ret_value = H5Dvlen_reclaim(type_id, space_id, xfer_plist_id, buf); + herr_t ret_value = H5Treclaim(type_id, space_id, xfer_plist_id, buf); if (ret_value < 0) { - throw DataSetIException("DataSet::vlenReclaim", "H5Dvlen_reclaim failed"); + throw DataSetIException("DataSet::vlenReclaim", "H5Treclaim failed"); } } diff --git a/c++/src/H5DxferProp.h b/c++/src/H5DxferProp.h index 6955778..e53a03b 100644 --- a/c++/src/H5DxferProp.h +++ b/c++/src/H5DxferProp.h @@ -66,7 +66,7 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { void getTypeConvCB(H5T_conv_except_func_t *op, void **user_data) const; // Sets the memory manager for variable-length datatype - // allocation in H5Dread and H5Dvlen_reclaim. + // allocation in H5Dread and H5Treclaim. void setVlenMemManager(H5MM_allocate_t alloc, void* alloc_info, H5MM_free_t free, void* free_info) const; @@ -75,7 +75,7 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { void setVlenMemManager() const; // Gets the memory manager for variable-length datatype - // allocation in H5Dread and H5Tvlen_reclaim. + // allocation in H5Dread and H5Treclaim. void getVlenMemManager(H5MM_allocate_t& alloc, void** alloc_info, H5MM_free_t& free, void** free_info) const; diff --git a/fortran/src/H5Df.c b/fortran/src/H5Df.c index 14fac6b..827baa1 100644 --- a/fortran/src/H5Df.c +++ b/fortran/src/H5Df.c @@ -544,7 +544,7 @@ h5dvlen_get_max_len_c ( hid_t_f *dset_id , hid_t_f *type_id, hid_t_f *space_id, c_len = 0; for (i=0; i < num_elem; i++) c_len = H5_MAX(c_len, c_buf[i].len); *len = (size_t_f)c_len; - H5Dvlen_reclaim(c_type_id, c_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_type_id, c_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: @@ -690,7 +690,7 @@ h5dread_vl_integer_c ( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_sp len[i] = (size_t_f)c_buf[i].len; memcpy(&buf[i*max_len], c_buf[i].p, c_buf[i].len*sizeof(int_f)); } - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); @@ -779,7 +779,7 @@ h5dwrite_vl_string_c( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_spa if( status < 0) goto DONE; ret_value = 0; DONE: - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); HDfree(c_buf); HDfree(tmp); return ret_value; @@ -861,7 +861,7 @@ h5dread_vl_string_c( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_spac } HD5packFstring(tmp, _fcdtocp(buf), (size_t)(max_len*num_elem)); ret_value = 0; - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); HDfree(c_buf); HDfree(tmp); return ret_value; @@ -1006,7 +1006,7 @@ h5dread_vl_real_c ( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_space memcpy(&buf[i*max_len], c_buf[i].p, c_buf[i].len*sizeof(real_f)); } - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); @@ -1284,7 +1284,7 @@ h5dget_access_plist_c (hid_t_f *dset_id, hid_t_f *plist_id) * NAME * h5dvlen_reclaim_c * PURPOSE - * Call H5Dvlen_reclaim + * Call H5Treclaim * INPUTS * type_id - Identifier of the datatype. * space_id - Identifier of the dataspace. @@ -1307,9 +1307,9 @@ h5dvlen_reclaim_c(hid_t_f *type_id, hid_t_f *space_id, hid_t_f *plist_id, void * herr_t status; /* - * Call H5Dvlen_reclaim function. + * Call H5Treclaim function. */ - status = H5Dvlen_reclaim((hid_t)*type_id, (hid_t)*space_id, (hid_t)*plist_id, buf); + status = H5Treclaim((hid_t)*type_id, (hid_t)*space_id, (hid_t)*plist_id, buf); if ( status < 0 ) return ret_value; ret_value = 0; diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index 067992f..b24f887 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -275,7 +275,7 @@ herr_t H5DSattach_scale(hid_t did, goto out; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -361,7 +361,7 @@ herr_t H5DSattach_scale(hid_t did, goto out; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -753,7 +753,7 @@ herr_t H5DSdetach_scale(hid_t did, } /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -896,7 +896,7 @@ out: dsbuf = NULL; } if(buf) { - /* Failure occured before H5Dvlen_reclaim was called; + /* Failure occured before H5Treclaim was called; free the pointers allocated when we read data in */ for(i = 0; i < rank; i++) { if(buf[i].p) @@ -1073,7 +1073,7 @@ htri_t H5DSis_attached(hid_t did, /* close */ - if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0) + if (H5Treclaim(tid,sid,H5P_DEFAULT,buf) < 0) goto out; if (H5Sclose(sid) < 0) goto out; @@ -1373,7 +1373,7 @@ herr_t H5DSiterate_scales(hid_t did, } /* if */ /* close */ - if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0) + if (H5Treclaim(tid,sid,H5P_DEFAULT,buf) < 0) goto out; if (H5Sclose(sid) < 0) goto out; @@ -1391,7 +1391,7 @@ herr_t H5DSiterate_scales(hid_t did, out: H5E_BEGIN_TRY { if(buf) { - H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf); + H5Treclaim(tid,sid,H5P_DEFAULT,buf); HDfree(buf); } H5Sclose(sid); @@ -2095,7 +2095,7 @@ int H5DSget_num_scales(hid_t did, nscales = (int)buf[idx].len; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; diff --git a/hl/src/H5PT.c b/hl/src/H5PT.c index 07d8bfb..f413bea 100644 --- a/hl/src/H5PT.c +++ b/hl/src/H5PT.c @@ -940,7 +940,7 @@ herr_t H5PTfree_vlen_buff( hid_t table_id, goto error; /* Free the memory. If this succeeds, ret_value should be 0. */ - if((ret_value = H5Dvlen_reclaim(table->type_id, space_id, H5P_DEFAULT, buff)) < 0) + if((ret_value = H5Treclaim(table->type_id, space_id, H5P_DEFAULT, buff)) < 0) goto error; /* If the dataspace cannot be closed, return -2 to indicate that memory */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index df9cf4e..9baa201 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -1519,7 +1519,7 @@ done: * * Purpose: Sets the memory allocate/free pair for VL datatypes. The * allocation routine is called when data is read into a new - * array and the free routine is called when H5Dvlen_reclaim is + * array and the free routine is called when H5Treclaim is * called. The alloc_info and free_info are user parameters * which are passed to the allocation and freeing functions * respectively. To reset the allocate/free functions to the @@ -1563,7 +1563,7 @@ done: * * Purpose: Sets the memory allocate/free pair for VL datatypes. The * allocation routine is called when data is read into a new - * array and the free routine is called when H5Dvlen_reclaim is + * array and the free routine is called when H5Treclaim is * called. The alloc_info and free_info are user parameters * which are passed to the allocation and freeing functions * respectively. To reset the allocate/free functions to the diff --git a/test/dsets.c b/test/dsets.c index 649e001..21d5431 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -4085,8 +4085,8 @@ test_nbit_compound_3(hid_t file) * Cleanup *---------------------------------------------------------------------- */ - if(H5Dvlen_reclaim(cmpd_tid, space, H5P_DEFAULT, new_data) < 0) goto error; - if(H5Dvlen_reclaim(cmpd_tid, space, H5P_DEFAULT, orig_data) < 0) goto error; + if(H5Treclaim(cmpd_tid, space, H5P_DEFAULT, new_data) < 0) goto error; + if(H5Treclaim(cmpd_tid, space, H5P_DEFAULT, orig_data) < 0) goto error; if(H5Tclose(i_tid) < 0) goto error; if(H5Tclose(str_tid) < 0) goto error; if(H5Tclose(vl_str_tid) < 0) goto error; diff --git a/test/dtypes.c b/test/dtypes.c index c3b7dcc..c3f80d6 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1809,7 +1809,7 @@ test_compound_9(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -1875,7 +1875,7 @@ test_compound_9(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't read data\n"); goto error; @@ -2063,12 +2063,12 @@ test_compound_10(void) goto error; } } /* end for */ - if(H5Dvlen_reclaim(arr_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(arr_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ - if(H5Dvlen_reclaim(arr_tid, space_id, H5P_DEFAULT, &wdata) < 0) { + if(H5Treclaim(arr_tid, space_id, H5P_DEFAULT, &wdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -2226,7 +2226,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid2, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid2, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2270,7 +2270,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2308,7 +2308,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2811,13 +2811,13 @@ test_compound_14(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { + if(H5Treclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ rdata1.str = NULL; - if(H5Dvlen_reclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { + if(H5Treclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -2898,13 +2898,13 @@ test_compound_14(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { + if(H5Treclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ rdata1.str = NULL; - if(H5Dvlen_reclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { + if(H5Treclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; diff --git a/test/fillval.c b/test/fillval.c index 0454bde..47cd53a 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -1516,7 +1516,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1572,7 +1572,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1613,7 +1613,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1652,7 +1652,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1693,7 +1693,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1739,7 +1739,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(H5Dwrite(dset, dtype, mspace, fspace, H5P_DEFAULT, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1758,7 +1758,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1786,7 +1786,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); diff --git a/test/genall5.c b/test/genall5.c index 4cc0a2d..849d97c 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -2735,11 +2735,11 @@ ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) { } if ((pass) && (write_data)) { - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, wdata); if (ret < 0) { pass = FALSE; - failure_mssg = "ds_ctg_v: H5Dvlen_reclaim() failed."; + failure_mssg = "ds_ctg_v: H5Treclaim() failed."; } HDassert(ret >= 0); @@ -3003,11 +3003,11 @@ vrfy_ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) { } if ((pass) && (write_data)) { - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rdata); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, rdata); if (ret < 0) { pass = FALSE; - failure_mssg = "vrfy_ds_ctg_v: H5Dvlen_reclaim() failed."; + failure_mssg = "vrfy_ds_ctg_v: H5Treclaim() failed."; } HDassert(ret >= 0); diff --git a/test/ntypes.c b/test/ntypes.c index 83cdfd2..34558f5 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -1779,10 +1779,10 @@ test_vl_dtype(hid_t file) } /* end for */ /* Reclaim the read VL data */ - if(H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, rdata) < 0) TEST_ERROR; + if(H5Treclaim(native_type, space, H5P_DEFAULT, rdata) < 0) TEST_ERROR; /* Reclaim the write VL data */ - if(H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, wdata) < 0) TEST_ERROR; + if(H5Treclaim(native_type, space, H5P_DEFAULT, wdata) < 0) TEST_ERROR; /* Close Dataset */ if(H5Dclose(dataset) < 0) TEST_ERROR; @@ -1808,8 +1808,8 @@ error: H5E_BEGIN_TRY { if(native_type > 0) { - H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, rdata); - H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, wdata); + H5Treclaim(native_type, space, H5P_DEFAULT, rdata); + H5Treclaim(native_type, space, H5P_DEFAULT, wdata); } /* end if */ H5Sclose(space); H5Dclose(dataset); diff --git a/test/objcopy.c b/test/objcopy.c index 05ddfa4..083d9af 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -547,7 +547,7 @@ done: if(tid >0 && sid > 0) { hid_t dxpl_id = H5Pcreate(H5P_DATASET_XFER); H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL); - H5Dvlen_reclaim(tid, sid, dxpl_id, buf); + H5Treclaim(tid, sid, dxpl_id, buf); H5Pclose(dxpl_id); } if(sid > 0) @@ -794,9 +794,9 @@ compare_attribute(hid_t aid, hid_t aid2, hid_t pid, const void *wbuf, hid_t obj_ /* Reclaim vlen data, if necessary */ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR /* Release raw data buffers */ HDfree(rbuf); @@ -1306,9 +1306,9 @@ compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf) /* Reclaim vlen data, if necessary */ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR /* Release raw data buffers */ HDfree(rbuf); @@ -5290,7 +5290,7 @@ test_copy_dataset_contig_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5307,7 +5307,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -5473,7 +5473,7 @@ test_copy_dataset_chunked_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5490,7 +5490,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -5618,7 +5618,7 @@ test_copy_dataset_compact_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5635,7 +5635,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -5896,8 +5896,8 @@ compare_attribute_compound_vlstr(hid_t loc, hid_t loc2) /* Reclaim vlen buffer */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, &rbuf) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, &rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, &rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, &rbuf2) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR /* Close the dataspaces */ @@ -5917,8 +5917,8 @@ error: H5E_BEGIN_TRY { H5Aclose(aid); H5Aclose(aid2); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, &rbuf); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, &rbuf2); + H5Treclaim(tid, sid, H5P_DEFAULT, &rbuf); + H5Treclaim(tid, sid, H5P_DEFAULT, &rbuf2); H5Sclose(sid); H5Sclose(sid2); H5Tclose(tid); @@ -6219,7 +6219,7 @@ test_copy_dataset_compressed_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -6239,7 +6239,7 @@ error: H5Dclose(did2); H5Dclose(did); H5Pclose(pid); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -8050,7 +8050,7 @@ test_copy_dataset_compact_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8068,7 +8068,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8197,7 +8197,7 @@ test_copy_dataset_contig_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8214,7 +8214,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8364,7 +8364,7 @@ test_copy_dataset_chunked_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8382,7 +8382,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8521,7 +8521,7 @@ test_copy_dataset_compressed_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_ if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8539,7 +8539,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8683,7 +8683,7 @@ test_copy_dataset_compact_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8701,7 +8701,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -8856,7 +8856,7 @@ test_copy_dataset_contig_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8874,7 +8874,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -9057,7 +9057,7 @@ test_copy_dataset_chunked_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9076,7 +9076,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid2); @@ -9233,7 +9233,7 @@ test_copy_dataset_compressed_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9252,7 +9252,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid2); @@ -9389,7 +9389,7 @@ test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9407,7 +9407,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid2); H5Tclose(tid); @@ -9542,7 +9542,7 @@ test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9560,7 +9560,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid2); @@ -9695,7 +9695,7 @@ test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9713,7 +9713,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid2); diff --git a/test/set_extent.c b/test/set_extent.c index 20322a3..78d2b0b 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -2658,7 +2658,7 @@ static int test_random_rank4_vl( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue, } /* end else */ /* Free read buffer */ - if(H5Dvlen_reclaim(type, mspace, H5P_DEFAULT, rbuf) < 0) + if(H5Treclaim(type, mspace, H5P_DEFAULT, rbuf) < 0) TEST_ERROR } /* end if */ @@ -2678,7 +2678,7 @@ static int test_random_rank4_vl( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue, /* Close */ if(H5Sselect_all(mspace) < 0) TEST_ERROR - if(H5Dvlen_reclaim(type, mspace, H5P_DEFAULT, wbuf) < 0) + if(H5Treclaim(type, mspace, H5P_DEFAULT, wbuf) < 0) TEST_ERROR free(fill_value.p); if(H5Sclose(mspace) < 0) diff --git a/test/tarray.c b/test/tarray.c index 0024746..e643fb0 100644 --- a/test/tarray.c +++ b/test/tarray.c @@ -1268,15 +1268,15 @@ test_array_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close dataset transfer property list */ ret = H5Pclose(xfer_pid); @@ -1523,15 +1523,15 @@ test_array_vlen_array(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close dataset transfer property list */ ret = H5Pclose(xfer_pid); diff --git a/test/tfile.c b/test/tfile.c index f39da5a..f6b92eb 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -2640,8 +2640,8 @@ test_file_double_file_dataset_open(hbool_t new_format) HDmemset(buffer, 0, sizeof(char*) * 5); ret = H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); CHECK(ret, FAIL, "H5Dread"); - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, buffer); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer); + CHECK(ret, FAIL, "H5Treclaim"); /* Second file's dataset close */ ret = H5Dclose(did2); @@ -2655,8 +2655,8 @@ test_file_double_file_dataset_open(hbool_t new_format) HDmemset(buffer, 0, sizeof(char*) * 5); ret = H5Dread(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); CHECK(ret, FAIL, "H5Dread"); - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, buffer); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer); + CHECK(ret, FAIL, "H5Treclaim"); /* First file's dataset close */ ret = H5Dclose(did1); diff --git a/test/tmisc.c b/test/tmisc.c index 5225333..d637802 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -460,8 +460,8 @@ static void test_misc2_write_attribute(void) ret = H5Aread(att1, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, dataspace, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, dataspace, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Aclose(att1); CHECK(ret, FAIL, "H5Aclose"); @@ -486,8 +486,8 @@ static void test_misc2_write_attribute(void) ret = H5Aread(att2, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, dataspace, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, dataspace, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Aclose(att2); CHECK(ret, FAIL, "H5Aclose"); @@ -535,8 +535,8 @@ static void test_misc2_read_attribute(const char *filename, const char *att_name ret = H5Aread(att, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, space, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Sclose(space); CHECK(ret, FAIL, "H5Sclose"); @@ -994,8 +994,8 @@ test_misc5(void) } /* Reclaim the memory for the VL information */ - ret=H5Dvlen_reclaim(mem_type_id, space_id, H5P_DEFAULT, &buf); - CHECK(ret,FAIL,"H5Dvlen_reclaim"); + ret=H5Treclaim(mem_type_id, space_id, H5P_DEFAULT, &buf); + CHECK(ret,FAIL,"H5Treclaim"); /* Close dataspace */ ret=H5Sclose(space_id); @@ -2061,8 +2061,8 @@ test_misc12(void) CHECK(ret, FAIL, "H5Sselect_all"); /* Reclaim VL data memory */ - ret = H5Dvlen_reclaim(tid1, space, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, space, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Everything */ ret = H5Dclose(dataset); diff --git a/test/tunicode.c b/test/tunicode.c index b3fa237..6f7431b 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -352,8 +352,8 @@ void test_vl_string(hid_t fid, const char *string) VERIFY(HDstrcmp(string, read_buf[0]), 0, "strcmp"); /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(type_id, space_id, H5P_DEFAULT, read_buf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type_id, space_id, H5P_DEFAULT, read_buf); + CHECK(ret, FAIL, "H5Treclaim"); /* Close all */ ret = H5Dclose(dset_id); diff --git a/test/tvlstr.c b/test/tvlstr.c index 5f715ce..731270c 100644 --- a/test/tvlstr.c +++ b/test/tvlstr.c @@ -208,11 +208,11 @@ test_vlstrings_basic(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -314,8 +314,8 @@ test_vlstrings_special(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -537,8 +537,8 @@ test_compact_vlstring(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -762,8 +762,8 @@ static void read_scalar_dset(hid_t file, hid_t type, hid_t space, char *name, ch if(HDstrcmp(data, data_read)) TestErrPrintf("Expected %s for dataset %s but read %s\n", data, name, data_read); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &data_read); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, space, H5P_DEFAULT, &data_read); + CHECK(ret, FAIL, "H5Treclaim"); } /**************************************************************** diff --git a/test/tvltypes.c b/test/tvltypes.c index ffa2aff..656bf92 100644 --- a/test/tvltypes.c +++ b/test/tvltypes.c @@ -415,11 +415,11 @@ test_vltypes_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, xfer_pid, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, xfer_pid, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used, 0, "H5Dvlen_reclaim"); + VERIFY(mem_used, 0, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -499,24 +499,24 @@ test_vltypes_vlen_atomic(void) /* Try to reclaim read data using "bad" dataspace with no extent * Should fail */ H5E_BEGIN_TRY { - ret=H5Dvlen_reclaim(tid1,sid2,xfer_pid,rdata); + ret=H5Treclaim(tid1,sid2,xfer_pid,rdata); } H5E_END_TRY - VERIFY(ret, FAIL, "H5Dvlen_reclaim"); + VERIFY(ret, FAIL, "H5Treclaim"); /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close datatype */ ret = H5Tclose(tid1); @@ -659,15 +659,15 @@ rewrite_vltypes_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -803,15 +803,15 @@ test_vltypes_vlen_compound(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -948,15 +948,15 @@ rewrite_vltypes_vlen_compound(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1118,12 +1118,12 @@ test_vltypes_compound_vlen_vlen(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1360,12 +1360,12 @@ test_vltypes_compound_vlstr(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Use this part for new data */ HDstrcpy(str, "bbbbbbbb\0"); @@ -1418,12 +1418,12 @@ test_vltypes_compound_vlstr(void) } /* end for */ /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata2); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata2); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata2); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata2); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); @@ -1568,11 +1568,11 @@ test_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, xfer_pid, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, xfer_pid, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used, 0, "H5Dvlen_reclaim"); + VERIFY(mem_used, 0, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1634,16 +1634,16 @@ test_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close datatype */ ret = H5Tclose(tid2); @@ -1786,15 +1786,15 @@ rewrite_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1997,15 +1997,15 @@ test_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2177,15 +2177,15 @@ rewrite_longer_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2353,15 +2353,15 @@ rewrite_shorter_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2743,8 +2743,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -2778,8 +2778,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -2808,8 +2808,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -2843,8 +2843,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -2970,8 +2970,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -3019,8 +3019,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -3066,8 +3066,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -3115,8 +3115,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index 4ad4c90..351e6ab 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -515,12 +515,12 @@ hsize_t diff_attr(hid_t loc1_id, /* Free buf1 and buf2, check both VLEN-data VLEN-string to reclaim any * VLEN memory first */ if(TRUE == h5tools_detect_vlen(mtype1_id)) - H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); + H5Treclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; if(TRUE == h5tools_detect_vlen(mtype2_id)) - H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); + H5Treclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; @@ -551,12 +551,12 @@ done: H5E_BEGIN_TRY { if(buf1) { if(buf1hasdata && TRUE == h5tools_detect_vlen(mtype1_id)) - H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); + H5Treclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); } /* end if */ if(buf2) { if(buf2hasdata && TRUE == h5tools_detect_vlen(mtype2_id)) - H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); + H5Treclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); } /* end if */ diff --git a/tools/lib/h5diff_dset.c b/tools/lib/h5diff_dset.c index ff542db..96f1d1a 100644 --- a/tools/lib/h5diff_dset.c +++ b/tools/lib/h5diff_dset.c @@ -416,10 +416,10 @@ hsize_t diff_datasetid(hid_t did1, /* reclaim any VL memory, if necessary */ h5diffdebug2("check vl_data1:%d\n", vl_data1); if(vl_data1) - H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); + H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1); h5diffdebug2("check vl_data2:%d\n", vl_data2); if(vl_data2) - H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); + H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2); if(buf1 != NULL) { HDfree(buf1); buf1 = NULL; @@ -510,9 +510,9 @@ hsize_t diff_datasetid(hid_t did1, /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); + H5Treclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); if(vl_data2) - H5Dvlen_reclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); + H5Treclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); /* calculate the next hyperslab offset */ for(i = rank1, carry = 1; i > 0 && carry; --i) { @@ -550,28 +550,28 @@ done: if(buf1 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); + H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; } if(buf2 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data2) - H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); + H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; } if(sm_buf1 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); + H5Treclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); HDfree(sm_buf1); sm_buf1 = NULL; } if(sm_buf2 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data2) - H5Dvlen_reclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); + H5Treclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); HDfree(sm_buf2); sm_buf2 = NULL; } diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index eaac94a..e80cf53 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -1256,7 +1256,7 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); + H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); if(H5Sclose(sm_space) < 0) H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sclose failed"); @@ -1645,7 +1645,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); + H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); /* Calculate the next hyperslab offset */ for (i = ctx->ndims, carry = 1; i > 0 && carry; --i) { @@ -3979,7 +3979,7 @@ h5tools_dump_data(FILE *stream, const h5tool_format_t *info, /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index c4fd948..be9e727 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -1919,7 +1919,7 @@ xml_dump_data(hid_t obj_id, int obj_data, struct subset_t H5_ATTR_UNUSED * sset, } /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } @@ -3099,7 +3099,7 @@ xml_print_strs(hid_t did, int source) HDfree(onestring); if (buf) { if (is_vlstr) - H5Dvlen_reclaim(type, space, H5P_DEFAULT, buf); + H5Treclaim(type, space, H5P_DEFAULT, buf); HDfree(buf); } H5Tclose(type); diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index 3b0001d..5c9c693 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -1568,7 +1568,7 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ain /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c index 0183cbf..5f688d9 100644 --- a/tools/src/h5repack/h5repack.c +++ b/tools/src/h5repack/h5repack.c @@ -486,7 +486,7 @@ copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p, trav_table_ /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) - H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim(wtype_id, space_id, H5P_DEFAULT, buf); HDfree(buf); buf = NULL; } /*H5T_REFERENCE*/ @@ -519,7 +519,9 @@ done: * datatype that must be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) - H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim(wtype_id, space_id, H5P_DEFAULT, buf); + + /* Free buf */ HDfree(buf); } diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index f6409e3..24f67db 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -918,8 +918,8 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, /* Check if we have VL data in the dataset's * datatype that must be reclaimed */ if (TRUE == H5Tdetect_class(wtype_id, H5T_VLEN)) - if (H5Dvlen_reclaim(wtype_id, f_space_id, H5P_DEFAULT, buf) < 0) - HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dvlen_reclaim failed"); + if (H5Treclaim(wtype_id, f_space_id, H5P_DEFAULT, buf) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Treclaim failed"); if (buf != NULL) { /* TODO: is buf potentially released by H5Dvlen_reclaim()? */ HDfree(buf); @@ -1010,7 +1010,7 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, /* reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(wtype_id, hslab_space, H5P_DEFAULT, hslab_buf); + H5Treclaim(wtype_id, hslab_space, H5P_DEFAULT, hslab_buf); /* calculate the next hyperslab offset */ for (k = rank, carry = 1; k > 0 && carry; --k) { diff --git a/tools/src/h5repack/h5repack_refs.c b/tools/src/h5repack/h5repack_refs.c index 7e8951f..bfc376f 100644 --- a/tools/src/h5repack/h5repack_refs.c +++ b/tools/src/h5repack/h5repack_refs.c @@ -712,7 +712,7 @@ static int copy_refs_attr(hid_t loc_in, HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed"); if (is_ref_vlen && buf) - H5Dvlen_reclaim (mtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim (mtype_id, space_id, H5P_DEFAULT, buf); } /* if (nelmts) */ if (refbuf == buf) diff --git a/tools/test/h5copy/h5copygentest.c b/tools/test/h5copy/h5copygentest.c index f6aa72f..a3acdae 100644 --- a/tools/test/h5copy/h5copygentest.c +++ b/tools/test/h5copy/h5copygentest.c @@ -261,7 +261,7 @@ static void gent_named_vl(hid_t loc_id) H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* close */ - H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf); + H5Treclaim(tid,sid,H5P_DEFAULT,buf); H5Sclose(sid); H5Dclose(did); H5Tclose(tid); @@ -314,7 +314,7 @@ static void gent_nested_vl(hid_t loc_id) H5Dwrite(did, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* close */ - H5Dvlen_reclaim(tid2,sid,H5P_DEFAULT,buf); + H5Treclaim(tid2,sid,H5P_DEFAULT,buf); H5Sclose(sid); H5Dclose(did); H5Tclose(tid1); diff --git a/tools/test/h5diff/h5diffgentest.c b/tools/test/h5diff/h5diffgentest.c index d60e393..c711013 100644 --- a/tools/test/h5diff/h5diffgentest.c +++ b/tools/test/h5diff/h5diffgentest.c @@ -4403,7 +4403,7 @@ static void test_comps_vlen(const char * fname, const char *dset, const char *at assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /* ---------------- @@ -4537,7 +4537,7 @@ static void test_comps_array_vlen(const char * fname, const char *dset, const ch assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /*------------------- @@ -4680,7 +4680,7 @@ static void test_comps_vlen_arry(const char * fname, const char *dset, const cha assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /* ---------------- @@ -5446,7 +5446,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -5712,7 +5712,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6108,7 +6108,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6434,7 +6434,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6702,7 +6702,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -7100,7 +7100,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -7395,7 +7395,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -7580,7 +7580,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff did = H5Dcreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -7759,7 +7759,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff did = H5Dcreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 35c3e3c..ad70770 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -2624,7 +2624,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset1.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, wdata); + ret = H5Treclaim(type, space, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2651,7 +2651,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset2.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, wdata); + ret = H5Treclaim(type, space, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2674,7 +2674,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset3.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, &adata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &adata); + ret = H5Treclaim(type, space, H5P_DEFAULT, &adata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2740,7 +2740,7 @@ gent_vldatatypes2(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2811,7 +2811,7 @@ static void gent_vldatatypes3(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2878,7 +2878,7 @@ static void gent_vldatatypes4(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2942,7 +2942,7 @@ static void gent_vldatatypes5(void) ret = H5Dclose(dataset); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Tclose(tid1); @@ -3385,7 +3385,7 @@ static void gent_array6(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -3454,7 +3454,7 @@ static void gent_array7(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -4054,7 +4054,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4165,7 +4165,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4298,7 +4298,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4496,7 +4496,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -4606,7 +4606,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -4745,7 +4745,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -5966,7 +5966,7 @@ static void gent_fvalues(void) did = H5Dcreate2(fid, "fill_vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf3); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf3); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, buf3); HDassert(ret >= 0); ret = H5Dclose(did); ret = H5Tclose(tid); diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index ec8df3c..f3e6cd3 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -4079,7 +4079,7 @@ int write_dset_in(hid_t loc_id, goto out; if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf5) < 0) goto out; if (H5Dclose(did) < 0) goto out; @@ -4312,7 +4312,7 @@ int write_dset_in(hid_t loc_id, goto out; if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf52) < 0) goto out; if (H5Dclose(did) < 0) goto out; @@ -4533,7 +4533,7 @@ int write_dset_in(hid_t loc_id, if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf53) < 0) goto out; if (H5Dclose(did) < 0) @@ -5009,7 +5009,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf5) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf5) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -5331,7 +5331,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf52) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf52) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -5793,7 +5793,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf53) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf53) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -7036,10 +7036,10 @@ static herr_t make_complex_attr_references(hid_t loc_id) } /* close resource for vlen data */ - status = H5Dvlen_reclaim (vlen_objref_attr_tid, vlen_objref_attr_sid, H5P_DEFAULT, vlen_objref_data); + status = H5Treclaim (vlen_objref_attr_tid, vlen_objref_attr_sid, H5P_DEFAULT, vlen_objref_data); if (status < 0) { - HDfprintf(stderr, "Error: %s %d> H5Dvlen_reclaim failed.\n", FUNC, __LINE__); + HDfprintf(stderr, "Error: %s %d> H5Treclaim failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } @@ -7091,10 +7091,10 @@ static herr_t make_complex_attr_references(hid_t loc_id) } /* close resource for vlen data */ - status = H5Dvlen_reclaim (vlen_regref_attr_tid, vlen_regref_attr_sid, H5P_DEFAULT, vlen_regref_data); + status = H5Treclaim (vlen_regref_attr_tid, vlen_regref_attr_sid, H5P_DEFAULT, vlen_regref_data); if (status < 0) { - HDfprintf(stderr, "Error: %s %d> H5Dvlen_reclaim failed.\n", FUNC, __LINE__); + HDfprintf(stderr, "Error: %s %d> H5Treclaim failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } -- cgit v0.12 From b18e4b0f1aa5548fd0b9f4a9fbc0a75d650bd10f Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Wed, 14 Aug 2019 12:41:29 -0500 Subject: Fix reference type comparison in h5dump --- tools/lib/h5tools_dump.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index e80cf53..ebe5c4a 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -2345,9 +2345,13 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_ if (H5Tequal(type, H5T_STD_REF_DSETREG) == TRUE) { h5tools_str_append(buffer, " { H5T_STD_REF_DSETREG }"); } - else { + else if (H5Tequal(type, H5T_STD_REF_OBJ) == TRUE) { h5tools_str_append(buffer, " { H5T_STD_REF_OBJECT }"); } + else if (H5Tequal(type, H5T_STD_REF) == TRUE) { + h5tools_str_append(buffer, " { H5T_STD_REF }"); + } else + h5tools_str_append(buffer, " { UNDEFINED }"); break; case H5T_ENUM: -- cgit v0.12 From 1a10f7b6721b5a42cda73819b14c731bbf400fed Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Tue, 8 Oct 2019 14:51:12 -0500 Subject: Update RELEASE.txt for reference changes --- release_docs/RELEASE.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 35247cc..441cce5 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -248,6 +248,16 @@ New Features (NAF - 2019/03/01) + - Add new H5R_ref_t type for object, dataset region and _attribute_ + references. This new type will deprecate the current hobj_ref_t + and hdset_reg_ref_t types for references. Added H5T_REF datatype + to read and write new reference types. As opposed to previous + reference types, reference creation no longer modifies existing + files. New reference types also now support references to external + files. + + (JS - 2019/10/08) + - Remove H5I_REFERENCE from the library This ID class was never used by the library and has been removed. -- cgit v0.12 From 5d2545ee26d4b7013ed363545705f16a67087549 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Wed, 9 Oct 2019 11:12:34 -0500 Subject: Fix func enter macro in H5T_ref_reclaim() --- src/H5Tref.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Tref.c b/src/H5Tref.c index 6f7bf90..e4e9267 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -746,7 +746,7 @@ H5T_ref_reclaim(void *elem, const H5T_t *dt) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ HDassert(elem); -- cgit v0.12