2
0
mirror of https://github.com/HDFGroup/hdf5.git synced 2025-04-24 17:51:25 +08:00

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
This commit is contained in:
Jerome Soumagne 2019-07-16 11:15:43 -05:00
parent 0f4e080309
commit ae490016b9
54 changed files with 10202 additions and 2058 deletions

@ -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

@ -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",

@ -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

@ -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

90
examples/h5_ref_compat.c Normal file

@ -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 <stdlib.h>
#include "hdf5.h"
#include <assert.h>
#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;
}

94
examples/h5_ref_extern.c Normal file

@ -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 <stdlib.h>
#include "hdf5.h"
#include <assert.h>
#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;
}

@ -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 &&\

@ -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

@ -2270,7 +2270,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 {
@ -2401,17 +2401,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

@ -704,56 +704,6 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Diterate() */
/*-------------------------------------------------------------------------
* 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

@ -6088,23 +6088,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 */

@ -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

@ -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 */

@ -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 */

@ -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)
@ -2540,50 +2540,6 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__get_offset() */
/*-------------------------------------------------------------------------
* 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

@ -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 */

@ -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);

@ -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 */

@ -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 */
/*****************************/
@ -1233,201 +1230,6 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O__copy_obj() */
/*-------------------------------------------------------------------------
* 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

485
src/H5Ocopy_ref.c Normal file

@ -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() */

@ -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);
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 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;
/* 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;
} /* end if */
/* 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:

@ -742,7 +742,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 */

@ -981,8 +981,8 @@ H5_DLL herr_t H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disable
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);

@ -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:

@ -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;

@ -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 */

1003
src/H5R.c

File diff suppressed because it is too large Load Diff

@ -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")
/* Get the VOL object */
if(NULL == (vol_obj = H5VL_vol_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "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, 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_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_addr;
loc_params.obj_type = vol_obj_type;
/* Get the vol object */
if (NULL == (vol_obj = H5VL_vol_object(id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid file identifier")
/* 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")
/* 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.
* Purpose: Given a reference to some object, open that object and return an
* ID for that object.
*
* 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
*
* 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")
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);
/* 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;
/* 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() */

File diff suppressed because it is too large Load Diff

@ -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 */

@ -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 */

@ -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)
/* 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).
*/
#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4)
/* 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_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 */

@ -1357,7 +1357,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)
@ -1378,7 +1377,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 */
@ -1390,7 +1389,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 */

169
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
@ -737,7 +755,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) */
@ -989,12 +1009,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
@ -1030,6 +1061,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
@ -1473,6 +1508,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:
} /* end H5Tconvert() */
/*-------------------------------------------------------------------------
* 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
*
@ -4456,28 +4542,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:
@ -5330,7 +5398,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:
@ -5455,17 +5523,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:
@ -5492,7 +5552,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).
*
@ -5527,9 +5587,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
@ -5541,7 +5601,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 */
@ -5551,8 +5611,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 */
@ -5561,14 +5622,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:
@ -5586,7 +5647,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() */
/*-------------------------------------------------------------------------
@ -5622,7 +5683,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;

@ -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() */

@ -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)

@ -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 {
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 {
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 {
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 {
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);

@ -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);

@ -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.
*

761
src/H5Tref.c Normal file

@ -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() */

@ -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:
@ -1206,58 +1200,6 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo
} /* end switch */ /*lint !e788 All appropriate cases are covered */
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() */

@ -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 */

@ -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; j<na; j++)
fprintf(rawoutstream, " H5T_%s_COMP_ALIGN_g = %lu;\n", misc_align[j].name, (unsigned long)(misc_align[j].comp_align));
@ -1544,11 +1543,12 @@ detect_C99_floats(void)
static void HDF_NO_UBSAN
detect_alignments(void)
{
/* Detect structure alignment for pointers, hvl_t, hobj_ref_t, hdset_reg_ref_t */
/* Detect structure alignment for pointers, vlen and reference types */
DETECT_M(void *, POINTER, m_g[na_g]); na_g++;
DETECT_M(hvl_t, HVL, m_g[na_g]); na_g++;
DETECT_M(hobj_ref_t, HOBJREF, m_g[na_g]); na_g++;
DETECT_M(hdset_reg_ref_t, HDSETREGREF, m_g[na_g]); na_g++;
DETECT_M(H5R_ref_t, REF, m_g[na_g]); na_g++;
}

