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:
parent
0f4e080309
commit
ae490016b9
MANIFEST
bin
examples
CMakeLists.txtMakefile.amh5_ref2reg_deprec.ch5_ref_compat.ch5_ref_extern.ch5_reference_deprec.crun-c-ex.sh.in
src
CMakeLists.txtH5Aint.cH5D.cH5Dchunk.cH5Dcompact.cH5Dcontig.cH5Ddeprec.cH5Dint.cH5Dio.cH5Dprivate.hH5Dpublic.hH5Ocopy.cH5Ocopy_ref.cH5Odtype.cH5Ofill.cH5Oprivate.hH5Pint.cH5Pprivate.hH5Ppublic.hH5R.cH5Rdeprec.cH5Rint.cH5Rpkg.hH5Rprivate.hH5Rpublic.hH5S.cH5T.cH5Tconv.cH5Tnative.cH5Tpkg.hH5Tprivate.hH5Tpublic.hH5Tref.cH5Tvlen.cH5VLnative_file.cH5detect.cH5trace.cMakefile.am
test
10
MANIFEST
10
MANIFEST
@ -167,8 +167,10 @@
|
||||
./examples/h5_select.c
|
||||
./examples/h5_attribute.c
|
||||
./examples/h5_mount.c
|
||||
./examples/h5_reference.c
|
||||
./examples/h5_ref2reg.c
|
||||
./examples/h5_ref_compat.c
|
||||
./examples/h5_ref_extern.c
|
||||
./examples/h5_reference_deprec.c
|
||||
./examples/h5_ref2reg_deprec.c
|
||||
./examples/h5_shared_mesg.c
|
||||
./examples/ph5example.c
|
||||
./examples/h5_vds.c
|
||||
@ -782,6 +784,7 @@
|
||||
./src/H5Ochunk.c
|
||||
./src/H5Ocont.c
|
||||
./src/H5Ocopy.c
|
||||
./src/H5Ocopy_ref.c
|
||||
./src/H5Odbg.c
|
||||
./src/H5Odeprec.c
|
||||
./src/H5Odrvinfo.c
|
||||
@ -911,6 +914,7 @@
|
||||
./src/H5Tprecis.c
|
||||
./src/H5Tprivate.h
|
||||
./src/H5Tpublic.h
|
||||
./src/H5Tref.c
|
||||
./src/H5Tstrpad.c
|
||||
./src/H5Tvisit.c
|
||||
./src/H5Tvlen.c
|
||||
@ -1107,6 +1111,7 @@
|
||||
./test/null_vol_connector.h
|
||||
./test/ohdr.c
|
||||
./test/objcopy.c
|
||||
./test/objcopy_ref.c
|
||||
./test/page_buffer.c
|
||||
./test/paged_nopersist.h5
|
||||
./test/paged_persist.h5
|
||||
@ -1176,6 +1181,7 @@
|
||||
./test/tmtimeo.h5
|
||||
./test/ttime.c
|
||||
./test/trefer.c
|
||||
./test/trefer_deprec.c
|
||||
./test/trefstr.c
|
||||
./test/tselect.c
|
||||
./test/tsizeslheap.h5
|
||||
|
@ -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
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
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
|
||||
|
14
src/H5Aint.c
14
src/H5Aint.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
|
||||
|
50
src/H5D.c
50
src/H5D.c
@ -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 */
|
||||
|
||||
|
46
src/H5Dint.c
46
src/H5Dint.c
@ -547,7 +547,7 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type)
|
||||
/* To use at least v18 format versions or not */
|
||||
use_at_least_v18 = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18);
|
||||
|
||||
/* Copy the datatype if it's a custom datatype or if it'll change when it's location is changed */
|
||||
/* Copy the datatype if it's a custom datatype or if it'll change when its location is changed */
|
||||
if(!immutable || relocatable || use_at_least_v18) {
|
||||
/* Copy datatype for dataset */
|
||||
if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL)) == NULL)
|
||||
@ -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 */
|
||||
|
||||
|
198
src/H5Ocopy.c
198
src/H5Ocopy.c
@ -85,8 +85,6 @@ static herr_t H5O__copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*
|
||||
hid_t ocpypl_id, hid_t lcpl_id);
|
||||
static herr_t H5O__copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc,
|
||||
const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id);
|
||||
static herr_t H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc,
|
||||
H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info);
|
||||
static herr_t H5O__copy_free_comm_dt_cb(void *item, void *key, void *op_data);
|
||||
static int H5O__copy_comm_dt_cmp(const void *dt1, const void *dt2);
|
||||
static herr_t H5O__copy_search_comm_dt_cb(hid_t group, const char *name,
|
||||
@ -110,7 +108,6 @@ H5FL_DEFINE(H5O_copy_search_comm_dt_key_t);
|
||||
/* Declare a free list to manage haddr_t variables */
|
||||
H5FL_DEFINE(haddr_t);
|
||||
|
||||
|
||||
/*****************************/
|
||||
/* Library Private Variables */
|
||||
/*****************************/
|
||||
@ -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
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);
|
||||
|
38
src/H5Pint.c
38
src/H5Pint.c
@ -169,6 +169,8 @@ hid_t H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID;
|
||||
H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL;
|
||||
hid_t H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
|
||||
H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL;
|
||||
hid_t H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
|
||||
H5P_genclass_t *H5P_CLS_REFERENCE_ACCESS_g = NULL;
|
||||
|
||||
/*
|
||||
* Predefined property lists for each predefined class. These are initialized
|
||||
@ -192,6 +194,7 @@ hid_t H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID;
|
||||
hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID;
|
||||
hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID;
|
||||
hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
|
||||
hid_t H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID;
|
||||
|
||||
/* Root property list class library initialization object */
|
||||
const H5P_libclass_t H5P_CLS_ROOT[1] = {{
|
||||
@ -312,6 +315,25 @@ const H5P_libclass_t H5P_CLS_VINI[1] = {{
|
||||
NULL /* Class close callback info */
|
||||
}};
|
||||
|
||||
/* Reference access property list class library initialization object */
|
||||
/* (move to proper source code file when used for real) */
|
||||
const H5P_libclass_t H5P_CLS_RACC[1] = {{
|
||||
"reference access", /* Class name for debugging */
|
||||
H5P_TYPE_REFERENCE_ACCESS, /* Class type */
|
||||
|
||||
&H5P_CLS_FILE_ACCESS_g, /* Parent class */
|
||||
&H5P_CLS_REFERENCE_ACCESS_g, /* Pointer to class */
|
||||
&H5P_CLS_REFERENCE_ACCESS_ID_g, /* Pointer to class ID */
|
||||
&H5P_LST_REFERENCE_ACCESS_ID_g, /* Pointer to default property list ID */
|
||||
NULL, /* Default property registration routine*/
|
||||
|
||||
NULL, /* Class creation callback */
|
||||
NULL, /* Class creation callback info */
|
||||
NULL, /* Class copy callback */
|
||||
NULL, /* Class copy callback info */
|
||||
NULL, /* Class close callback */
|
||||
NULL /* Class close callback info */
|
||||
}};
|
||||
|
||||
/* Library property list classes defined in other code modules */
|
||||
/* (And not present in src/H5Pprivate.h) */
|
||||
@ -364,7 +386,8 @@ static H5P_libclass_t const * const init_class[] = {
|
||||
H5P_CLS_ACRT, /* Attribute creation */
|
||||
H5P_CLS_AACC, /* Attribute access */
|
||||
H5P_CLS_LCRT, /* Link creation */
|
||||
H5P_CLS_VINI /* VOL initialization */
|
||||
H5P_CLS_VINI, /* VOL initialization */
|
||||
H5P_CLS_RACC /* Reference access */
|
||||
};
|
||||
|
||||
/* Declare a free list to manage the H5P_genclass_t struct */
|
||||
@ -440,7 +463,7 @@ H5P__init_package(void)
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
|
||||
HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
|
||||
|
||||
/*
|
||||
* Initialize the Generic Property class & object groups.
|
||||
@ -564,6 +587,7 @@ H5P_term_package(void)
|
||||
H5P_LST_LINK_CREATE_ID_g =
|
||||
H5P_LST_LINK_ACCESS_ID_g =
|
||||
H5P_LST_VOL_INITIALIZE_ID_g =
|
||||
H5P_LST_REFERENCE_ACCESS_ID_g =
|
||||
H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
@ -594,6 +618,7 @@ H5P_term_package(void)
|
||||
H5P_CLS_LINK_CREATE_g =
|
||||
H5P_CLS_LINK_ACCESS_g =
|
||||
H5P_CLS_VOL_INITIALIZE_g =
|
||||
H5P_CLS_REFERENCE_ACCESS_g =
|
||||
H5P_CLS_FILE_MOUNT_g = NULL;
|
||||
|
||||
H5P_CLS_ROOT_ID_g =
|
||||
@ -616,6 +641,7 @@ H5P_term_package(void)
|
||||
H5P_CLS_LINK_CREATE_ID_g =
|
||||
H5P_CLS_LINK_ACCESS_ID_g =
|
||||
H5P_CLS_VOL_INITIALIZE_ID_g =
|
||||
H5P_CLS_REFERENCE_ACCESS_ID_g =
|
||||
H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
@ -5453,8 +5479,8 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity checks */
|
||||
HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
|
||||
HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_MAP_ACCESS);
|
||||
HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
|
||||
HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_REFERENCE_ACCESS);
|
||||
|
||||
/* Check arguments */
|
||||
if(type == H5P_TYPE_USER)
|
||||
@ -5544,6 +5570,10 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
|
||||
class_id = H5P_CLS_VOL_INITIALIZE_ID_g;
|
||||
break;
|
||||
|
||||
case H5P_TYPE_REFERENCE_ACCESS:
|
||||
class_id = H5P_CLS_REFERENCE_ACCESS_ID_g;
|
||||
break;
|
||||
|
||||
case H5P_TYPE_USER: /* shut compiler warnings up */
|
||||
case H5P_TYPE_ROOT:
|
||||
case H5P_TYPE_MAX_TYPE:
|
||||
|
@ -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 */
|
||||
|
498
src/H5Rdeprec.c
498
src/H5Rdeprec.c
@ -37,14 +37,15 @@
|
||||
#include "H5Ppublic.h" /* Property lists */
|
||||
|
||||
/* Private headers needed by this file */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5CXprivate.h" /* API Contexts */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Gprivate.h" /* Groups */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Gprivate.h" /* Groups */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5Oprivate.h" /* Object headers */
|
||||
#include "H5Oprivate.h" /* Object headers */
|
||||
#include "H5Rpkg.h" /* References */
|
||||
#include "H5Sprivate.h" /* Dataspaces */
|
||||
|
||||
|
||||
/****************/
|
||||
@ -81,53 +82,61 @@
|
||||
/* Local Variables */
|
||||
/*******************/
|
||||
|
||||
|
||||
#ifndef H5_NO_DEPRECATED_SYMBOLS
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Rget_obj_type1
|
||||
*
|
||||
* Purpose: Retrieves the type of the object that an object points to.
|
||||
* Purpose: Retrieves the type of the object that a reference points to.
|
||||
*
|
||||
* Parameters:
|
||||
* id IN: Dataset reference object is in or location ID of
|
||||
* object that the dataset is located within
|
||||
* ref_type IN: Type of reference to query
|
||||
* ref IN: Reference to query
|
||||
*
|
||||
* Return: Success: An object type (as defined in H5Gpublic.h)
|
||||
* Failure: H5G_UNKNOWN
|
||||
* Return: Object type (as defined in H5Gpublic.h) on success
|
||||
* H5G_UNKNOWN on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
H5G_obj_t
|
||||
H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref)
|
||||
{
|
||||
H5VL_object_t *vol_obj = NULL; /* object token of loc_id */
|
||||
H5VL_loc_params_t loc_params;
|
||||
H5O_type_t obj_type; /* Object type */
|
||||
H5G_obj_t ret_value; /* Return value */
|
||||
H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */
|
||||
H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */
|
||||
H5VL_loc_params_t loc_params; /* Location parameters */
|
||||
haddr_t obj_addr; /* Object address */
|
||||
H5O_type_t obj_type; /* Object type */
|
||||
const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */
|
||||
H5G_obj_t ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(H5G_UNKNOWN)
|
||||
H5TRACE3("Go", "iRt*x", id, ref_type, ref);
|
||||
|
||||
/* Check args */
|
||||
if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type")
|
||||
if (ref == NULL)
|
||||
if(buf == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer")
|
||||
if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type")
|
||||
|
||||
/* 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() */
|
||||
|
2032
src/H5Rint.c
2032
src/H5Rint.c
File diff suppressed because it is too large
Load Diff
80
src/H5Rpkg.h
80
src/H5Rpkg.h
@ -36,11 +36,51 @@
|
||||
/* Package Private Macros */
|
||||
/**************************/
|
||||
|
||||
/* Encode flags */
|
||||
#define H5R_IS_EXTERNAL 0x1 /* Set when encoding reference to external file */
|
||||
|
||||
/* Macros for convenience */
|
||||
#define H5R_REF_FILENAME(x) ((x)->ref.obj.filename)
|
||||
#define H5R_REF_ATTRNAME(x) ((x)->ref.attr.name)
|
||||
|
||||
/* Header size */
|
||||
#define H5R_ENCODE_HEADER_SIZE (2 * H5_SIZEOF_UINT8_T)
|
||||
|
||||
/****************************/
|
||||
/* Package Private Typedefs */
|
||||
/****************************/
|
||||
|
||||
/* Object reference */
|
||||
typedef struct H5R_ref_priv_obj_t {
|
||||
H5VL_token_t token; /* Object token */
|
||||
char *filename; /* File name */
|
||||
} H5R_ref_priv_obj_t;
|
||||
|
||||
/* Region reference */
|
||||
typedef struct H5R_ref_priv_reg_t {
|
||||
H5R_ref_priv_obj_t obj; /* Object reference */
|
||||
H5S_t *space; /* Selection */
|
||||
} H5R_ref_priv_reg_t;
|
||||
|
||||
/* Attribute reference */
|
||||
typedef struct H5R_ref_priv_attr_t {
|
||||
H5R_ref_priv_obj_t obj; /* Object reference */
|
||||
char *name; /* Attribute name */
|
||||
} H5R_ref_priv_attr_t;
|
||||
|
||||
/* Generic reference type (keep it cache aligned) */
|
||||
typedef struct H5R_ref_priv_t {
|
||||
union {
|
||||
H5R_ref_priv_obj_t obj;/* Object reference */
|
||||
H5R_ref_priv_reg_t reg;/* Region reference */
|
||||
H5R_ref_priv_attr_t attr;/* Attribute Reference */
|
||||
} ref;
|
||||
hid_t loc_id; /* Cached location identifier */
|
||||
uint32_t encode_size; /* Cached encoding size */
|
||||
int8_t type; /* Reference type */
|
||||
uint8_t token_size; /* Cached token size */
|
||||
char unused[18]; /* Unused */
|
||||
} H5R_ref_priv_t;
|
||||
|
||||
/*****************************/
|
||||
/* Package Private Variables */
|
||||
@ -50,11 +90,41 @@
|
||||
/******************************/
|
||||
/* Package Private Prototypes */
|
||||
/******************************/
|
||||
H5_DLL herr_t H5R__create(void *ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space);
|
||||
H5_DLL hid_t H5R__dereference(H5F_t *file, hid_t dapl_id, H5R_type_t ref_type, const void *_ref);
|
||||
H5_DLL H5S_t *H5R__get_region(H5F_t *file, const void *_ref);
|
||||
H5_DLL herr_t H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type);
|
||||
H5_DLL ssize_t H5R__get_name(H5F_t *file, H5R_type_t ref_type, const void *_ref, char *name, size_t size);
|
||||
H5_DLL herr_t H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref);
|
||||
H5_DLL herr_t H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref);
|
||||
H5_DLL herr_t H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref);
|
||||
H5_DLL herr_t H5R__destroy(H5R_ref_priv_t *ref);
|
||||
|
||||
H5_DLL herr_t H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref);
|
||||
H5_DLL hid_t H5R__get_loc_id(const H5R_ref_priv_t *ref);
|
||||
H5_DLL hid_t H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id);
|
||||
|
||||
H5_DLL H5R_type_t H5R__get_type(const H5R_ref_priv_t *ref);
|
||||
H5_DLL htri_t H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2);
|
||||
H5_DLL herr_t H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref);
|
||||
|
||||
H5_DLL herr_t H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, size_t *token_size);
|
||||
H5_DLL herr_t H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, size_t token_size);
|
||||
H5_DLL herr_t H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space);
|
||||
|
||||
H5_DLL ssize_t H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size);
|
||||
H5_DLL ssize_t H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size);
|
||||
|
||||
H5_DLL herr_t H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, size_t *nalloc, unsigned flags);
|
||||
H5_DLL herr_t H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref);
|
||||
|
||||
/* Native HDF5 specific routines */
|
||||
H5_DLL herr_t H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, const unsigned char *data, size_t data_size);
|
||||
H5_DLL herr_t H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, unsigned char **data_ptr, size_t *data_size);
|
||||
H5_DLL herr_t H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes);
|
||||
|
||||
H5_DLL herr_t H5R__decode_addr_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type, const unsigned char *buf, haddr_t *addr_ptr);
|
||||
|
||||
H5_DLL herr_t H5R__encode_addr_obj_compat(haddr_t obj_addr, unsigned char *buf, size_t *nalloc);
|
||||
H5_DLL herr_t H5R__decode_addr_obj_compat(const unsigned char *buf, size_t *nbytes, haddr_t *obj_addr_ptr);
|
||||
|
||||
H5_DLL herr_t H5R__encode_addr_region_compat(H5F_t *f, haddr_t obj_addr, H5S_t *space, unsigned char *buf, size_t *nalloc);
|
||||
H5_DLL herr_t H5R__decode_addr_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, haddr_t *obj_addr_ptr, H5S_t **space_ptr);
|
||||
|
||||
#endif /* _H5Rpkg_H */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
108
src/H5Rpublic.h
108
src/H5Rpublic.h
@ -26,47 +26,64 @@
|
||||
/* Public Macros */
|
||||
/*****************/
|
||||
|
||||
/* Note! Be careful with the sizes of the references because they should really
|
||||
* depend on the run-time values in the file. Unfortunately, the arrays need
|
||||
* to be defined at compile-time, so we have to go with the worst case sizes
|
||||
* for them. -QAK
|
||||
*/
|
||||
/* Deprecated reference buffer sizes that are kept for backward compatibility */
|
||||
#define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t)
|
||||
|
||||
/* 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
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;
|
||||
|
||||
|
273
src/H5Tconv.c
273
src/H5Tconv.c
@ -1018,6 +1018,9 @@ H5FL_BLK_DEFINE_STATIC(vlen_seq);
|
||||
/* Declare a free list to manage pieces of array data */
|
||||
H5FL_BLK_DEFINE_STATIC(array_seq);
|
||||
|
||||
/* Declare a free list to manage pieces of reference data */
|
||||
H5FL_BLK_DEFINE_STATIC(ref_seq);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T__conv_noop
|
||||
@ -3476,6 +3479,195 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5T__conv_array() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T__conv_ref
|
||||
*
|
||||
* Purpose: Converts between reference datatypes in memory and on disk.
|
||||
* This is a soft conversion function.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
|
||||
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg)
|
||||
{
|
||||
H5T_t *src = NULL; /* source datatype */
|
||||
H5T_t *dst = NULL; /* destination datatype */
|
||||
uint8_t *s = NULL; /* source buffer */
|
||||
uint8_t *d = NULL; /* destination buffer */
|
||||
uint8_t *b = NULL; /* background buffer */
|
||||
ssize_t s_stride, d_stride; /* src and dst strides */
|
||||
ssize_t b_stride; /* bkg stride */
|
||||
size_t safe; /* how many elements are safe to process in each pass */
|
||||
void *conv_buf = NULL; /* temporary conversion buffer */
|
||||
size_t conv_buf_size = 0; /* size of conversion buffer in bytes */
|
||||
size_t elmtno; /* element number counter */
|
||||
herr_t ret_value = SUCCEED; /* return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
switch(cdata->command) {
|
||||
case H5T_CONV_INIT:
|
||||
/*
|
||||
* First, determine if this conversion function applies to the
|
||||
* conversion path SRC_ID-->DST_ID. If not, return failure;
|
||||
* otherwise initialize the `priv' field of `cdata' with
|
||||
* information that remains (almost) constant for this
|
||||
* conversion path.
|
||||
*/
|
||||
if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id)))
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype")
|
||||
if(H5T_REFERENCE != src->shared->type)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype")
|
||||
if(H5T_REFERENCE != dst->shared->type)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype")
|
||||
/* Only allow for source reference that is not an opaque type, destination must be opaque */
|
||||
if(!dst->shared->u.atomic.u.r.opaque)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not an H5T_STD_REF datatype")
|
||||
|
||||
/* Reference types don't need a background buffer */
|
||||
cdata->need_bkg = H5T_BKG_NO;
|
||||
break;
|
||||
|
||||
case H5T_CONV_FREE:
|
||||
break;
|
||||
|
||||
case H5T_CONV_CONV:
|
||||
{
|
||||
/*
|
||||
* Conversion.
|
||||
*/
|
||||
if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
|
||||
|
||||
HDassert(src->shared->u.atomic.u.r.cls);
|
||||
|
||||
/* Initialize source & destination strides */
|
||||
if(buf_stride) {
|
||||
HDassert(buf_stride >= src->shared->size);
|
||||
HDassert(buf_stride >= dst->shared->size);
|
||||
H5_CHECK_OVERFLOW(buf_stride, size_t, ssize_t);
|
||||
s_stride = d_stride = (ssize_t)buf_stride;
|
||||
} /* end if */
|
||||
else {
|
||||
H5_CHECK_OVERFLOW(src->shared->size, size_t, ssize_t);
|
||||
H5_CHECK_OVERFLOW(dst->shared->size, size_t, ssize_t);
|
||||
s_stride = (ssize_t)src->shared->size;
|
||||
d_stride = (ssize_t)dst->shared->size;
|
||||
} /* end else */
|
||||
if(bkg) {
|
||||
if(bkg_stride)
|
||||
b_stride = (ssize_t)bkg_stride;
|
||||
else
|
||||
b_stride = d_stride;
|
||||
} /* end if */
|
||||
else
|
||||
b_stride = 0;
|
||||
|
||||
/* The outer loop of the type conversion macro, controlling which */
|
||||
/* direction the buffer is walked */
|
||||
while(nelmts > 0) {
|
||||
/* Check if we need to go backwards through the buffer */
|
||||
if(d_stride > s_stride) {
|
||||
/* Sanity check */
|
||||
HDassert(s_stride > 0);
|
||||
HDassert(d_stride > 0);
|
||||
HDassert(b_stride >= 0);
|
||||
|
||||
/* Compute the number of "safe" destination elements at */
|
||||
/* the end of the buffer (Those which don't overlap with */
|
||||
/* any source elements at the beginning of the buffer) */
|
||||
safe = nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride);
|
||||
|
||||
/* If we're down to the last few elements, just wrap up */
|
||||
/* with a "real" reverse copy */
|
||||
if(safe < 2) {
|
||||
s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride;
|
||||
d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride;
|
||||
b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride;
|
||||
s_stride = -s_stride;
|
||||
d_stride = -d_stride;
|
||||
b_stride = -b_stride;
|
||||
|
||||
safe = nelmts;
|
||||
} /* end if */
|
||||
else {
|
||||
s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride;
|
||||
d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride;
|
||||
b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride;
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else {
|
||||
/* Single forward pass over all data */
|
||||
s = d = (uint8_t *)buf;
|
||||
b = (uint8_t *)bkg;
|
||||
safe = nelmts;
|
||||
} /* end else */
|
||||
|
||||
for(elmtno = 0; elmtno < safe; elmtno++) {
|
||||
size_t buf_size;
|
||||
hbool_t dst_copy = FALSE;
|
||||
|
||||
/* Get size of references */
|
||||
if(0 == (buf_size = src->shared->u.atomic.u.r.cls->getsize(
|
||||
src->shared->u.atomic.u.r.f, s, src->shared->size,
|
||||
dst->shared->u.atomic.u.r.f, &dst_copy)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect size")
|
||||
|
||||
/* Check if conversion buffer is large enough, resize if necessary. */
|
||||
if(conv_buf_size < buf_size) {
|
||||
conv_buf_size = buf_size;
|
||||
if(NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
|
||||
HDmemset(conv_buf, 0, conv_buf_size);
|
||||
} /* end if */
|
||||
|
||||
if(dst_copy && (src->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) {
|
||||
H5MM_memcpy(conv_buf, s, buf_size);
|
||||
} else {
|
||||
/* Read reference */
|
||||
if(src->shared->u.atomic.u.r.cls->read(
|
||||
src->shared->u.atomic.u.r.f, s, src->shared->size,
|
||||
dst->shared->u.atomic.u.r.f, conv_buf, buf_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data")
|
||||
}
|
||||
|
||||
if(dst_copy && (dst->shared->u.atomic.u.r.loc == H5T_LOC_DISK)) {
|
||||
H5MM_memcpy(d, conv_buf, buf_size);
|
||||
} else {
|
||||
/* Write reference to destination location */
|
||||
if(dst->shared->u.atomic.u.r.cls->write(
|
||||
src->shared->u.atomic.u.r.f, conv_buf, buf_size, src->shared->u.atomic.u.r.rtype,
|
||||
dst->shared->u.atomic.u.r.f, d, dst->shared->size, b) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data")
|
||||
}
|
||||
|
||||
/* Advance pointers */
|
||||
s += s_stride;
|
||||
d += d_stride;
|
||||
b += b_stride;
|
||||
} /* end for */
|
||||
|
||||
/* Decrement number of elements left to convert */
|
||||
nelmts -= safe;
|
||||
} /* end while */
|
||||
} /* end case */
|
||||
break;
|
||||
|
||||
default: /* Some other command we don't know about yet.*/
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command")
|
||||
} /* end switch */
|
||||
|
||||
done:
|
||||
/* Release the conversion buffer (always allocated, except on errors) */
|
||||
if(conv_buf)
|
||||
conv_buf = H5FL_BLK_FREE(ref_seq, conv_buf);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5T__conv_ref() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T__conv_i_i
|
||||
@ -9307,3 +9499,84 @@ H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order)
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T_reclaim
|
||||
*
|
||||
* Purpose: Frees the buffers allocated for storing variable-length data
|
||||
* in memory. Only frees the VL data in the selection defined in the
|
||||
* dataspace.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5T_reclaim(hid_t type_id, H5S_t *space, void *buf)
|
||||
{
|
||||
H5T_t *type; /* Datatype */
|
||||
H5S_sel_iter_op_t dset_op; /* Operator for iteration */
|
||||
H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */
|
||||
herr_t ret_value = FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/* Check args */
|
||||
HDassert(H5I_DATATYPE == H5I_get_type(type_id));
|
||||
HDassert(space);
|
||||
HDassert(buf);
|
||||
|
||||
if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
|
||||
|
||||
/* Get the allocation info */
|
||||
if(H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info")
|
||||
|
||||
/* Call H5S_select_iterate with args, etc. */
|
||||
dset_op.op_type = H5S_SEL_ITER_OP_LIB;
|
||||
dset_op.u.lib_op = H5T_reclaim_cb;
|
||||
|
||||
ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5T_reclaim() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T_reclaim_cb
|
||||
*
|
||||
* Purpose: Iteration callback to reclaim conversion allocated memory for a
|
||||
* buffer element.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned H5_ATTR_UNUSED ndim,
|
||||
const hsize_t H5_ATTR_UNUSED *point, void *op_data)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(elem);
|
||||
HDassert(dt);
|
||||
|
||||
if(dt->shared->type == H5T_REFERENCE) {
|
||||
if(H5T_ref_reclaim(elem, dt) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim ref elements")
|
||||
} else {
|
||||
HDassert(op_data);
|
||||
|
||||
/* Allow vlen reclaim to recurse into that routine */
|
||||
if(H5T_vlen_reclaim(elem, dt, (H5T_vlen_alloc_info_t *)op_data) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements")
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5T_reclaim_cb() */
|
||||
|
@ -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)
|
||||
|
81
src/H5Tpkg.h
81
src/H5Tpkg.h
@ -95,9 +95,14 @@
|
||||
/* This version also encodes array types more efficiently */
|
||||
#define H5O_DTYPE_VERSION_3 3
|
||||
|
||||
/* This is the version that adds support for new reference types and prevents
|
||||
* older versions of the library to attempt reading unknown types.
|
||||
*/
|
||||
#define H5O_DTYPE_VERSION_4 4
|
||||
|
||||
/* The latest version of the format. Look through the 'encode helper' routine
|
||||
* and 'size' callback for places to change when updating this. */
|
||||
#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_3
|
||||
#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_4
|
||||
|
||||
|
||||
/* Flags for visiting datatype */
|
||||
@ -175,37 +180,52 @@ struct H5T_path_t {
|
||||
H5T_cdata_t cdata; /*data for this function */
|
||||
};
|
||||
|
||||
/* Reference function pointers */
|
||||
typedef size_t (*H5T_ref_getsizefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy);
|
||||
typedef herr_t (*H5T_ref_readfunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size);
|
||||
typedef herr_t (*H5T_ref_writefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5R_type_t src_type, H5F_t *dst_f, void *dst_buf, size_t dst_size, void *bg_buf);
|
||||
|
||||
typedef struct H5T_ref_class_t {
|
||||
H5T_ref_getsizefunc_t getsize; /* get reference size (bytes) */
|
||||
H5T_ref_readfunc_t read; /* read reference into buffer */
|
||||
H5T_ref_writefunc_t write; /* write reference from buffer */
|
||||
} H5T_ref_class_t;
|
||||
|
||||
typedef struct H5T_atomic_t {
|
||||
H5T_order_t order; /*byte order */
|
||||
size_t prec; /*precision in bits */
|
||||
size_t offset; /*bit position of lsb of value */
|
||||
H5T_pad_t lsb_pad;/*type of lsb padding */
|
||||
H5T_pad_t msb_pad;/*type of msb padding */
|
||||
H5T_order_t order; /* byte order */
|
||||
size_t prec; /* precision in bits */
|
||||
size_t offset; /* bit position of lsb of value */
|
||||
H5T_pad_t lsb_pad; /* type of lsb padding */
|
||||
H5T_pad_t msb_pad; /* type of msb padding */
|
||||
union {
|
||||
struct {
|
||||
H5T_sign_t sign; /*type of integer sign */
|
||||
} i; /*integer; integer types */
|
||||
struct {
|
||||
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
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() */
|
127
src/H5Tvlen.c
127
src/H5Tvlen.c
@ -26,15 +26,13 @@
|
||||
/***********/
|
||||
/* Headers */
|
||||
/***********/
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5CXprivate.h" /* API Contexts */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Fprivate.h" /* File access */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5CXprivate.h" /* API Contexts */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Fpkg.h" /* File */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
#include "H5Tpkg.h" /* Datatypes */
|
||||
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
#include "H5Tpkg.h" /* Datatypes */
|
||||
|
||||
/****************/
|
||||
/* Local Macros */
|
||||
@ -54,7 +52,6 @@
|
||||
/********************/
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
static herr_t H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info);
|
||||
|
||||
/* Memory-based VL sequence callbacks */
|
||||
static herr_t H5T__vlen_mem_seq_getlen(H5F_t *f, const void *_vl, size_t *len);
|
||||
@ -100,7 +97,7 @@ static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl);
|
||||
/* Local Variables */
|
||||
/*******************/
|
||||
|
||||
/* Class for VL seqences in memory */
|
||||
/* Class for VL sequences in memory */
|
||||
static const H5T_vlen_class_t H5T_vlen_mem_seq_g = {
|
||||
H5T__vlen_mem_seq_getlen, /* 'getlen' */
|
||||
H5T__vlen_mem_seq_getptr, /* 'getptr' */
|
||||
@ -122,7 +119,7 @@ static const H5T_vlen_class_t H5T_vlen_mem_str_g = {
|
||||
NULL /* 'delete' */
|
||||
};
|
||||
|
||||
/* Class for both VL strings and seqences in file */
|
||||
/* Class for both VL strings and sequences in file */
|
||||
static const H5T_vlen_class_t H5T_vlen_disk_g = {
|
||||
H5T__vlen_disk_getlen, /* 'getlen' */
|
||||
NULL, /* 'getptr' */
|
||||
@ -1085,38 +1082,35 @@ done:
|
||||
} /* end H5T__vlen_disk_delete() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5T__vlen_reclaim_recurse
|
||||
PURPOSE
|
||||
Internal recursive routine to free VL datatypes
|
||||
USAGE
|
||||
herr_t H5T__vlen_reclaim_recurse(elem,dt)
|
||||
void *elem; IN/OUT: Pointer to the dataset element
|
||||
H5T_t *dt; IN: Datatype of dataset element
|
||||
|
||||
RETURNS
|
||||
SUCCEED/FAIL
|
||||
DESCRIPTION
|
||||
Frees any dynamic memory used by VL datatypes in the current dataset
|
||||
element. Performs a recursive depth-first traversal of all compound
|
||||
datatypes to free all VL datatype information allocated by any field.
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
static herr_t
|
||||
H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info)
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5T_vlen_reclaim
|
||||
*
|
||||
* Purpose: Internal recursive routine to free VL datatypes
|
||||
*
|
||||
* Return: Non-negative on success / Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Friday, August 15, 2019
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5T_vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info)
|
||||
{
|
||||
unsigned u; /* Local index variable */
|
||||
H5MM_free_t free_func; /* Free function */
|
||||
void *free_info; /* Free info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(elem);
|
||||
HDassert(dt);
|
||||
HDassert(alloc_info);
|
||||
|
||||
free_func = alloc_info->free_func;
|
||||
free_info = alloc_info->free_info;
|
||||
|
||||
/* Check the datatype of this element */
|
||||
switch(dt->shared->type) {
|
||||
@ -1128,7 +1122,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo
|
||||
/* Calculate the offset member and recurse on it */
|
||||
for(u = 0; u < dt->shared->u.array.nelem; u++) {
|
||||
off = ((uint8_t *)elem) + u * (dt->shared->parent->shared->size);
|
||||
if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0)
|
||||
if(H5T_reclaim_cb(off, dt->shared->parent, 0, NULL, alloc_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free array element")
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
@ -1143,7 +1137,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo
|
||||
|
||||
/* Calculate the offset member and recurse on it */
|
||||
off = ((uint8_t *)elem) + dt->shared->u.compnd.memb[u].offset;
|
||||
if(H5T__vlen_reclaim_recurse(off, dt->shared->u.compnd.memb[u].type, free_func, free_info) < 0)
|
||||
if(H5T_reclaim_cb(off, dt->shared->u.compnd.memb[u].type, 0, NULL, alloc_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free compound field")
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
@ -1163,7 +1157,7 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo
|
||||
/* Calculate the offset of each array element and recurse on it */
|
||||
while(vl->len > 0) {
|
||||
off = ((uint8_t *)vl->p) + (vl->len - 1) * dt->shared->parent->shared->size;
|
||||
if(H5T__vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0)
|
||||
if(H5T_reclaim_cb(off, dt->shared->parent, 0, NULL, alloc_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free VL element")
|
||||
vl->len--;
|
||||
} /* end while */
|
||||
@ -1193,11 +1187,11 @@ H5T__vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, vo
|
||||
case H5T_STRING:
|
||||
case H5T_BITFIELD:
|
||||
case H5T_OPAQUE:
|
||||
case H5T_REFERENCE:
|
||||
case H5T_ENUM:
|
||||
break;
|
||||
|
||||
/* Should never have these values */
|
||||
case H5T_REFERENCE:
|
||||
case H5T_NO_CLASS:
|
||||
case H5T_NCLASSES:
|
||||
default:
|
||||
@ -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
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);
|
||||
|
2200
test/trefer.c
2200
test/trefer.c
File diff suppressed because it is too large
Load Diff
1827
test/trefer_deprec.c
Normal file
1827
test/trefer_deprec.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user