@ -34,6 +34,7 @@
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5FDprivate.h" /* File drivers */
#include "H5Rprivate.h" /* References */
#include "H5Ipkg.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5VLprivate.h" /* Virtual Object Layer */
@ -1856,22 +1857,51 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end else */
break;
case 'r':
if(ptr) {
if(vp)
HDfprintf(out, "0x%lx", (unsigned long)vp);
else
HDfprintf(out, "NULL");
} /* end if */
else {
hobj_ref_t ref = HDva_arg(ap, hobj_ref_t);
HDfprintf(out, "Reference Object=%a", ref);
} /* end else */
break;
case 'R':
switch(type[1]) {
case 'o':
if(ptr) {
if(vp)
HDfprintf(out, "0x%lx", (unsigned long)vp);
else
HDfprintf(out, "NULL");
} /* end if */
else {
hobj_ref_t ref = HDva_arg(ap, hobj_ref_t);
HDfprintf(out, "Reference Object=%a", ref);
} /* end else */
break;
case 'd':
if(ptr) {
if(vp)
HDfprintf(out, "0x%lx", (unsigned long)vp);
else
HDfprintf(out, "NULL");
} /* end if */
else {
/* Note! region references are array types */
HDfprintf(out, "Reference Region");
goto error;
} /* end else */
break;
case 'r':
if(ptr) {
if(vp)
HDfprintf(out, "0x%lx", (unsigned long)vp);
else
HDfprintf(out, "NULL");
} /* end if */
else {
/* Note! reference types are opaque types */
HDfprintf(out, "Reference Opaque");
goto error;
} /* end else */
break;
case 't':
if(ptr) {
if(vp)
@ -1887,12 +1917,24 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
HDfprintf(out, "H5R_BADTYPE");
break;
case H5R_OBJECT:
HDfprintf(out, "H5R_OBJECT");
case H5R_OBJECT1:
HDfprintf(out, "H5R_OBJECT1");
break;
case H5R_DATASET_REGION:
HDfprintf(out, "H5R_DATASET_REGION");
case H5R_DATASET_REGION1:
HDfprintf(out, "H5R_DATASET_REGION1");
break;
case H5R_OBJECT2:
HDfprintf(out, "H5R_OBJECT2");
break;
case H5R_DATASET_REGION2:
HDfprintf(out, "H5R_DATASET_REGION2");
break;
case H5R_ATTR:
HDfprintf(out, "H5R_ATTR");
break;
case H5R_MAXTYPE:

@ -83,7 +83,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5O.c H5Odeprec.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ocache_image.c \
H5Ochunk.c \
H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \
H5Ocont.c H5Ocopy.c H5Ocopy_ref.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \
H5Ofill.c H5Oflush.c H5Ofsinfo.c H5Oginfo.c \
H5Oint.c H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \
@ -114,6 +114,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c \
H5Topaque.c \
H5Torder.c \
H5Tref.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_blob.c H5VLnative_dataset.c \

@ -194,6 +194,7 @@ set (testhdf5_SOURCES
${HDF5_TEST_SOURCE_DIR}/tmeta.c
${HDF5_TEST_SOURCE_DIR}/tmisc.c
${HDF5_TEST_SOURCE_DIR}/trefer.c
${HDF5_TEST_SOURCE_DIR}/trefer_deprec.c
${HDF5_TEST_SOURCE_DIR}/trefstr.c
${HDF5_TEST_SOURCE_DIR}/tselect.c
${HDF5_TEST_SOURCE_DIR}/tskiplist.c
@ -250,6 +251,7 @@ set (H5_TESTS
external
external_env
efc
objcopy_ref
objcopy
links
unlink

@ -59,7 +59,7 @@ TEST_PROG= testhdf5 \
stab gheap evict_on_close farray earray btree2 fheap \
pool accum hyperslab istore bittests dt_arith page_buffer \
dtypes dsets chunk_info cmpd_dset filter_fail extend direct_chunk \
external efc objcopy links unlink twriteorder big mtime fillval mount \
external efc objcopy objcopy_ref links unlink twriteorder big mtime fillval mount \
flush1 flush2 app_ref enum set_extent ttsafe enc_dec_plist \
enc_dec_plist_cross_platform getname vfd ros3 s3comms hdfs ntypes \
dangle dtransform reserved cross_read freespace mf vds file_image \
@ -190,7 +190,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
stdio.h5 sec2.h5 dtypes[0-9].h5 dtypes1[0].h5 dt_arith[1-2].h5 tattr.h5 \
tselect.h5 mtime.h5 unlink.h5 unicode.h5 coord.h5 \
fillval_[0-9].h5 fillval.raw mount_[0-9].h5 testmeta.h5 ttime.h5 \
trefer[1-3].h5 tvltypes.h5 tvlstr.h5 tvlstr2.h5 twriteorder.dat \
trefer[1-3].h5 trefer_*.h5 tvltypes.h5 tvlstr.h5 tvlstr2.h5 twriteorder.dat \
flush.h5 flush-swmr.h5 noflush.h5 noflush-swmr.h5 flush_extend.h5 \
flush_extend-swmr.h5 noflush_extend.h5 noflush_extend-swmr.h5 \
enum1.h5 titerate.h5 ttsafe.h5 tarray1.h5 tgenprop.h5 \
@ -218,7 +218,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
# Sources for testhdf5 executable
testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \
tgenprop.c th5o.c th5s.c tcoords.c theap.c tid.c titerate.c tmeta.c tmisc.c \
trefer.c trefstr.c tselect.c tskiplist.c tsohm.c ttime.c ttst.c tunicode.c \
trefer.c trefer_deprec.c trefstr.c tselect.c tskiplist.c tsohm.c ttime.c ttst.c tunicode.c \
tvlstr.c tvltypes.c
# Sources for Use Cases

1739
test/objcopy_ref.c Normal file

File diff suppressed because it is too large Load Diff

@ -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);

@ -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);

File diff suppressed because it is too large Load Diff

1827
test/trefer_deprec.c Normal file

File diff suppressed because it is too large Load Diff