diff options
131 files changed, 12744 insertions, 3373 deletions
@@ -167,8 +167,10 @@ ./examples/h5_select.c ./examples/h5_attribute.c ./examples/h5_mount.c -./examples/h5_reference.c -./examples/h5_ref2reg.c +./examples/h5_ref_compat.c +./examples/h5_ref_extern.c +./examples/h5_reference_deprec.c +./examples/h5_ref2reg_deprec.c ./examples/h5_shared_mesg.c ./examples/ph5example.c ./examples/h5_vds.c @@ -782,6 +784,7 @@ ./src/H5Ochunk.c ./src/H5Ocont.c ./src/H5Ocopy.c +./src/H5Ocopy_ref.c ./src/H5Odbg.c ./src/H5Odeprec.c ./src/H5Odrvinfo.c @@ -911,6 +914,7 @@ ./src/H5Tprecis.c ./src/H5Tprivate.h ./src/H5Tpublic.h +./src/H5Tref.c ./src/H5Tstrpad.c ./src/H5Tvisit.c ./src/H5Tvlen.c @@ -925,6 +929,7 @@ ./src/H5VLnative.c ./src/H5VLnative.h ./src/H5VLnative_attr.c +./src/H5VLnative_blob.c ./src/H5VLnative_dataset.c ./src/H5VLnative_datatype.c ./src/H5VLnative_file.c @@ -1106,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 @@ -1175,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 @@ -79,7 +79,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", @@ -100,6 +102,7 @@ $Source = ""; "unsigned long long" => "UL", "H5VL_attr_get_t" => "Va", "H5VL_attr_specific_t" => "Vb", + "H5VL_blob_specific_t" => "VB", "H5VL_class_value_t" => "VC", "H5VL_dataset_get_t" => "Vc", "H5VL_dataset_specific_t" => "Vd", diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp index db14577..a071289 100644 --- a/c++/src/H5DataSet.cpp +++ b/c++/src/H5DataSet.cpp @@ -369,10 +369,10 @@ void DataSet::vlenReclaim(const DataType& type, const DataSpace& space, const DS hid_t space_id = space.getId(); hid_t xfer_plist_id = xfer_plist.getId(); - herr_t ret_value = H5Dvlen_reclaim(type_id, space_id, xfer_plist_id, buf); + herr_t ret_value = H5Treclaim(type_id, space_id, xfer_plist_id, buf); if (ret_value < 0) { - throw DataSetIException("DataSet::vlenReclaim", "H5Dvlen_reclaim failed"); + throw DataSetIException("DataSet::vlenReclaim", "H5Treclaim failed"); } } @@ -397,10 +397,10 @@ void DataSet::vlenReclaim(void* buf, const DataType& type, const DataSpace& spac hid_t space_id = space.getId(); hid_t xfer_plist_id = xfer_plist.getId(); - herr_t ret_value = H5Dvlen_reclaim(type_id, space_id, xfer_plist_id, buf); + herr_t ret_value = H5Treclaim(type_id, space_id, xfer_plist_id, buf); if (ret_value < 0) { - throw DataSetIException("DataSet::vlenReclaim", "H5Dvlen_reclaim failed"); + throw DataSetIException("DataSet::vlenReclaim", "H5Treclaim failed"); } } diff --git a/c++/src/H5DxferProp.h b/c++/src/H5DxferProp.h index 6955778..e53a03b 100644 --- a/c++/src/H5DxferProp.h +++ b/c++/src/H5DxferProp.h @@ -66,7 +66,7 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { void getTypeConvCB(H5T_conv_except_func_t *op, void **user_data) const; // Sets the memory manager for variable-length datatype - // allocation in H5Dread and H5Dvlen_reclaim. + // allocation in H5Dread and H5Treclaim. void setVlenMemManager(H5MM_allocate_t alloc, void* alloc_info, H5MM_free_t free, void* free_info) const; @@ -75,7 +75,7 @@ class H5_DLLCPP DSetMemXferPropList : public PropList { void setVlenMemManager() const; // Gets the memory manager for variable-length datatype - // allocation in H5Dread and H5Tvlen_reclaim. + // allocation in H5Dread and H5Treclaim. void getVlenMemManager(H5MM_allocate_t& alloc, void** alloc_info, H5MM_free_t& free, void** free_info) const; diff --git a/config/cmake/CTestCustom.cmake b/config/cmake/CTestCustom.cmake index a05f906..7ee5737 100644 --- a/config/cmake/CTestCustom.cmake +++ b/config/cmake/CTestCustom.cmake @@ -11,8 +11,8 @@ # set (CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 3000) # Allow full output to go to CDash set to 0 -SET(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 50000) -SET(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 50000) +set (CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 50000) +set (CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 50000) # WARNING! This could be a lot of output and could overwhelm CDash and the # MySQL DB so this might not be a good idea! diff --git a/config/toolchain/mingw64.cmake b/config/toolchain/mingw64.cmake index 721c39a..fde5e38 100644 --- a/config/toolchain/mingw64.cmake +++ b/config/toolchain/mingw64.cmake @@ -1,10 +1,14 @@ +set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) set (CMAKE_SYSTEM_NAME Windows) -set (CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) -set (CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) -set (CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) -set (CMAKE_Fortran_COMPILER x86_64-w64-mingw32-gfortran) -set (CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) +set (CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set (CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set (CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) +set (CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran) +set (CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /usr/local/${TOOLCHAIN_PREFIX}) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set (CMAKE_CROSSCOMPILING_EMULATOR wine64) + +include_directories(/usr/local/${TOOLCHAIN_PREFIX}/include) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS On CACHE BOOL "Export windows symbols") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6e1f79d..9f42f95 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,9 +23,11 @@ set (examples h5_select h5_attribute h5_mount - h5_reference + h5_ref_extern + h5_ref_compat + h5_reference_deprec h5_drivers - h5_ref2reg + h5_ref2reg_deprec h5_extlink h5_elink_unix2win h5_shared_mesg diff --git a/examples/Makefile.am b/examples/Makefile.am index a0d2b00..5b428cd 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -34,8 +34,9 @@ INSTALL_TOP_FILES = README EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \ h5_crtgrpd h5_subset h5_cmprss h5_rdwt h5_crtgrpar h5_extend \ h5_crtatt h5_crtgrp h5_crtdat \ - h5_group h5_select h5_attribute h5_mount h5_reference h5_drivers \ - h5_ref2reg h5_extlink h5_elink_unix2win h5_shared_mesg h5_vds h5_vds-exc \ + h5_group h5_select h5_attribute h5_mount h5_reference_deprec h5_drivers \ + h5_ref_extern h5_ref_compat \ + h5_ref2reg_deprec h5_extlink h5_elink_unix2win h5_shared_mesg h5_vds h5_vds-exc \ h5_vds-exclim h5_vds-eiger h5_vds-simpleIO h5_vds-percival \ h5_vds-percival-unlim h5_vds-percival-unlim-maxmin TEST_SCRIPT=testh5cc.sh @@ -47,8 +48,9 @@ INSTALL_FILES = h5_write.c h5_read.c h5_extend_write.c h5_chunk_read.c \ h5_crtgrpd.c h5_subset.c h5_cmprss.c h5_rdwt.c h5_crtgrpar.c \ h5_extend.c h5_crtatt.c h5_crtgrp.c h5_crtdat.c \ h5_compound.c h5_group.c h5_select.c h5_attribute.c h5_mount.c \ - h5_reference.c h5_drivers.c h5_extlink.c h5_elink_unix2win.c \ - h5_ref2reg.c h5_shared_mesg.c ph5example.c h5_vds.c h5_vds-exc.c \ + h5_reference_deprec.c h5_drivers.c h5_extlink.c h5_elink_unix2win.c \ + h5_ref_extern.c h5_ref_compat.c \ + h5_ref2reg_deprec.c h5_shared_mesg.c ph5example.c h5_vds.c h5_vds-exc.c \ h5_vds-exclim.c h5_vds-eiger.c h5_vds-simpleIO.c h5_vds-percival.c \ h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin.c @@ -111,8 +113,10 @@ h5_read: $(srcdir)/h5_read.c h5_select: $(srcdir)/h5_select.c h5_attribute: $(srcdir)/h5_attribute.c h5_mount: $(srcdir)/h5_mount.c -h5_reference: $(srcdir)/h5_reference.c -h5_ref2reg: $(srcdir)/h5_ref2reg.c +h5_ref_compat: $(srcdir)/h5_ref_compat.c +h5_ref_extern: $(srcdir)/h5_ref_extern.c +h5_reference_deprec: $(srcdir)/h5_reference_deprec.c +h5_ref2reg_deprec: $(srcdir)/h5_ref2reg_deprec.c h5_drivers: $(srcdir)/h5_drivers.c ph5example: $(srcdir)/ph5example.c h5_dtransform: $(srcdir)/h5_dtransform.c diff --git a/examples/h5_ref2reg.c b/examples/h5_ref2reg_deprec.c index dc2964c..dc2964c 100644 --- a/examples/h5_ref2reg.c +++ b/examples/h5_ref2reg_deprec.c diff --git a/examples/h5_ref_compat.c b/examples/h5_ref_compat.c new file mode 100644 index 0000000..a1fbf96 --- /dev/null +++ b/examples/h5_ref_compat.c @@ -0,0 +1,90 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * The example below illustrates the use of the new API with a file that was + * written using the old-style reference API, showing how one can take + * advantage of the automatic type conversion from old reference type to new + * reference type. + */ + +#include <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; +} + diff --git a/examples/h5_ref_extern.c b/examples/h5_ref_extern.c new file mode 100644 index 0000000..4327a06 --- /dev/null +++ b/examples/h5_ref_extern.c @@ -0,0 +1,94 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* + * The example below illustrates the use of the new API with files that are + * opened read-only. Created references to the objects in that file are + * stored into a separate file, and accessed from that file, without the user + * explicitly opening the original file that was referenced. + */ + +#include <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; +} + diff --git a/examples/h5_reference.c b/examples/h5_reference_deprec.c index 32a5f59..32a5f59 100644 --- a/examples/h5_reference.c +++ b/examples/h5_reference_deprec.c diff --git a/examples/run-c-ex.sh.in b/examples/run-c-ex.sh.in index 030d967..b561617 100644 --- a/examples/run-c-ex.sh.in +++ b/examples/run-c-ex.sh.in @@ -135,12 +135,16 @@ then rm h5_attribute &&\ RunTest h5_mount &&\ rm h5_mount &&\ - RunTest h5_reference &&\ - rm h5_reference &&\ + RunTest h5_reference_deprec &&\ + rm h5_reference_deprec &&\ + RunTest h5_ref_extern &&\ + rm h5_ref_extern &&\ + RunTest h5_ref_compat &&\ + rm h5_ref_compat &&\ RunTest h5_drivers &&\ rm h5_drivers &&\ - RunTest h5_ref2reg &&\ - rm h5_ref2reg &&\ + RunTest h5_ref2reg_deprec &&\ + rm h5_ref2reg_deprec &&\ RunTest h5_extlink &&\ rm h5_extlink &&\ RunTest h5_elink_unix2win &&\ diff --git a/fortran/src/H5Df.c b/fortran/src/H5Df.c index 14fac6b..827baa1 100644 --- a/fortran/src/H5Df.c +++ b/fortran/src/H5Df.c @@ -544,7 +544,7 @@ h5dvlen_get_max_len_c ( hid_t_f *dset_id , hid_t_f *type_id, hid_t_f *space_id, c_len = 0; for (i=0; i < num_elem; i++) c_len = H5_MAX(c_len, c_buf[i].len); *len = (size_t_f)c_len; - H5Dvlen_reclaim(c_type_id, c_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_type_id, c_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: @@ -690,7 +690,7 @@ h5dread_vl_integer_c ( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_sp len[i] = (size_t_f)c_buf[i].len; memcpy(&buf[i*max_len], c_buf[i].p, c_buf[i].len*sizeof(int_f)); } - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); @@ -779,7 +779,7 @@ h5dwrite_vl_string_c( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_spa if( status < 0) goto DONE; ret_value = 0; DONE: - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); HDfree(c_buf); HDfree(tmp); return ret_value; @@ -861,7 +861,7 @@ h5dread_vl_string_c( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_spac } HD5packFstring(tmp, _fcdtocp(buf), (size_t)(max_len*num_elem)); ret_value = 0; - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); HDfree(c_buf); HDfree(tmp); return ret_value; @@ -1006,7 +1006,7 @@ h5dread_vl_real_c ( hid_t_f *dset_id , hid_t_f *mem_type_id, hid_t_f *mem_space memcpy(&buf[i*max_len], c_buf[i].p, c_buf[i].len*sizeof(real_f)); } - H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); + H5Treclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); @@ -1284,7 +1284,7 @@ h5dget_access_plist_c (hid_t_f *dset_id, hid_t_f *plist_id) * NAME * h5dvlen_reclaim_c * PURPOSE - * Call H5Dvlen_reclaim + * Call H5Treclaim * INPUTS * type_id - Identifier of the datatype. * space_id - Identifier of the dataspace. @@ -1307,9 +1307,9 @@ h5dvlen_reclaim_c(hid_t_f *type_id, hid_t_f *space_id, hid_t_f *plist_id, void * herr_t status; /* - * Call H5Dvlen_reclaim function. + * Call H5Treclaim function. */ - status = H5Dvlen_reclaim((hid_t)*type_id, (hid_t)*space_id, (hid_t)*plist_id, buf); + status = H5Treclaim((hid_t)*type_id, (hid_t)*space_id, (hid_t)*plist_id, buf); if ( status < 0 ) return ret_value; ret_value = 0; diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index 067992f..b24f887 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -275,7 +275,7 @@ herr_t H5DSattach_scale(hid_t did, goto out; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -361,7 +361,7 @@ herr_t H5DSattach_scale(hid_t did, goto out; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -753,7 +753,7 @@ herr_t H5DSdetach_scale(hid_t did, } /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; @@ -896,7 +896,7 @@ out: dsbuf = NULL; } if(buf) { - /* Failure occured before H5Dvlen_reclaim was called; + /* Failure occured before H5Treclaim was called; free the pointers allocated when we read data in */ for(i = 0; i < rank; i++) { if(buf[i].p) @@ -1073,7 +1073,7 @@ htri_t H5DSis_attached(hid_t did, /* close */ - if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0) + if (H5Treclaim(tid,sid,H5P_DEFAULT,buf) < 0) goto out; if (H5Sclose(sid) < 0) goto out; @@ -1373,7 +1373,7 @@ herr_t H5DSiterate_scales(hid_t did, } /* if */ /* close */ - if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0) + if (H5Treclaim(tid,sid,H5P_DEFAULT,buf) < 0) goto out; if (H5Sclose(sid) < 0) goto out; @@ -1391,7 +1391,7 @@ herr_t H5DSiterate_scales(hid_t did, out: H5E_BEGIN_TRY { if(buf) { - H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf); + H5Treclaim(tid,sid,H5P_DEFAULT,buf); HDfree(buf); } H5Sclose(sid); @@ -2095,7 +2095,7 @@ int H5DSget_num_scales(hid_t did, nscales = (int)buf[idx].len; /* close */ - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) + if(H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) goto out; if(H5Sclose(sid) < 0) goto out; diff --git a/hl/src/H5PT.c b/hl/src/H5PT.c index 07d8bfb..f413bea 100644 --- a/hl/src/H5PT.c +++ b/hl/src/H5PT.c @@ -940,7 +940,7 @@ herr_t H5PTfree_vlen_buff( hid_t table_id, goto error; /* Free the memory. If this succeeds, ret_value should be 0. */ - if((ret_value = H5Dvlen_reclaim(table->type_id, space_id, H5P_DEFAULT, buff)) < 0) + if((ret_value = H5Treclaim(table->type_id, space_id, H5P_DEFAULT, buff)) < 0) goto error; /* If the dataspace cannot be closed, return -2 to indicate that memory */ diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index adb50f1..09fb223 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -2155,7 +2155,10 @@ public class H5 implements java.io.Serializable { * - Error from the HDF-5 Library. * @exception NullPointerException * - buf is null. + * + * @deprecated As of HDF5 1.12.0 in favor of H5Treclaim **/ + @Deprecated public synchronized static native int H5Dvlen_reclaim(long type_id, long space_id, long xfer_plist_id, byte[] buf) throws HDF5LibraryException, NullPointerException; @@ -3093,6 +3096,7 @@ public class H5 implements java.io.Serializable { * * @deprecated As of HDF5 1.10.5 in favor of H5Fis_accessible. **/ + @Deprecated public synchronized static native boolean H5Fis_hdf5(String name) throws HDF5LibraryException, NullPointerException; /** @@ -10313,6 +10317,28 @@ public class H5 implements java.io.Serializable { public synchronized static native int H5Tpack(long type_id) throws HDF5LibraryException; /** + * H5Treclaim reclaims buffer used for VL data. + * + * @param type_id + * Identifier of the datatype. + * @param space_id + * Identifier of the dataspace. + * @param xfer_plist_id + * Identifier of a transfer property list for this I/O operation. + * @param buf + * Buffer with data to be reclaimed. + * + * @return a non-negative value if successful + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. + * @exception NullPointerException + * - buf is null. + **/ + public synchronized static native int H5Treclaim(long type_id, long space_id, long xfer_plist_id, byte[] buf) + throws HDF5LibraryException, NullPointerException; + + /** * H5Tvlen_create creates a new variable-length (VL) dataype. * * @param base_id diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index eaa356e..9f22665 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -94,11 +94,18 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1name (JNIEnv *env, jclass clss, jlong loc_id, jstring name) { +#ifndef H5_NO_DEPRECATED_SYMBOLS const char *attrName = NULL; +#endif hid_t attr_id = H5I_INVALID_HID; UNUSED(clss); +#ifdef H5_NO_DEPRECATED_SYMBOLS + UNUSED(loc_id); + UNUSED(name); + H5_UNIMPLEMENTED(ENVONLY, "H5Aopen_name: not implemented"); +#else if (NULL == name) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aopen_name: attribute name is null"); @@ -106,10 +113,13 @@ Java_hdf_hdf5lib_H5__1H5Aopen_1name if((attr_id = H5Aopen_name((hid_t)loc_id, attrName)) < 0) H5_LIBRARY_ERROR(ENVONLY); +#endif done: +#ifndef H5_NO_DEPRECATED_SYMBOLS if (attrName) UNPIN_JAVA_STRING(ENVONLY, name, attrName); +#endif return (jlong)attr_id; } /* end Java_hdf_hdf5lib_H5__1H5Aopen_1name */ @@ -127,8 +137,14 @@ Java_hdf_hdf5lib_H5__1H5Aopen_1idx UNUSED(clss); +#ifdef H5_NO_DEPRECATED_SYMBOLS + UNUSED(loc_id); + UNUSED(idx); + H5_UNIMPLEMENTED(ENVONLY, "H5Aopen_idx: not implemented"); +#else if ((attr_id = H5Aopen_idx((hid_t) loc_id, (unsigned int) idx)) < 0) H5_LIBRARY_ERROR(ENVONLY); +#endif done: return (jlong)attr_id; @@ -1028,7 +1044,7 @@ H5AreadVL_str /* * When repeatedly reading a dataset with a large number of strs (e.g., 1,000,000 strings), - * H5Dvlen_reclaim() may crash on Windows because the Java GC will not be able to collect + * H5Treclaim() may crash on Windows because the Java GC will not be able to collect * free space in time. Instead, we use "H5free_memory(strs[i])" to free individual strings * once done. */ @@ -1125,7 +1141,7 @@ done: if (h5str.s) h5str_free(&h5str); if (readBuf) { - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, readBuf); + H5Treclaim(tid, sid, H5P_DEFAULT, readBuf); HDfree(readBuf); } if (sid >= 0) @@ -1313,7 +1329,7 @@ H5AwriteVL_asstr /* * When repeatedly writing a dataset with a large number of strs (e.g., 1,000,000 strings), - * H5Dvlen_reclaim() may crash on Windows because the Java GC will not be able to collect + * H5Treclaim() may crash on Windows because the Java GC will not be able to collect * free space in time. Instead, we use "H5free_memory(strs[i])" to free individual strings * once done. */ @@ -1356,7 +1372,7 @@ done: if (utf8) UNPIN_JAVA_STRING(ENVONLY, jstr, utf8); if (writeBuf) { - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, writeBuf); + H5Treclaim(tid, sid, H5P_DEFAULT, writeBuf); HDfree(writeBuf); } if (sid >= 0) @@ -1512,8 +1528,13 @@ Java_hdf_hdf5lib_H5_H5Aget_1num_1attrs UNUSED(clss); +#ifdef H5_NO_DEPRECATED_SYMBOLS + UNUSED(loc_id); + H5_UNIMPLEMENTED(ENVONLY, "H5Aget_num_attrs: not implemented"); +#else if ((retVal = H5Aget_num_attrs((hid_t)loc_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); +#endif done: return (jint)retVal; diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 5500847..b395189 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -340,12 +340,21 @@ Java_hdf_hdf5lib_H5_H5Dvlen_1reclaim (JNIEnv *env, jclass clss, jlong type_id, jlong space_id, jlong xfer_plist_id, jbyteArray buf) { +#ifndef H5_NO_DEPRECATED_SYMBOLS jboolean vlenBufIsCopy; jbyte *vlenBuf = NULL; +#endif herr_t status = FAIL; UNUSED(clss); +#ifdef H5_NO_DEPRECATED_SYMBOLS + UNUSED(type_id); + UNUSED(space_id); + UNUSED(xfer_plist_id); + UNUSED(buf); + H5_UNIMPLEMENTED(ENVONLY, "H5Dvlen_reclaim: not implemented"); +#else if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dvlen_reclaim: buffer is NULL"); @@ -353,10 +362,13 @@ Java_hdf_hdf5lib_H5_H5Dvlen_1reclaim if ((status = H5Dvlen_reclaim((hid_t)type_id, (hid_t)space_id, (hid_t)xfer_plist_id, vlenBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); +#endif done: +#ifndef H5_NO_DEPRECATED_SYMBOLS if (vlenBuf) UNPIN_BYTE_ARRAY(ENVONLY, buf, vlenBuf, (status < 0) ? JNI_ABORT : 0); +#endif return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Dvlen_1reclaim */ @@ -1172,7 +1184,7 @@ H5DreadVL_str /* * When repeatedly reading a dataset with a large number of strs (e.g., 1,000,000 strings), - * H5Dvlen_reclaim() may crash on Windows because the Java GC will not be able to collect + * H5Treclaim() may crash on Windows because the Java GC will not be able to collect * free space in time. Instead, we use "H5free_memory(strs[i])" to free individual strings * once done. */ @@ -1230,7 +1242,7 @@ H5DreadVL_asstr if (mem_space == H5S_ALL) { /* - * Retrieve a valid dataspace for H5Dvlen_reclaim(). + * Retrieve a valid dataspace for H5Treclaim(). */ if ((mem_space = H5Dget_space(did)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1285,7 +1297,7 @@ done: if (h5str.s) h5str_free(&h5str); if (readBuf) { - H5Dvlen_reclaim(tid, mem_space, xfer_plist_id, readBuf); + H5Treclaim(tid, mem_space, xfer_plist_id, readBuf); HDfree(readBuf); } if (close_mem_space) @@ -1504,7 +1516,7 @@ H5DwriteVL_asstr if (mem_space == H5S_ALL) { /* - * Retrieve a valid dataspace for H5Dvlen_reclaim(). + * Retrieve a valid dataspace for H5Treclaim(). */ if ((mem_space = H5Dget_space(did)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1565,7 +1577,7 @@ done: if (utf8) UNPIN_JAVA_STRING(ENVONLY, obj, utf8); if (writeBuf) { - H5Dvlen_reclaim(tid, mem_space, xfer_plist_id, writeBuf); + H5Treclaim(tid, mem_space, xfer_plist_id, writeBuf); HDfree(writeBuf); } if (close_mem_space) diff --git a/java/src/jni/h5fImp.c b/java/src/jni/h5fImp.c index 4fd6807..2eb3ad5 100644 --- a/java/src/jni/h5fImp.c +++ b/java/src/jni/h5fImp.c @@ -156,15 +156,17 @@ JNIEXPORT jboolean JNICALL Java_hdf_hdf5lib_H5_H5Fis_1hdf5 (JNIEnv *env, jclass clss, jstring name) { +#ifndef H5_NO_DEPRECATED_SYMBOLS const char *fileName = NULL; +#endif htri_t bval = JNI_FALSE; UNUSED(clss); #ifdef H5_NO_DEPRECATED_SYMBOLS + UNUSED(name); H5_UNIMPLEMENTED(ENVONLY, "H5Fis_hdf5: not implemented"); -#endif - +#else if (NULL == name) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fis_hdf5: file name is NULL"); @@ -174,10 +176,13 @@ Java_hdf_hdf5lib_H5_H5Fis_1hdf5 H5_LIBRARY_ERROR(ENVONLY); bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; +#endif done: +#ifndef H5_NO_DEPRECATED_SYMBOLS if (fileName) UNPIN_JAVA_STRING(ENVONLY, name, fileName); +#endif return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Fis_1hdf5 */ diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index 460f12e..3302b7d 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -980,6 +980,37 @@ done: /* * Class: hdf_hdf5lib_H5 + * Method: H5Treclaim + * Signature: (JJJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Treclaim + (JNIEnv *env, jclass clss, jlong type_id, jlong space_id, + jlong xfer_plist_id, jbyteArray buf) +{ + jboolean bufIsCopy; + jbyte *pinBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Treclaim: buffer is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, buf, pinBuf, &bufIsCopy, "H5Treclaim: buffer not pinned"); + + if ((status = H5Treclaim((hid_t)type_id, (hid_t)space_id, (hid_t)xfer_plist_id, pinBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (pinBuf) + UNPIN_BYTE_ARRAY(ENVONLY, buf, pinBuf, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Treclaim */ + +/* + * Class: hdf_hdf5lib_H5 * Method: _H5Tclose * Signature: (J)I */ diff --git a/java/src/jni/h5tImp.h b/java/src/jni/h5tImp.h index 374d992..a63969b 100644 --- a/java/src/jni/h5tImp.h +++ b/java/src/jni/h5tImp.h @@ -401,6 +401,15 @@ Java_hdf_hdf5lib_H5_H5Tpack /* * Class: hdf_hdf5lib_H5 + * Method: H5Treclaim + * Signature: (JJJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Treclaim + (JNIEnv*, jclass, jlong, jlong, jlong, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 * Method: _H5Tclose * Signature: (J)I */ diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index af83caa..700f75f 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -2781,7 +2781,7 @@ h5str_dump_simple_dset /* Reclaim any VL memory, if necessary */ if (vl_data) { - if (H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0) + if (H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0) H5_LIBRARY_ERROR(ENVONLY); } diff --git a/java/test/TestH5Dparams.java b/java/test/TestH5Dparams.java index a3618f2..621c000 100644 --- a/java/test/TestH5Dparams.java +++ b/java/test/TestH5Dparams.java @@ -113,17 +113,6 @@ public class TestH5Dparams { H5.H5Dvlen_get_buf_size(-1, -1, -1); } - @Test(expected = HDF5LibraryException.class) - public void testH5Dvlen_reclaim_invalid() throws Throwable { - byte[] buf = new byte[2]; - H5.H5Dvlen_reclaim(-1, -1, -1, buf); - } - - @Test(expected = NullPointerException.class) - public void testH5Dvlen_reclaim_null() throws Throwable { - H5.H5Dvlen_reclaim(-1, -1, -1, null); - } - @Test(expected = IllegalArgumentException.class) public void testH5Dget_storage_size_invalid() throws Throwable { H5.H5Dget_storage_size(-1); diff --git a/java/test/TestH5Tparams.java b/java/test/TestH5Tparams.java index 53d3a37..8baccd1 100644 --- a/java/test/TestH5Tparams.java +++ b/java/test/TestH5Tparams.java @@ -274,6 +274,17 @@ public class TestH5Tparams { public void testH5Tpack_invalid() throws Throwable { H5.H5Tpack(-1); } + + @Test(expected = HDF5LibraryException.class) + public void testH5Treclaim_invalid() throws Throwable { + byte[] buf = new byte[2]; + H5.H5Treclaim(-1, -1, -1, buf); + } + + @Test(expected = NullPointerException.class) + public void testH5Treclaim_null() throws Throwable { + H5.H5Treclaim(-1, -1, -1, null); + } @Test(expected = HDF5LibraryException.class) public void testH5Tvlen_create_invalid() throws Throwable { diff --git a/java/test/testfiles/JUnit-TestH5Dparams.txt b/java/test/testfiles/JUnit-TestH5Dparams.txt index 9751be4..9acedd7 100644 --- a/java/test/testfiles/JUnit-TestH5Dparams.txt +++ b/java/test/testfiles/JUnit-TestH5Dparams.txt @@ -7,11 +7,9 @@ JUnit version 4.11 .testH5Dvlen_get_buf_size_invalid .testH5Dcreate_null .testH5Dset_extent_status_null -.testH5Dvlen_reclaim_null .testH5Dcreate_invalid .testH5Dcreate_anon_invalid .testH5Dset_extent_status_invalid -.testH5Dvlen_reclaim_invalid .testH5Dopen_invalid .testH5Dclose_invalid .testH5Dflush_invalid @@ -22,5 +20,5 @@ JUnit version 4.11 Time: XXXX -OK (20 tests) +OK (18 tests) diff --git a/java/test/testfiles/JUnit-TestH5Tparams.txt b/java/test/testfiles/JUnit-TestH5Tparams.txt index e61f1e4..9f725ac 100644 --- a/java/test/testfiles/JUnit-TestH5Tparams.txt +++ b/java/test/testfiles/JUnit-TestH5Tparams.txt @@ -1,5 +1,6 @@ JUnit version 4.11 .testH5Tget_member_type_invalid +.testH5Treclaim_invalid .testH5Tenum_insert_null .testH5Tget_offset_invalid .testH5Tset_precision_invalid @@ -68,9 +69,10 @@ JUnit version 4.11 .testH5Tget_member_index_null .testH5Trefresh_invalid .testH5Tset_sign_invalid +.testH5Treclaim_null .testH5Tenum_insert_name_null Time: XXXX -OK (70 tests) +OK (72 tests) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 4c398a0..c2f2ebe 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -248,6 +248,16 @@ New Features (NAF - 2019/03/01) + - Add new H5R_ref_t type for object, dataset region and _attribute_ + references. This new type will deprecate the current hobj_ref_t + and hdset_reg_ref_t types for references. Added H5T_REF datatype + to read and write new reference types. As opposed to previous + reference types, reference creation no longer modifies existing + files. New reference types also now support references to external + files. + + (JS - 2019/10/08) + - Remove H5I_REFERENCE from the library This ID class was never used by the library and has been removed. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6df8af3..9bb73a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -446,6 +446,7 @@ set (H5O_SOURCES ${HDF5_SRC_DIR}/H5Ochunk.c ${HDF5_SRC_DIR}/H5Ocont.c ${HDF5_SRC_DIR}/H5Ocopy.c + ${HDF5_SRC_DIR}/H5Ocopy_ref.c ${HDF5_SRC_DIR}/H5Odbg.c ${HDF5_SRC_DIR}/H5Odeprec.c ${HDF5_SRC_DIR}/H5Odrvinfo.c @@ -616,6 +617,7 @@ set (H5T_SOURCES ${HDF5_SRC_DIR}/H5Torder.c ${HDF5_SRC_DIR}/H5Tpad.c ${HDF5_SRC_DIR}/H5Tprecis.c + ${HDF5_SRC_DIR}/H5Tref.c ${HDF5_SRC_DIR}/H5Tstrpad.c ${HDF5_SRC_DIR}/H5Tvisit.c ${HDF5_SRC_DIR}/H5Tvlen.c @@ -649,6 +651,7 @@ set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VLint.c ${HDF5_SRC_DIR}/H5VLnative.c ${HDF5_SRC_DIR}/H5VLnative_attr.c + ${HDF5_SRC_DIR}/H5VLnative_blob.c ${HDF5_SRC_DIR}/H5VLnative_dataset.c ${HDF5_SRC_DIR}/H5VLnative_datatype.c ${HDF5_SRC_DIR}/H5VLnative_file.c diff --git a/src/H5Aint.c b/src/H5Aint.c index c1c0078..2b43a64 100644 --- a/src/H5Aint.c +++ b/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 @@ -706,56 +706,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Dvlen_reclaim - * - * Purpose: Frees the buffers allocated for storing variable-length data - * in memory. Only frees the VL data in the selection defined in the - * dataspace. The dataset transfer property list is required to find the - * correct allocation/free methods for the VL data in the buffer. - * - * Return: Non-negative on success, negative on failure - * - * Programmer: Quincey Koziol - * Thursday, June 10, 1999 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) -{ - H5S_t *space; /* Dataspace for iteration */ - herr_t ret_value; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); - - /* Check args */ - if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") - if(!(H5S_has_extent(space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if(H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else - if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Call internal routine */ - ret_value = H5D_vlen_reclaim(type_id, space, buf); - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dvlen_reclaim() */ - - -/*------------------------------------------------------------------------- * Function: H5Dvlen_get_buf_size * * Purpose: This routine checks the number of bytes required to store the VL diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index ed82b3b..53ca7d1 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -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 */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index 29401f8..edad3c5 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -551,26 +551,16 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds H5MM_memcpy(storage_dst->buf, buf, storage_dst->size); - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ else if(H5T_get_class(dt_src, FALSE) == H5T_REFERENCE) { if(f_src != f_dst) { /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - size_t src_dt_size; /* Source datatype size */ - - /* Determine largest datatype size */ - if(0 == (src_dt_size = H5T_get_size(dt_src))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") - - /* Determine # of reference elements to copy */ - ref_count = storage_src->size / src_dt_size; - /* Copy objects referenced in source buffer to destination file and set destination elements */ - if(H5O_copy_expand_ref(f_src, storage_src->buf, f_dst, - storage_dst->buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + if (H5O_copy_expand_ref(f_src, tid_src, dt_src, storage_src->buf, + storage_src->size, f_dst, storage_dst->buf, cpy_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index c9f9fc2..0be7364 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -1543,19 +1543,14 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") /* Reclaim space from variable length data */ - if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") } /* end if */ else if(fix_ref) { /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - - /* Determine # of reference elements to copy */ - ref_count = src_nbytes / H5T_get_size(dt_src); - /* Copy the reference elements */ - if(H5O_copy_expand_ref(f_src, buf, f_dst, bkg, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) + if(H5O_copy_expand_ref(f_src, tid_src, dt_src, buf, buf_size, f_dst, bkg, cpy_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") /* After fix ref, copy the new reference elements to the buffer to write out */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 6380bee..f321c82 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -303,5 +303,55 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Dextend() */ + +/*------------------------------------------------------------------------- + * Function: H5Dvlen_reclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. The dataset transfer property list is required to find the + * correct allocation/free methods for the VL data in the buffer. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Thursday, June 10, 1999 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) +{ + H5S_t *space; /* Dataspace for iteration */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); + + /* Check args */ + if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + + /* Call internal routine */ + ret_value = H5T_reclaim(type_id, space, buf); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dvlen_reclaim() */ + #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Dint.c b/src/H5Dint.c index ada542e..772a150 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -547,7 +547,7 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type) /* To use at least v18 format versions or not */ use_at_least_v18 = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18); - /* Copy the datatype if it's a custom datatype or if it'll change when it's location is changed */ + /* Copy the datatype if it's a custom datatype or if it'll change when its location is changed */ if(!immutable || relocatable || use_at_least_v18) { /* Copy datatype for dataset */ if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL)) == NULL) @@ -2542,50 +2542,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5D_vlen_reclaim - * - * Purpose: Frees the buffers allocated for storing variable-length data - * in memory. Only frees the VL data in the selection defined in the - * dataspace. - * - * Return: Non-negative on success, negative on failure - *------------------------------------------------------------------------- - */ -herr_t -H5D_vlen_reclaim(hid_t type_id, H5S_t *space, void *buf) -{ - H5T_t *type; /* Datatype */ - H5S_sel_iter_op_t dset_op; /* Operator for iteration */ - H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ - herr_t ret_value = FAIL; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Check args */ - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - HDassert(space); - HDassert(buf); - - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype") - - /* Get the allocation info */ - if(H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") - - /* Call H5S_select_iterate with args, etc. */ - dset_op.op_type = H5S_SEL_ITER_OP_APP; - dset_op.u.app_op.op = H5T_vlen_reclaim; - dset_op.u.app_op.type_id = type_id; - - ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_vlen_reclaim() */ - - -/*------------------------------------------------------------------------- * Function: H5D__vlen_get_buf_size_alloc * * Purpose: This routine makes certain there is enough space in the temporary diff --git a/src/H5Dio.c b/src/H5Dio.c index 1e6e70d..79a856a 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -32,11 +32,6 @@ #include "H5VLnative_private.h" /* Native VOL connector */ -#ifdef H5_HAVE_PARALLEL -/* Remove this if H5R_DATASET_REGION is no longer used in this file */ -#include "H5Rpublic.h" -#endif /*H5_HAVE_PARALLEL*/ - /****************/ /* Local Macros */ @@ -478,33 +473,33 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") /* H5S_select_shape_same() has been modified to accept topologically identical - * selections with different rank as having the same shape (if the most - * rapidly changing coordinates match up), but the I/O code still has + * selections with different rank as having the same shape (if the most + * rapidly changing coordinates match up), but the I/O code still has * difficulties with the notion. * - * To solve this, we check to see if H5S_select_shape_same() returns true, - * and if the ranks of the mem and file spaces are different. If the are, - * construct a new mem space that is equivalent to the old mem space, and + * To solve this, we check to see if H5S_select_shape_same() returns true, + * and if the ranks of the mem and file spaces are different. If the are, + * construct a new mem space that is equivalent to the old mem space, and * use that instead. * - * Note that in general, this requires us to touch up the memory buffer as + * Note that in general, this requires us to touch up the memory buffer as * well. */ if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ /* Attempt to construct projected dataspace for memory dataspace */ if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.dst_type_size) < 0) + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.dst_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") HDassert(projected_mem_space); HDassert(adj_buf); /* Switch to using projected memory dataspace & adjusted buffer */ mem_space = projected_mem_space; - buf = adj_buf; + buf = (void *)adj_buf; /* Casting away 'const' OK -QAK */ } /* end if */ @@ -712,27 +707,27 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(!(H5S_has_extent(mem_space))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") - /* H5S_select_shape_same() has been modified to accept topologically - * identical selections with different rank as having the same shape - * (if the most rapidly changing coordinates match up), but the I/O + /* H5S_select_shape_same() has been modified to accept topologically + * identical selections with different rank as having the same shape + * (if the most rapidly changing coordinates match up), but the I/O * code still has difficulties with the notion. * - * To solve this, we check to see if H5S_select_shape_same() returns - * true, and if the ranks of the mem and file spaces are different. - * If the are, construct a new mem space that is equivalent to the + * To solve this, we check to see if H5S_select_shape_same() returns + * true, and if the ranks of the mem and file spaces are different. + * If the are, construct a new mem space that is equivalent to the * old mem space, and use that instead. * - * Note that in general, this requires us to touch up the memory buffer + * Note that in general, this requires us to touch up the memory buffer * as well. */ if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ /* Attempt to construct projected dataspace for memory dataspace */ if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.src_type_size) < 0) + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.src_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") HDassert(projected_mem_space); HDassert(adj_buf); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 511e380..9a5277f 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -170,9 +170,6 @@ H5_DLL herr_t H5D_flush_all(H5F_t *f); H5_DLL hid_t H5D_get_create_plist(const H5D_t *dset); H5_DLL hid_t H5D_get_access_plist(const H5D_t *dset); -/* Functions that operate on vlen data */ -H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, void *buf); - /* Functions that operate on chunked storage */ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 7234d16..281da81 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -156,7 +156,6 @@ H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf); H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op, void *operator_data); -H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size); H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, hid_t buf_type, hid_t space); @@ -203,6 +202,7 @@ H5_DLL hid_t H5Dcreate1(hid_t file_id, const char *name, hid_t type_id, hid_t space_id, hid_t dcpl_id); H5_DLL hid_t H5Dopen1(hid_t file_id, const char *name); H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); +H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 71e9fe1..11f0411 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -22,15 +22,15 @@ #include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ -#include "H5private.h" /* Generic Functions */ +#include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Dataset functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDmpi.h" /* MPI-based file drivers */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ +#include "H5Dprivate.h" /* Dataset functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5FDmpi.h" /* MPI-based file drivers */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #ifdef H5_HAVE_PARALLEL @@ -1324,6 +1324,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__mpio_read() */ + /*------------------------------------------------------------------------- * Function: H5FD__mpio_write @@ -1366,6 +1367,7 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, #endif int size_i; hbool_t use_view_this_time = FALSE; + hbool_t derived_type = FALSE; H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode */ herr_t ret_value = SUCCEED; @@ -1391,8 +1393,6 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, if(H5FD_mpi_haddr_to_MPIOff(addr, &mpi_off) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") size_i = (int)size; - if((hsize_t)size_i != size) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from size to size_i") #ifdef H5FDmpio_DEBUG if(H5FD_mpio_Debug[(int)'w']) @@ -1430,6 +1430,20 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, */ mpi_off = 0; } /* end if */ + else if(size != (hsize_t)size_i) { + /* If HERE, then we need to work around the integer size limit + * of 2GB. The input size_t size variable cannot fit into an integer, + * but we can get around that limitation by creating a different datatype + * and then setting the integer size (or element count) to 1 when using + * the derived_type. + */ + + if (H5_mpio_create_large_type(size, 0, MPI_BYTE, &buf_type) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "can't create MPI-I/O datatype") + + derived_type = TRUE; + size_i = 1; + } /* Write the data. */ if(use_view_this_time) { @@ -1506,6 +1520,9 @@ H5FD__mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, file->local_eof = addr + (haddr_t)bytes_written; done: + if(derived_type) { + MPI_Type_free(&buf_type); + } #ifdef H5FDmpio_DEBUG if(H5FD_mpio_Debug[(int)'t']) HDfprintf(stdout, "%s: Leaving, proc %d: ret_value = %d\n", FUNC, file->mpi_rank, ret_value ); diff --git a/src/H5Fint.c b/src/H5Fint.c index 5e2cf26..2ebcd94 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -139,18 +139,14 @@ H5F__set_vol_conn(H5F_t *file) /* Sanity check */ HDassert(0 != connector_prop.connector_id); - /* Copy connector info, if it exists */ - if(connector_prop.connector_info) { - H5VL_class_t *connector; /* Pointer to connector */ + /* Retrieve the connector for the ID */ + if(NULL == (file->shared->vol_cls = (H5VL_class_t *)H5I_object(connector_prop.connector_id))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Retrieve the connector for the ID */ - if(NULL == (connector = (H5VL_class_t *)H5I_object(connector_prop.connector_id))) - HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a VOL connector ID") - - /* Allocate and copy connector info */ - if(H5VL_copy_connector_info(connector, &new_connector_info, connector_prop.connector_info) < 0) + /* Allocate and copy connector info, if it exists */ + if(connector_prop.connector_info) + if(H5VL_copy_connector_info(file->shared->vol_cls, &new_connector_info, connector_prop.connector_info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "connector info copy failed") - } /* end if */ /* Cache the connector ID & info for the container */ file->shared->vol_id = connector_prop.connector_id; @@ -1377,6 +1373,7 @@ H5F__dest(H5F_t *f, hbool_t flush) if(H5I_dec_ref(f->shared->vol_id) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close VOL connector ID") + f->shared->vol_cls = NULL; /* Close the file */ if(H5FD_close(f->shared->lf) < 0) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 6cd2d3c..4b5b788 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -29,9 +29,6 @@ /* Get package's private header */ #include "H5Fprivate.h" -/* Other public headers needed by this file */ -#include "H5VLpublic.h" /* Virtual Object Layer */ - /* Other private headers needed by this file */ #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ @@ -313,6 +310,7 @@ struct H5F_shared_t { /* Cached VOL connector ID & info */ hid_t vol_id; /* ID of VOL connector for the container */ + const H5VL_class_t *vol_cls; /* Pointer to VOL connector class for the container */ void *vol_info; /* Copy of VOL connector info for container */ /* File space allocation information */ @@ -413,6 +411,7 @@ H5_DLL herr_t H5F__close(H5F_t *f); H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); H5_DLL H5F_t *H5F__get_file(void *obj, H5I_type_t type); H5_DLL hid_t H5F__get_file_id(H5F_t *file, hbool_t app_ref); +H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); /* File mount related routines */ H5_DLL herr_t H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 7e87f79..c9a1b25 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -25,14 +25,15 @@ typedef struct H5F_t H5F_t; #include "H5Fpublic.h" /* Public headers needed by this file */ -#include "H5FDpublic.h" /* File drivers */ +#include "H5FDpublic.h" /* File drivers */ +#include "H5VLpublic.h" /* Virtual Object Layer */ /* Private headers needed by this file */ -#include "H5MMprivate.h" /* Memory management */ +#include "H5MMprivate.h" /* Memory management */ #ifdef H5_HAVE_PARALLEL -#include "H5Pprivate.h" /* Property lists */ +#include "H5Pprivate.h" /* Property lists */ #endif /* H5_HAVE_PARALLEL */ -#include "H5VMprivate.h" /* Vectors and arrays */ +#include "H5VMprivate.h" /* Vectors and arrays */ /**************************/ @@ -335,6 +336,7 @@ typedef struct H5F_t H5F_t; #define H5F_NULL_FSM_ADDR(F) ((F)->shared->null_fsm_addr) #define H5F_GET_MIN_DSET_OHDR(F) ((F)->shared->crt_dset_min_ohdr_flag) #define H5F_SET_MIN_DSET_OHDR(F, V) ((F)->shared->crt_dset_min_ohdr_flag = (V)) +#define H5F_VOL_CLS(F) ((F)->shared->vol_cls) #else /* H5F_MODULE */ #define H5F_LOW_BOUND(F) (H5F_get_low_bound(F)) #define H5F_HIGH_BOUND(F) (H5F_get_high_bound(F)) @@ -395,6 +397,7 @@ typedef struct H5F_t H5F_t; #define H5F_NULL_FSM_ADDR(F) (H5F_get_null_fsm_addr(F)) #define H5F_GET_MIN_DSET_OHDR(F) (H5F_get_min_dset_ohdr(F)) #define H5F_SET_MIN_DSET_OHDR(F, V) (H5F_set_min_dset_ohdr((F), (V))) +#define H5F_VOL_CLS(F) (H5F_get_vol_cls(F)) #endif /* H5F_MODULE */ @@ -755,6 +758,7 @@ H5_DLL hbool_t H5F_get_point_of_no_return(const H5F_t *f); H5_DLL hbool_t H5F_get_null_fsm_addr(const H5F_t *f); H5_DLL hbool_t H5F_get_min_dset_ohdr(const H5F_t *f); H5_DLL herr_t H5F_set_min_dset_ohdr(H5F_t *f, hbool_t minimize); +H5_DLL const H5VL_class_t *H5F_get_vol_cls(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index f36f348..32743c4 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1279,3 +1279,66 @@ H5F_get_null_fsm_addr(const H5F_t *f) FUNC_LEAVE_NOAPI(f->shared->null_fsm_addr) } /* end H5F_get_null_fsm_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_vol_cls + * + * Purpose: Get the VOL class for the file + * + * Return: VOL class pointer for file, can't fail + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +const H5VL_class_t * +H5F_get_vol_cls(const H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->vol_cls) +} /* end H5F_get_vol_cls */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_cont_info + * + * Purpose: Get the VOL container info for the file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + + /* Verify structure version */ + if(info->version != H5VL_CONTAINER_INFO_VERSION) + HGOTO_ERROR(H5E_FILE, H5E_VERSION, FAIL, "wrong container info version #") + + /* Set the container info fields */ + info->feature_flags = 0; /* None currently defined */ + info->token_size = H5F_SIZEOF_ADDR(f); + info->blob_id_size = H5HG_HEAP_ID_SIZE(f); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_cont_info */ + diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 97a3ccf..fcb16d3 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -926,41 +926,38 @@ herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API(FAIL); H5TRACE4("e", "i*sbx", loc_id, name, follow_link, statbuf); /* Check arguments */ - if(!name || !*name) + if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Set up collective metadata if appropriate */ - if(H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + if (H5CX_set_loc(loc_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info"); - /* Retrieve object info, if pointer to struct is given */ - if(statbuf) { - H5VL_object_t *vol_obj; /* Object token of loc_id */ - H5VL_loc_params_t loc_params; - - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(loc_id); + /* Retrieve object info */ + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ - if(NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Get the location object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier"); - /* Retrieve the object's information */ - if(H5VL_group_optional(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_NATIVE_GROUP_GET_OBJINFO, &loc_params, (unsigned)follow_link, statbuf) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name) - } /* end if */ + /* Retrieve the object's information */ + if (H5VL_group_optional(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_NATIVE_GROUP_GET_OBJINFO, &loc_params, (unsigned)follow_link, statbuf) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name); done: - FUNC_LEAVE_API(ret_value) + FUNC_LEAVE_API(ret_value); } /* end H5Gget_objinfo() */ @@ -982,60 +979,64 @@ H5G__get_objinfo_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char *name, c H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_trav_goi_t *udata = (H5G_trav_goi_t *)_udata; /* User data passed in */ - H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC; /* Check if the name in this group resolved to a valid link */ - if(lnk == NULL && obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name) - - /* Common code to retrieve the file's fileno */ - if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno[0]) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno") - - /* Info for soft and UD links is gotten by H5L_get_info. If we have - * a hard link, follow it and get info on the object - */ - if(udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { - H5O_info_t oinfo; /* Object information */ - - /* Go retrieve the object information */ - /* (don't need index & heap info) */ - HDassert(obj_loc); - if(H5O_get_info(obj_loc->oloc, &oinfo, H5O_INFO_BASIC|H5O_INFO_TIME|H5O_INFO_HDR) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info") - - /* Get mapped object type */ - statbuf->type = H5G_map_obj_type(oinfo.type); - - /* Get object number (i.e. address) for object */ - statbuf->objno[0] = (unsigned long)(oinfo.addr); + if (lnk == NULL && obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name); + + /* Only modify user's buffer if it's available */ + if (udata->statbuf) { + H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */ + + /* Common code to retrieve the file's fileno */ + if (H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno[0]) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno"); + + /* Info for soft and UD links is gotten by H5L_get_info. If we have + * a hard link, follow it and get info on the object + */ + if (udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { + H5O_info_t oinfo; /* Object information */ + + /* Go retrieve the object information */ + /* (don't need index & heap info) */ + HDassert(obj_loc); + if (H5O_get_info(obj_loc->oloc, &oinfo, H5O_INFO_BASIC|H5O_INFO_TIME|H5O_INFO_HDR) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info"); + + /* Get mapped object type */ + statbuf->type = H5G_map_obj_type(oinfo.type); + + /* Get object number (i.e. address) for object */ + statbuf->objno[0] = (unsigned long)(oinfo.addr); #if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - statbuf->objno[1] = (unsigned long)(oinfo.addr >> 8 * sizeof(long)); + statbuf->objno[1] = (unsigned long)(oinfo.addr >> 8 * sizeof(long)); #else - statbuf->objno[1] = 0; + statbuf->objno[1] = 0; #endif - /* Get # of hard links pointing to object */ - statbuf->nlink = oinfo.rc; - - /* Get modification time for object */ - statbuf->mtime = oinfo.ctime; - - /* Retrieve the object header information */ - statbuf->ohdr.size = oinfo.hdr.space.total; - statbuf->ohdr.free = oinfo.hdr.space.free; - statbuf->ohdr.nmesgs = oinfo.hdr.nmesgs; - statbuf->ohdr.nchunks = oinfo.hdr.nchunks; - } /* end if */ + /* Get # of hard links pointing to object */ + statbuf->nlink = oinfo.rc; + + /* Get modification time for object */ + statbuf->mtime = oinfo.ctime; + + /* Retrieve the object header information */ + statbuf->ohdr.size = oinfo.hdr.space.total; + statbuf->ohdr.free = oinfo.hdr.space.free; + statbuf->ohdr.nmesgs = oinfo.hdr.nmesgs; + statbuf->ohdr.nchunks = oinfo.hdr.nchunks; + } + } done: /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(ret_value); } /* end H5G__get_objinfo_cb() */ @@ -1062,15 +1063,15 @@ H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, H5G_trav_goi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_PACKAGE; /* Sanity checks */ HDassert(loc); HDassert(name && *name); - HDassert(statbuf); /* Reset stat buffer */ - HDmemset(statbuf, 0, sizeof(H5G_stat_t)); + if (statbuf) + HDmemset(statbuf, 0, sizeof(H5G_stat_t)); /* Set up user data for retrieving information */ udata.statbuf = statbuf; @@ -1078,11 +1079,11 @@ H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, udata.loc_file = loc->oloc->file; /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : (H5G_TARGET_SLINK | H5G_TARGET_UDLINK)), H5G__get_objinfo_cb, &udata) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + if (H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : (H5G_TARGET_SLINK | H5G_TARGET_UDLINK)), H5G__get_objinfo_cb, &udata) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist"); /* If we're pointing at a soft or UD link, get the real link length and type */ - if(follow_link == 0) { + if (statbuf && follow_link == 0) { H5L_info_t linfo; /* Link information buffer */ herr_t ret; @@ -1090,21 +1091,23 @@ H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, * because the object is ".", just treat the object as a hard link. */ H5E_BEGIN_TRY { ret = H5L_get_info(loc, name, &linfo); - } H5E_END_TRY + } H5E_END_TRY; - if(ret >= 0 && linfo.type != H5L_TYPE_HARD) { + if (ret >= 0 && linfo.type != H5L_TYPE_HARD) { statbuf->linklen = linfo.u.val_size; - if(linfo.type == H5L_TYPE_SOFT) + if (linfo.type == H5L_TYPE_SOFT) { statbuf->type = H5G_LINK; - else { /* UD link. H5L_get_info checked for invalid link classes */ + } + else { + /* UD link. H5L_get_info checked for invalid link classes */ HDassert(linfo.type >= H5L_TYPE_UD_MIN && linfo.type <= H5L_TYPE_MAX); statbuf->type = H5G_UDLINK; - } /* end else */ - } /* end if */ - } /* end if */ + } + } + } done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(ret_value); } /* end H5G__get_objinfo() */ diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 1c609e2..4841847 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -49,6 +49,10 @@ typedef struct H5HG_heap_t H5HG_heap_t; #define H5HG_FREE_SIZE(H) (H5HG_get_free_size(H)) #endif /* H5HG_MODULE */ +/* Size of encoded global heap ID */ +/* (size of file address + 32-bit integer) */ +#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + H5_SIZEOF_UINT32_T) + /* Main global heap routines */ H5_DLL herr_t H5HG_insert(H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/); @@ -278,6 +278,7 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5VL_loc_params_t loc_params1; H5VL_object_t *vol_obj2 = NULL; /* Object token of dst_id */ H5VL_loc_params_t loc_params2; + H5VL_object_t tmp_vol_obj; /* Temporary object token */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -329,8 +330,12 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + /* Construct a temporary source VOL object */ + tmp_vol_obj.data = (vol_obj1 ? vol_obj1->data : NULL); + tmp_vol_obj.connector = (vol_obj1 ? vol_obj1->connector : vol_obj2->connector); + /* Move the link */ - if(H5VL_link_move(vol_obj1, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if(H5VL_link_move(&tmp_vol_obj, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") done: @@ -360,7 +365,7 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5VL_loc_params_t loc_params1; H5VL_object_t *vol_obj2 = NULL; /* Object token of dst_id */ H5VL_loc_params_t loc_params2; - H5VL_object_t tmp_vol_obj; /* Temporary object token of */ + H5VL_object_t tmp_vol_obj; /* Temporary object token */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -377,15 +382,15 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + /* Check the link create property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Verify access property list and set up collective metadata if appropriate */ if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, ((src_loc_id != H5L_SAME_LOC) ? src_loc_id : dst_loc_id), TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* Check the link create property list */ - if(H5P_DEFAULT == lcpl_id) - lcpl_id = H5P_LINK_CREATE_DEFAULT; - /* Set location paramter for source object */ loc_params1.type = H5VL_OBJECT_BY_NAME; loc_params1.loc_data.loc_by_name.name = src_name; @@ -255,22 +255,48 @@ hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr) { H5VL_object_t *vol_obj; /* 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 */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + void *vol_obj_file = NULL; /* Object token of file_id */ + H5F_t *f = NULL; + uint8_t *p = NULL; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "ia", loc_id, addr); - loc_params.type = H5VL_OBJECT_BY_ADDR; - loc_params.loc_data.loc_by_addr.addr = addr; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Get object type */ + if((vol_obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* 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, 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") + + /* This is a native specific routine that requires serialization of the token */ + p = obj_token; + H5F_addr_encode(f, &p, addr); + + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = vol_obj_type; + /* Open the object */ if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") @@ -280,6 +306,8 @@ H5Oopen_by_addr(hid_t loc_id, haddr_t addr) HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") 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 H5Oopen_by_addr() */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 9578f95..6e0db25 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -85,8 +85,6 @@ static herr_t H5O__copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /* hid_t ocpypl_id, hid_t lcpl_id); static herr_t H5O__copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); -static herr_t H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); static herr_t H5O__copy_free_comm_dt_cb(void *item, void *key, void *op_data); static int H5O__copy_comm_dt_cmp(const void *dt1, const void *dt2); static herr_t H5O__copy_search_comm_dt_cb(hid_t group, const char *name, @@ -110,7 +108,6 @@ H5FL_DEFINE(H5O_copy_search_comm_dt_key_t); /* Declare a free list to manage haddr_t variables */ H5FL_DEFINE(haddr_t); - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -1235,201 +1232,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5O__copy_obj_by_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_STATIC - - HDassert(src_oloc); - HDassert(dst_oloc); - - /* Perform the copy, or look up existing copy */ - if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, cpy_info, FALSE, NULL, NULL)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - - /* Check if a new valid object is copied to the destination */ - if(H5F_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) { - char tmp_obj_name[80]; - H5G_name_t new_path; - H5O_loc_t new_oloc; - H5G_loc_t new_loc; - - /* Set up group location for new object */ - new_loc.oloc = &new_oloc; - new_loc.path = &new_path; - H5G_loc_reset(&new_loc); - new_oloc.file = dst_oloc->file; - new_oloc.addr = dst_oloc->addr; - - /* Pick a default name for the new object */ - HDsnprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); - - /* Create a link to the newly copied object */ - /* Note: since H5O_copy_header_map actually copied the target object, it - * must exist either in cache or on disk, therefore it is is safe to not - * pass the obj_type and udata fields returned by H5O_copy_header_map. - * This could be changed in the future to slightly improve performance - * --NAF */ - if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, cpy_info->lcpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") - - H5G_loc_free(&new_loc); - } /* if (H5F_addr_defined(dst_oloc.addr)) */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O__copy_obj_by_ref() */ - - -/*------------------------------------------------------------------------- - * Function: H5O_copy_expand_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, H5F_t *file_dst, - void *_dst_ref, size_t ref_count, H5R_type_t ref_type, H5O_copy_t *cpy_info) -{ - H5O_loc_t dst_oloc; /* Copied object object location */ - H5O_loc_t src_oloc; /* Temporary object location for source object */ - H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ - const uint8_t *q; /* Pointer to source OID to store */ - uint8_t *p; /* Pointer to destination OID to store */ - size_t i; /* Local index variable */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(file_src); - HDassert(_src_ref); - HDassert(file_dst); - HDassert(_dst_ref); - HDassert(ref_count); - HDassert(cpy_info); - - /* Initialize object locations */ - H5O_loc_reset(&src_oloc); - H5O_loc_reset(&dst_oloc); - src_oloc.file = file_src; - dst_oloc.file = file_dst; - - /* Set up the root group in the destination file */ - if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") - if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") - - /* Copy object references */ - if(H5R_OBJECT == ref_type) { - hobj_ref_t *src_ref = (hobj_ref_t *)_src_ref; - hobj_ref_t *dst_ref = (hobj_ref_t *)_dst_ref; - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Set up for the object copy for the reference */ - q = (uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* Attempt to copy object from source to destination file */ - if(src_oloc.addr != (haddr_t)0) { - if(H5O__copy_obj_by_ref(&src_oloc, &dst_oloc, &dst_root_loc, cpy_info) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&dst_oloc.addr, 0, sizeof(dst_oloc.addr)); - - /* Set the object reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - } /* end for */ - } /* end if */ - /* Copy region references */ - else if(H5R_DATASET_REGION == ref_type) { - hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; - hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; - uint8_t *buf = NULL; /* Buffer to store serialized selection in */ - H5HG_t hobjid; /* Heap object ID */ - size_t buf_size; /* Length of object in heap */ - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Get the heap ID for the dataset region */ - q = (const uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(hobjid.addr)); - UINT32DECODE(q, hobjid.idx); - - if(hobjid.addr != (haddr_t)0) { - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(src_oloc.file, &hobjid, NULL, &buf_size)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") - - /* Get the object oid for the dataset */ - q = (const uint8_t *)buf; - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* copy the object pointed by the ref to the destination */ - if(H5O__copy_obj_by_ref(&src_oloc, &dst_oloc, &dst_root_loc, cpy_info) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - - /* Serialize object ID */ - p = (uint8_t *)buf; - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - - /* Save the serialized buffer to the destination */ - if(H5HG_insert(dst_oloc.file, buf_size, buf, &hobjid) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") - } /* end if */ - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&hobjid, 0, sizeof(hobjid)); - - /* Set the dataset region reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, hobjid.addr); - UINT32ENCODE(p, hobjid.idx); - - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - } /* end for */ - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_expand_ref() */ - - -/*------------------------------------------------------------------------- * Function: H5O__copy_free_comm_dt_cb * * Purpose: Frees the merge committed dt skip list key and object. diff --git a/src/H5Ocopy_ref.c b/src/H5Ocopy_ref.c new file mode 100644 index 0000000..3b18073 --- /dev/null +++ b/src/H5Ocopy_ref.c @@ -0,0 +1,498 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 */ + size_t token_size = H5F_SIZEOF_ADDR(src_oloc->file); + 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]; + H5VL_token_t tmp_token = { 0 }; + uint8_t *p; + + /* 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_token_obj_compat(src_buf, &buf_size, &tmp_token, token_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address") + p = tmp_token; + H5F_addr_decode(src_oloc->file, (const uint8_t **)&p, &src_oloc->addr); + 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 */ + p = tmp_token; + H5F_addr_encode(dst_oloc->file, &p, dst_oloc->addr); + if(H5R__encode_token_obj_compat((const H5VL_token_t *)&tmp_token, token_size, 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 */ + size_t token_size = H5F_SIZEOF_ADDR(src_oloc->file); + 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]; + H5VL_token_t tmp_token = { 0 }; + uint8_t *p; + + /* Get src object address */ + if(H5R__get_obj_token(ref, &tmp_token, &token_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token") + p = tmp_token; + H5F_addr_decode(src_oloc->file, (const uint8_t **)&p, &src_oloc->addr); + + /* 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 */ + p = tmp_token; + H5F_addr_encode(dst_oloc->file, &p, dst_oloc->addr); + if(H5R__set_obj_token(ref, (const H5VL_token_t *)&tmp_token, token_size) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token") + if(H5R__set_loc_id(ref, dst_loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set destination loc id") + } /* end for */ + + /* Copy into another buffer, to reclaim memory later */ + if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + H5MM_memcpy(reclaim_buf, conv_buf, conv_buf_size); + if(NULL == (buf_space = H5S_create_simple((unsigned)1, buf_dim, NULL))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create simple dataspace") + + /* Convert from memory to destination file */ + if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, ref_count, (size_t)0, (size_t)0, conv_buf, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + H5MM_memcpy(buf_dst, conv_buf, nbytes_src); + + /* Reclaim space from reference data */ + if(H5T_reclaim(tid_mem, buf_space, reclaim_buf) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to reclaim reference data") + +done: + if(buf_space && (H5S_close(buf_space) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't close dataspace") + /* Don't decrement ID, we want to keep underlying datatype */ + if(reg_tid_src && (tid_src > 0) && (NULL == H5I_remove(tid_src))) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if((tid_mem > 0) && H5I_dec_ref(tid_mem) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if((tid_dst > 0) && H5I_dec_ref(tid_dst) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if(reclaim_buf) + reclaim_buf = H5FL_BLK_FREE(type_conv, reclaim_buf); + if(conv_buf) + conv_buf = H5FL_BLK_FREE(type_conv, conv_buf); + if((dst_loc_id != H5I_INVALID_HID) && (H5I_dec_ref(dst_loc_id) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O__copy_expand_ref_object2() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_expand_ref + * + * Purpose: Copy the object pointed by a reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, H5T_t *dt_src, + void *buf_src, size_t nbytes_src, H5F_t *file_dst, void *buf_dst, + H5O_copy_t *cpy_info) +{ + H5O_loc_t dst_oloc; /* Copied object object location */ + H5O_loc_t src_oloc; /* Temporary object location for source object */ + H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ + size_t ref_count; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(file_src); + HDassert(buf_src); + HDassert(file_dst); + HDassert(buf_dst); + HDassert(nbytes_src); + HDassert(cpy_info); + + /* Initialize object locations */ + H5O_loc_reset(&src_oloc); + H5O_loc_reset(&dst_oloc); + src_oloc.file = file_src; + dst_oloc.file = file_dst; + + /* Set up the root group in the destination file */ + if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Determine # of reference elements to copy */ + ref_count = nbytes_src / H5T_get_size(dt_src); + + /* Copy object references */ + switch(H5T_get_ref_type(dt_src)) { + case H5R_OBJECT1: + if(H5O__copy_expand_ref_object1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_OBJECT1 reference") + break; + case H5R_DATASET_REGION1: + if(H5O__copy_expand_ref_region1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_DATASET_REGION1 reference") + break; + case H5R_DATASET_REGION2: + case H5R_ATTR: + case H5R_OBJECT2: + if(H5O__copy_expand_ref_object2(&src_oloc, tid_src, dt_src, buf_src, nbytes_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand reference") + break; + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + break; + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_expand_ref() */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 8f301af..805df2b 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -129,7 +129,7 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ *------------------------------------------------------------------------- */ static htri_t -H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt) +H5O_dtype_decode_helper(unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt) { unsigned flags, version; unsigned i; @@ -145,7 +145,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* 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); @@ -331,7 +331,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Decode the field's datatype information */ - if((can_upgrade = H5O_dtype_decode_helper(f, ioflags, pp, temp_type)) < 0) { + if((can_upgrade = H5O_dtype_decode_helper(ioflags, pp, temp_type)) < 0) { for(j = 0; j <= i; j++) H5MM_xfree(dt->shared->u.compnd.memb[j].name); H5MM_xfree(dt->shared->u.compnd.memb); @@ -438,16 +438,28 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Set reference type */ dt->shared->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f); - - /* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */ - if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) { - /* Mark location this type as undefined for now. The caller function should - * decide the location. */ - dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; - - /* This type needs conversion */ - dt->shared->force_conv = TRUE; - } /* end if */ + if(dt->shared->u.atomic.u.r.rtype <= H5R_BADTYPE + || dt->shared->u.atomic.u.r.rtype >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "invalid reference type"); + + /* Set generic flag */ + if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT2 + || dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION2 + || dt->shared->u.atomic.u.r.rtype == H5R_ATTR) { + dt->shared->u.atomic.u.r.opaque = TRUE; + dt->shared->u.atomic.u.r.version = (unsigned)((flags >> 4) & 0x0f); + if(dt->shared->u.atomic.u.r.version != H5R_ENCODE_VERSION) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "reference version does not match"); + } else + dt->shared->u.atomic.u.r.opaque = FALSE; + + /* This type needs conversion */ + dt->shared->force_conv = TRUE; + + /* Mark location of this type as undefined for now. The caller + * function should decide the location. */ + if(H5T_set_loc(dt, NULL, H5T_LOC_BADLOC) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") break; case H5T_ENUM: @@ -457,7 +469,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p dt->shared->u.enumer.nmembs = dt->shared->u.enumer.nalloc = flags & 0xffff; if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype") /* Check if the parent of this enum has a version greater than the @@ -499,7 +511,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Decode base type of VL information */ if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type") /* Check if the parent of this vlen has a version greater than the @@ -511,7 +523,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Mark location this type as undefined for now. The caller function should * decide the location. */ - if(H5T_set_loc(dt, f, H5T_LOC_BADLOC) < 0) + if(H5T_set_loc(dt, NULL, H5T_LOC_BADLOC) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") break; @@ -540,7 +552,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Decode base type of array */ if(NULL == (dt->shared->parent = H5T__alloc())) HGOTO_ERROR(H5E_DATATYPE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(H5O_dtype_decode_helper(f, ioflags, pp, dt->shared->parent) < 0) + if(H5O_dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode array parent type") /* Check if the parent of this array has a version greater than the @@ -596,7 +608,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) +H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt) { unsigned flags = 0; uint8_t *hdr = (uint8_t *)*pp; @@ -956,7 +968,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Subtype */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->u.compnd.memb[i].type) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->u.compnd.memb[i].type) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode member type") } /* end for */ } @@ -964,6 +976,8 @@ H5O_dtype_encode_helper(const H5F_t *f, 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: @@ -976,7 +990,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) flags = dt->shared->u.enumer.nmembs & 0xffff; /* Parent type */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode parent datatype") /* Names, each a multiple of eight bytes */ @@ -1012,7 +1026,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Encode base type of VL information */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type") break; @@ -1050,7 +1064,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end if */ /* Encode base type of array's information */ - if(H5O_dtype_encode_helper(f, pp, dt->shared->parent) < 0) + if(H5O_dtype_encode_helper(pp, dt->shared->parent) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type") break; @@ -1091,7 +1105,7 @@ done: function using malloc() and is returned to the caller. --------------------------------------------------------------------------*/ static void * -H5O_dtype_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, +H5O_dtype_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned *ioflags/*in,out*/, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) { H5T_t *dt = NULL; @@ -1107,7 +1121,7 @@ H5O_dtype_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Perform actual decode of message */ - if(H5O_dtype_decode_helper(f, ioflags, &p, dt) < 0) + if(H5O_dtype_decode_helper(ioflags, &p, dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type") /* Set return value */ @@ -1136,7 +1150,7 @@ done: message in the "raw" disk form. --------------------------------------------------------------------------*/ static herr_t -H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg) +H5O_dtype_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *mesg) { const H5T_t *dt = (const H5T_t *) mesg; herr_t ret_value = SUCCEED; /* Return value */ @@ -1149,7 +1163,7 @@ H5O_dtype_encode(H5F_t *f, uint8_t *p, const void *mesg) HDassert(dt); /* encode */ - if(H5O_dtype_encode_helper(f, &p, dt) < 0) + if(H5O_dtype_encode_helper(&p, dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode type") done: diff --git a/src/H5Ofill.c b/src/H5Ofill.c index df39d19..0cc58a6 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -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 */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index bcb8299..54e8ec8 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -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); diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index df9cf4e..9baa201 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -1519,7 +1519,7 @@ done: * * Purpose: Sets the memory allocate/free pair for VL datatypes. The * allocation routine is called when data is read into a new - * array and the free routine is called when H5Dvlen_reclaim is + * array and the free routine is called when H5Treclaim is * called. The alloc_info and free_info are user parameters * which are passed to the allocation and freeing functions * respectively. To reset the allocate/free functions to the @@ -1563,7 +1563,7 @@ done: * * Purpose: Sets the memory allocate/free pair for VL datatypes. The * allocation routine is called when data is read into a new - * array and the free routine is called when H5Dvlen_reclaim is + * array and the free routine is called when H5Treclaim is * called. The alloc_info and free_info are user parameters * which are passed to the allocation and freeing functions * respectively. To reset the allocate/free functions to the diff --git a/src/H5Pint.c b/src/H5Pint.c index 36367d7..2911eef 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -169,6 +169,8 @@ hid_t H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID; H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL; hid_t H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL; +hid_t H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; +H5P_genclass_t *H5P_CLS_REFERENCE_ACCESS_g = NULL; /* * Predefined property lists for each predefined class. These are initialized @@ -192,6 +194,7 @@ hid_t H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID; hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID; hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID; hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; +hid_t H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; /* Root property list class library initialization object */ const H5P_libclass_t H5P_CLS_ROOT[1] = {{ @@ -312,6 +315,25 @@ const H5P_libclass_t H5P_CLS_VINI[1] = {{ NULL /* Class close callback info */ }}; +/* Reference access property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_RACC[1] = {{ + "reference access", /* Class name for debugging */ + H5P_TYPE_REFERENCE_ACCESS, /* Class type */ + + &H5P_CLS_FILE_ACCESS_g, /* Parent class */ + &H5P_CLS_REFERENCE_ACCESS_g, /* Pointer to class */ + &H5P_CLS_REFERENCE_ACCESS_ID_g, /* Pointer to class ID */ + &H5P_LST_REFERENCE_ACCESS_ID_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine*/ + + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; /* Library property list classes defined in other code modules */ /* (And not present in src/H5Pprivate.h) */ @@ -364,7 +386,8 @@ static H5P_libclass_t const * const init_class[] = { H5P_CLS_ACRT, /* Attribute creation */ H5P_CLS_AACC, /* Attribute access */ H5P_CLS_LCRT, /* Link creation */ - H5P_CLS_VINI /* VOL initialization */ + H5P_CLS_VINI, /* VOL initialization */ + H5P_CLS_RACC /* Reference access */ }; /* Declare a free list to manage the H5P_genclass_t struct */ @@ -440,7 +463,7 @@ H5P__init_package(void) FUNC_ENTER_PACKAGE /* Sanity check */ - HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); + HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); /* * Initialize the Generic Property class & object groups. @@ -564,6 +587,7 @@ H5P_term_package(void) H5P_LST_LINK_CREATE_ID_g = H5P_LST_LINK_ACCESS_ID_g = H5P_LST_VOL_INITIALIZE_ID_g = + H5P_LST_REFERENCE_ACCESS_ID_g = H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID; } /* end if */ } /* end if */ @@ -594,6 +618,7 @@ H5P_term_package(void) H5P_CLS_LINK_CREATE_g = H5P_CLS_LINK_ACCESS_g = H5P_CLS_VOL_INITIALIZE_g = + H5P_CLS_REFERENCE_ACCESS_g = H5P_CLS_FILE_MOUNT_g = NULL; H5P_CLS_ROOT_ID_g = @@ -616,6 +641,7 @@ H5P_term_package(void) H5P_CLS_LINK_CREATE_ID_g = H5P_CLS_LINK_ACCESS_ID_g = H5P_CLS_VOL_INITIALIZE_ID_g = + H5P_CLS_REFERENCE_ACCESS_ID_g = H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID; } /* end if */ } /* end if */ @@ -5453,8 +5479,8 @@ H5P__new_plist_of_type(H5P_plist_type_t type) FUNC_ENTER_PACKAGE /* Sanity checks */ - HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); - HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_MAP_ACCESS); + HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); + HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_REFERENCE_ACCESS); /* Check arguments */ if(type == H5P_TYPE_USER) @@ -5544,6 +5570,10 @@ H5P__new_plist_of_type(H5P_plist_type_t type) class_id = H5P_CLS_VOL_INITIALIZE_ID_g; break; + case H5P_TYPE_REFERENCE_ACCESS: + class_id = H5P_CLS_REFERENCE_ACCESS_ID_g; + break; + case H5P_TYPE_USER: /* shut compiler warnings up */ case H5P_TYPE_ROOT: case H5P_TYPE_MAX_TYPE: diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 9fc1acc..f7253a0 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -81,6 +81,7 @@ typedef enum H5P_plist_type_t { H5P_TYPE_VOL_INITIALIZE = 19, H5P_TYPE_MAP_CREATE = 20, H5P_TYPE_MAP_ACCESS = 21, + H5P_TYPE_REFERENCE_ACCESS = 22, H5P_TYPE_MAX_TYPE } H5P_plist_type_t; diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 9f26b8b..bb33561 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -71,6 +71,7 @@ #define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g) #define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g) #define H5P_VOL_INITIALIZE (H5OPEN H5P_CLS_VOL_INITIALIZE_ID_g) +#define H5P_REFERENCE_ACCESS (H5OPEN H5P_CLS_REFERENCE_ACCESS_ID_g) /* * The library's default property lists @@ -93,6 +94,7 @@ #define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g) #define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g) #define H5P_VOL_INITIALIZE_DEFAULT (H5OPEN H5P_LST_VOL_INITIALIZE_ID_g) +#define H5P_REFERENCE_ACCESS_DEFAULT (H5OPEN H5P_LST_REFERENCE_ACCESS_ID_g) /* Common creation order flags (for links in groups and attributes on objects) */ #define H5P_CRT_ORDER_TRACKED 0x0001 @@ -204,6 +206,7 @@ H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_ID_g; H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_ID_g; H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_ID_g; H5_DLLVAR hid_t H5P_CLS_VOL_INITIALIZE_ID_g; +H5_DLLVAR hid_t H5P_CLS_REFERENCE_ACCESS_ID_g; /* Default roperty list IDs */ /* (Internal to library, do not use! Use macros above) */ @@ -225,6 +228,7 @@ H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_ID_g; H5_DLLVAR hid_t H5P_LST_LINK_CREATE_ID_g; H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_ID_g; H5_DLLVAR hid_t H5P_LST_VOL_INITIALIZE_ID_g; +H5_DLLVAR hid_t H5P_LST_REFERENCE_ACCESS_ID_g; /*********************/ /* Public Prototypes */ @@ -11,22 +11,24 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* + * Purpose: Reference routines. + */ + /****************/ /* Module Setup */ /****************/ #include "H5Rmodule.h" /* This source code file is part of the H5R module */ - /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Rpkg.h" /* References */ #include "H5Sprivate.h" /* Dataspaces */ @@ -61,330 +63,825 @@ /*******************/ -/*-------------------------------------------------------------------------- - NAME - H5Rcreate - PURPOSE - Creates a particular kind of reference for the user - USAGE - herr_t H5Rcreate(ref, loc_id, name, ref_type, space_id) - void *ref; OUT: Reference created - hid_t loc_id; IN: Location ID used to locate object pointed to - const char *name; IN: Name of object at location LOC_ID of object - pointed to - H5R_type_t ref_type; IN: Type of reference to create - hid_t space_id; IN: Dataspace ID with selection, used for Dataset - Region references. - - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Creates a particular type of reference specified with REF_TYPE, in the - space pointed to by REF. The LOC_ID and NAME are used to locate the object - pointed to and the SPACE_ID is used to choose the region pointed to (for - Dataset Region references). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rcreate_object + * + * Purpose: Creates an object reference. The LOC_ID and NAME are used to locate + * the object pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) +H5Rcreate_object(hid_t loc_id, const char *name, H5R_ref_t *ref_ptr) { - H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "*xi*sRti", ref, loc_id, name, ref_type, space_id); + H5TRACE3("e", "i*s*Rr", loc_id, name, ref_ptr); /* Check args */ - if (ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(ref_type != H5R_OBJECT && ref_type != H5R_DATASET_REGION) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported") - if(space_id == (-1) && ref_type == H5R_DATASET_REGION) + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_object((const H5VL_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcreate_region + * + * Purpose: Creates a region reference. The LOC_ID and NAME are used to locate + * the object pointed to and the SPACE_ID is used to choose the region pointed + * to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, + H5R_ref_t *ref_ptr) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + struct H5S_t *space = NULL; /* Pointer to dataspace containing region */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*si*Rr", loc_id, name, space_id, ref_ptr); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + if((space_id == H5I_BADID) || (space_id == H5S_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") + if(NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_region((const H5VL_token_t *)&obj_token, cont_info.token_size, space, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcreate_attr + * + * Purpose: Creates an attribute reference. The LOC_ID, NAME and ATTR_NAME are + * used to locate the attribute pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, + H5R_ref_t *ref_ptr) +{ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID;/* File ID */ + H5VL_object_t *vol_obj_file = NULL; /* Object token of file_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*s*s*Rr", loc_id, name, attr_name, ref_ptr); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + if(!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name given") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object type */ + if((obj_type = H5I_get_type(loc_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - /* Set up collective metadata if appropriate */ - if(H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + /* Get the file for the object */ + if((file_id = H5F_get_file_id(loc_id, obj_type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL file object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.obj_type = obj_type; + + /* Get the object token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* Create the reference (do not pass filename, since file_id is attached) */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + if(H5R__create_attr((const H5VL_token_t *)&obj_token, cont_info.token_size, attr_name, (H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create attribute reference") + + /* Attach loc_id to reference and hold reference to it */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref_ptr, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference") + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement refcount on file") + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_attr() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rdestroy + * + * Purpose: Destroy reference and free resources allocated during H5Rcreate. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rdestroy(H5R_ref_t *ref_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "*Rr", ref_ptr); + + /* Check args */ + if(NULL == ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid reference pointer") + + /* Destroy reference */ + if(H5R__destroy((H5R_ref_priv_t *)ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "unable to destroy reference") + + /* Memset back to 0 for safety */ + HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rdestroy() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_type + * + * Purpose: Given a reference to some object, return the type of that reference. + * + * Return: Reference type/H5R_BADTYPE on failure + * + *------------------------------------------------------------------------- + */ +H5R_type_t +H5Rget_type(const H5R_ref_t *ref_ptr) +{ + H5R_type_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5R_BADTYPE) + H5TRACE1("Rt", "*Rr", ref_ptr); + + /* Check args */ + if(NULL == ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5R_BADTYPE, "invalid reference pointer") + + /* Get reference type */ + ret_value = H5R__get_type((const H5R_ref_priv_t *)ref_ptr); + if((ret_value <= H5R_BADTYPE) || (ret_value >= H5R_MAXTYPE)) + HGOTO_ERROR(H5E_REFERENCE, H5E_BADVALUE, H5R_BADTYPE, "invalid reference type") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5Requal + * + * Purpose: Compare two references + * + * Return: TRUE if equal, FALSE if unequal, FAIL if error + * + *------------------------------------------------------------------------- + */ +htri_t +H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("t", "*Rr*Rr", ref1_ptr, ref2_ptr); + + /* Check args */ + if(!ref1_ptr || !ref2_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + + /* Compare references */ + if((ret_value = H5R__equal((const H5R_ref_priv_t *)ref2_ptr, (const H5R_ref_priv_t *)ref2_ptr)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare references") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Requal() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rcopy + * + * Purpose: Copy a reference + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ - /* Get the file object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "*Rr*Rr", src_ref_ptr, dst_ref_ptr); - /* Set up collective metadata if appropriate */ - if(H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + /* Check args */ + if(NULL == src_ref_ptr || NULL == dst_ref_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid reference pointer") - /* Create reference */ - if((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_REF_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, ref, name, (int)ref_type, space_id)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create reference") + /* Copy reference */ + if(H5R__copy((const H5R_ref_priv_t *)src_ref_ptr, (H5R_ref_priv_t *)dst_ref_ptr) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "cannot copy reference") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rcreate() */ +} /* end H5Rcopy() */ -/*-------------------------------------------------------------------------- - NAME - H5Rdereference2 - PURPOSE - Opens the HDF5 object referenced. - USAGE - hid_t H5Rdereference2(ref) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - hid_t oapl_id; IN: Property list of the object being referenced. - H5R_type_t ref_type; IN: Type of reference to create - void *ref; IN: Reference to open. - - RETURNS - Valid ID on success, H5I_INVALID_HID on failure - DESCRIPTION - Given a reference to some object, open that object and return an ID for - that object. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG - Raymond Lu - 13 July 2011 - I added the OAPL_ID parameter for the object being referenced. It only - supports dataset access property list currently. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Ropen_object + * + * Purpose: Given a reference to some object, open that object and return an + * ID for that object. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) +H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5I_type_t opened_type; - void *opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE4("i", "iiRt*x", obj_id, oapl_id, ref_type, _ref); + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") if(oapl_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") - if(_ref == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") /* Verify access property list and set up collective metadata if appropriate */ - if(H5CX_set_apl(&oapl_id, H5P_CLS_DACC, obj_id, FALSE) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set access property list info") + if(H5CX_set_apl(&oapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") /* Get the VOL object */ - if(NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_REF; - loc_params.loc_data.loc_by_ref.ref_type = ref_type; - loc_params.loc_data.loc_by_ref._ref = _ref; - loc_params.loc_data.loc_by_ref.lapl_id = oapl_id; - loc_params.obj_type = H5I_get_type(obj_id); + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* Dereference */ + /* Open object by token */ if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to dereference object") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + /* Register object */ if((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rdereference2() */ +} /* end H5Ropen_object() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_region - PURPOSE - Retrieves a dataspace with the region pointed to selected. - USAGE - hid_t H5Rget_region(id, ref_type, ref) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to get region of - void *ref; IN: Reference to open. - - RETURNS - Valid ID on success, H5I_INVALID_HID on failure - DESCRIPTION - Given a reference to some object, creates a copy of the dataset pointed - to's dataspace and defines a selection in the copy which is the region - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Ropen_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy which is the + * region pointed to. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) +H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + H5S_t *space = NULL; /* Dataspace pointer (copy) */ + hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "iRt*x", id, ref_type, ref); + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); /* Check args */ - if(ref_type != H5R_DATASET_REGION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") - if(ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if((H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_DATASET_REGION1) + && (H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_DATASET_REGION2)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + if(oapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Open object by token */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + + /* Register object */ + if((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + + /* Get VOL object object */ + if(NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get dataspace from object */ + if(H5VL_dataset_get(opened_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &space_id) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace from dataset") + if(NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace") /* Get the dataspace with the correct region selected */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_REGION, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, (int)ref_type, ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve dataspace") + if(H5R__get_region((const H5R_ref_priv_t *)ref_ptr, space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get selection on dataspace") + + /* Simply return space_id */ + ret_value = space_id; + +done: + if((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object") + if(H5I_INVALID_HID == ret_value) /* Cleanup on failure */ + if((space_id != H5I_INVALID_HID) && (H5I_dec_ref(space_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close dataspace") + + FUNC_LEAVE_API(ret_value) +} /* end H5Ropen_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5Ropen_attr + * + * Purpose: Given a reference to some attribute, open that attribute and + * return an ID for that attribute. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) +{ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void *opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + void *opened_attr = NULL; /* Opened attribute */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_ATTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + if(aapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") + + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Open object by token */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + + /* Register object */ + if((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = opened_type; + + /* Get VOL object object */ + if(NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Open the attribute */ + if(NULL == (opened_attr = H5VL_attr_open(opened_obj, &loc_params, H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr), aapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr)) + + /* Register the attribute and get an ID for it */ + if((ret_value = H5VL_register(H5I_ATTR, opened_attr, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") done: + if((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0)) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object") + if(H5I_INVALID_HID == ret_value) /* Cleanup on failure */ + if(opened_attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_LEAVE_API(ret_value) -} /* end H5Rget_region() */ +} /* end H5Ropen_attr() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_obj_type2 - PURPOSE - Retrieves the type of object that an object reference points to - USAGE - herr_t H5Rget_obj_type2(id, ref_type, ref, obj_type) - hid_t id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to query - void *ref; IN: Reference to query. - H5O_type_t *obj_type; OUT: Type of object reference points to - - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Given a reference to some object, this function retrieves the type of - object pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rget_obj_type3 + * + * Purpose: Given a reference to some object, this function returns the type + * of object pointed to. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, - H5O_type_t *obj_type) +H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); + H5TRACE3("e", "*Rri*Ot", ref_ptr, rapl_id, obj_type); /* Check args */ - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(ref == NULL) + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, FAIL, "cannot re-open referenced file") + } + + /* Get object token */ + if(H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get object token") - /* Get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object type */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_type, (int)ref_type, ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object type") + /* Retrieve object's type */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_type) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object type") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_obj_type2() */ +} /* end H5Rget_obj_type3() */ -/*-------------------------------------------------------------------------- - NAME - H5Rget_name - PURPOSE - Determines a name for the object referenced - USAGE - ssize_t H5Rget_name(loc_id, ref_type, ref, name, size) - hid_t loc_id; IN: Dataset reference object is in or location ID of - object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to query. - char *name; OUT: Buffer to place name of object referenced. If NULL - then this call will return the size in bytes of name. - size_t size; IN: Size of name buffer (user needs to include NULL terminator - when passing in the size) - - RETURNS - Non-negative length of the path on success, -1 on failure - DESCRIPTION - Given a reference to some object, determine a path to the object - referenced in the file. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This may not be the only path to that object. - EXAMPLES - REVISION LOG - M. Scot Breitenfeld - 22 January 2014 - Changed the behavior for the returned value of the function when name is NULL. - If name is NULL then size is ignored and the function returns the size - of the name buffer (not including the NULL terminator), it still returns - negative on failure. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Rget_file_name + * + * Purpose: Given a reference to some object, determine a file name of the + * object located into. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ ssize_t -H5Rget_name(hid_t id, H5R_type_t ref_type, const void *_ref, char *name, - size_t size) +H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + hid_t loc_id; /* Reference location ID */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE5("Zs", "iRt*x*sz", id, ref_type, _ref, name, size); + H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); /* Check args */ - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") - if(_ref == NULL) + + /* Get name */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Un-opened external references do not have loc_id set but hold a + * copy of the filename */ + if((ret_value = H5R__get_file_name((const H5R_ref_priv_t *)ref_ptr, buf, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to retrieve file name") + } else { + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + + /* Retrieve VOL file object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + if(H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5I_FILE, size, buf, &ret_value) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get file name") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_file_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5Rget_obj_name + * + * Purpose: Given a reference to some object, determine a path to the object + * referenced in the file. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) +{ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API((-1)) + H5TRACE4("Zs", "*Rri*sz", ref_ptr, rapl_id, buf, size); + + /* Check args */ + if(ref_ptr == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) <= H5R_BADTYPE + || H5R__get_type((const H5R_ref_priv_t *)ref_ptr) >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") + if(rapl_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Retrieve loc_id from reference */ + if(H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + /* Attempt to re-open file and pass rapl_id as a fapl_id */ + if((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, (-1), "cannot re-open referenced file") + } - /* Get the file object */ - if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Get object token */ + if((ret_value = H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get object token") - /* Get name */ - if(H5VL_object_get(vol_obj, &loc_params, H5VL_REF_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, name, size, (int)ref_type, _ref) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to determine object path") + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Retrieve object's name */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, buf, size) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't retrieve object name") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_name() */ +} /* end H5Rget_obj_name() */ + +/*------------------------------------------------------------------------- + * Function: H5Rget_attr_name + * + * Purpose: Given a reference to some attribute, determine its name. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) +{ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API((-1)) + H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); + + /* Check args */ + if(ref_ptr == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference pointer") + if(H5R__get_type((const H5R_ref_priv_t *)ref_ptr) != H5R_ATTR) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid reference type") + + /* Get attribute name */ + if((ret_value = H5R__get_attr_name((const H5R_ref_priv_t *)ref_ptr, buf, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to determine attribute name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_attr_name() */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index ab8d3b4..b9bdffa 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -37,14 +37,15 @@ #include "H5Ppublic.h" /* Property lists */ /* Private headers needed by this file */ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Gprivate.h" /* Groups */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ -#include "H5Oprivate.h" /* Object headers */ +#include "H5Oprivate.h" /* Object headers */ #include "H5Rpkg.h" /* References */ +#include "H5Sprivate.h" /* Dataspaces */ /****************/ @@ -81,53 +82,58 @@ /* 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 */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5O_type_t obj_type; /* Object type */ + const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE3("Go", "iRt*x", id, ref_type, ref); /* Check args */ - if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type") - if (ref == NULL) + if(buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer") + if(ref_type != H5R_OBJECT1 && ref_type != H5R_DATASET_REGION1) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(id); + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") - /* Get the vol object */ - if (NULL == (vol_obj = H5VL_vol_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid file identifier") + /* Get object token */ + if(H5R__decode_token_compat(id, vol_obj_type, ref_type, buf, &obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5G_UNKNOWN, "unable to get object token") - /* 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") + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = vol_obj_type; + + /* Retrieve object's type */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &obj_type) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, H5G_UNKNOWN, "can't retrieve object type") /* Set return value */ ret_value = H5G_map_obj_type(obj_type); @@ -140,54 +146,58 @@ done: /*------------------------------------------------------------------------- * Function: H5Rdereference1 * - * Purpose: Opens the HDF5 object referenced. - * - * Parameters: - * id IN: Dataset reference object is in or location ID of - * object that the dataset is located within - * ref_type IN: Type of reference to create - * ref IN: Reference to open + * Purpose: Given a reference to some object, open that object and return an + * ID for that object. * - * Return: Success: Valid HDF5 ID - * Failure: H5I_INVALID_HID + * Return: Valid ID on success/Negative on failure * *------------------------------------------------------------------------- */ hid_t -H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *_ref) +H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t *vol_obj = NULL; /* object token of loc_id */ - H5I_type_t opened_type; - void *opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID;/* Object type of loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_token_t obj_token = {0}; /* Object token */ + 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") + + /* 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") - loc_params.type = H5VL_OBJECT_BY_REF; - loc_params.loc_data.loc_by_ref.ref_type = ref_type; - loc_params.loc_data.loc_by_ref._ref = _ref; - loc_params.loc_data.loc_by_ref.lapl_id = H5P_DATASET_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(obj_id); + /* Get object token */ + if(H5R__decode_token_compat(obj_id, vol_obj_type, ref_type, buf, &obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5I_INVALID_HID, "unable to get object token") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + 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 token") - /* 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 +205,361 @@ 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 */ + H5VL_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + void *vol_obj_file = NULL; + 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") + + /* 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 token */ + if(H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") + + /* 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") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + /* Create reference */ + if(ref_type == H5R_OBJECT1) { + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + + if((ret_value = H5R__encode_token_obj_compat((const H5VL_token_t *)&obj_token, cont_info.token_size, buf, &buf_size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to encode object reference") + } else { + H5F_t *f = NULL; + H5S_t *space = NULL; /* Pointer to dataspace containing region */ + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + + /* 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") + + /* Currently restrict API usage to native VOL + * TODO check for terminal connector or use capability flag */ + + /* 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") + + /* Encode dataset region */ + if((ret_value = H5R__encode_token_region_compat(f, (const H5VL_token_t *)&obj_token, cont_info.token_size, 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 */ + H5VL_token_t obj_token = {0}; /* Object token */ + 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") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object token */ + if(H5R__decode_token_compat(id, vol_obj_type, ref_type, buf, &obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object token") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + 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 */ + H5VL_token_t obj_token = {0}; /* Object token */ + 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") + + /* 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 token */ + if(H5R__decode_token_compat(obj_id, vol_obj_type, ref_type, buf, &obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, H5I_INVALID_HID, "unable to get object token") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = vol_obj_type; + + /* Open object by token */ + if(NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") + + /* Register object */ + if((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 */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + 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") + + /* 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") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get container info") + + /* 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_token_region_compat(f, buf, &buf_size, NULL, cont_info.token_size, &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 */ + H5VL_token_t obj_token = {0}; /* Object token */ + 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") + + /* Get object type */ + if((vol_obj_type = H5I_get_type(id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + + /* Get object token */ + if(H5R__decode_token_compat(id, vol_obj_type, ref_type, buf, &obj_token) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, (-1), "unable to get object token") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_TOKEN; + loc_params.loc_data.loc_by_token.token = obj_token; + loc_params.obj_type = vol_obj_type; + + /* Retrieve object's name */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, name, size) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't retrieve object name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_name() */ diff --git a/src/H5Rint.c b/src/H5Rint.c index 07efae2..443a245 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -35,11 +35,73 @@ #include "H5Sprivate.h" /* Dataspaces */ #include "H5Tprivate.h" /* Datatypes */ - /****************/ /* Local Macros */ /****************/ +#define H5R_MAX_STRING_LEN (1 << 16) /* Max encoded string length */ + +/* Encode macro */ +#define H5R_ENCODE(func, val, buf, buf_size, actual, m) do {\ + size_t __nalloc = buf_size; \ + if(func(val, buf, &__nalloc) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \ + if(buf && buf_size >= __nalloc) { \ + buf += __nalloc; \ + buf_size -= __nalloc; \ + } \ + actual += __nalloc; \ +} while(0) + +#define H5R_ENCODE_VAR(func, var, size, buf, buf_size, actual, m) do { \ + size_t __nalloc = buf_size; \ + if(func(var, size, buf, &__nalloc) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \ + if(buf && buf_size >= __nalloc) { \ + p += __nalloc; \ + buf_size -= __nalloc; \ + } \ + actual += __nalloc; \ +} while(0) + +/* Decode macro */ +#define H5R_DECODE(func, val, buf, buf_size, actual, m) do {\ + size_t __nbytes = buf_size; \ + if(func(buf, &__nbytes, val) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \ + buf += __nbytes; \ + buf_size -= __nbytes; \ + actual += __nbytes; \ +} while(0) + +#define H5R_DECODE_VAR(func, var, size, buf, buf_size, actual, m) do { \ + size_t __nbytes = buf_size; \ + if(func(buf, &__nbytes, var, size) < 0) \ + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \ + p += __nbytes; \ + buf_size -= __nbytes; \ + actual += __nbytes; \ +} while(0) + +/* Debug */ +//#define H5R_DEBUG +#ifdef H5R_DEBUG +#define H5R_LOG_DEBUG(...) do { \ + HDfprintf(stdout, " # %s(): ", __func__); \ + HDfprintf(stdout, __VA_ARGS__); \ + HDfprintf(stdout, "\n"); \ + HDfflush(stdout); \ + } while (0) +static const char * +H5R__print_token(const H5VL_token_t token) { + static char string[64]; + HDsnprintf(string, 64, "%zu", *(haddr_t *)token); + return string; +} +#else +#define H5R_LOG_DEBUG(...) do { } while (0) +#endif + /******************/ /* Local Typedefs */ /******************/ @@ -48,6 +110,13 @@ /* Local Prototypes */ /********************/ +static herr_t H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, uint8_t *token_size); +static herr_t H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr); +static herr_t H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -82,14 +151,15 @@ DESCRIPTION herr_t H5R__init_package(void) { - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR /* Mark "top" of interface as initialized */ H5R_top_package_initialize_s = TRUE; - FUNC_LEAVE_NOAPI(ret_value) + /* Sanity check, if assert fails, H5R_REF_BUF_SIZE must be increased */ + HDcompile_assert(sizeof(H5R_ref_priv_t) <= H5R_REF_BUF_SIZE); + + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5R__init_package() */ @@ -167,571 +237,1488 @@ H5R_term_package(void) } /* end H5R_term_package() */ -/*-------------------------------------------------------------------------- - NAME - H5R__create - PURPOSE - Creates a particular kind of reference for the user - USAGE - herr_t H5R__create(ref, loc, name, ref_type, space) - void *ref; OUT: Reference created - H5G_loc_t *loc; IN: File location used to locate object pointed to - const char *name; IN: Name of object at location LOC_ID of object - pointed to - H5R_type_t ref_type; IN: Type of reference to create - H5S_t *space; IN: Dataspace ID with selection, used for Dataset - Region references. +/*------------------------------------------------------------------------- + * Function: H5R__create_object + * + * Purpose: Creates an object reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, + H5R_ref_priv_t *ref) +{ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Creates a particular type of reference specified with REF_TYPE, in the - space pointed to by REF. The LOC_ID and NAME are used to locate the object - pointed to and the SPACE_ID is used to choose the region pointed to (for - Dataset Region references). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE + + HDassert(ref); + + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_OBJECT2; + ref->token_size = (uint8_t)token_size; + + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; + + H5R_LOG_DEBUG("Created object reference, %d, filename=%s, obj_addr=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__create_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__create_region + * + * Purpose: Creates a region reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space) +H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, + H5S_t *space, H5R_ref_priv_t *ref) { - H5G_loc_t obj_loc; /* Group hier. location of object */ - H5G_name_t path; /* Object group hier. path */ - H5O_loc_t oloc; /* Object object location */ - hbool_t obj_found = FALSE; /* Object location found */ - herr_t ret_value = SUCCEED; /* Return value */ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(loc); - HDassert(name); - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); + HDassert(space); + HDassert(ref); - /* Set up object location to fill in */ - obj_loc.oloc = &oloc; - obj_loc.path = &path; - H5G_loc_reset(&obj_loc); + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + if(NULL == (ref->ref.reg.space = H5S_copy(space, FALSE, TRUE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") - /* Set the FAPL for the API context */ - H5CX_set_libver_bounds(loc->oloc->file); + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_DATASET_REGION2; + ref->token_size = (uint8_t)token_size; - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; - switch (ref_type) { - case H5R_OBJECT: - { - hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + H5R_LOG_DEBUG("Created region reference, %d, filename=%s, obj_addr=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); - *ref = obj_loc.oloc->addr; - break; +done: + if(ret_value < 0) { + if(ref->ref.reg.space) { + H5S_close(ref->ref.reg.space); + ref->ref.reg.space = NULL; } + } + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__create_region */ - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - hssize_t buf_size; /* Size of buffer needed to serialize selection */ - uint8_t *p; /* Pointer to OID to store */ - uint8_t *buf; /* Buffer to store serialized selection in */ - unsigned heapid_found; /* Flag for non-zero heap ID found */ - unsigned u; /* local index */ - - /* Set up information for dataset region */ - - /* Return any previous heap block to the free list if we are - * garbage collecting - */ - if (H5F_GC_REF(loc->oloc->file)) { - /* Check for an existing heap ID in the reference */ - for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++) - if (p[u] != 0) { - heapid_found = 1; - break; - } - - if (heapid_found != 0) { - /* Return heap block to free list */ - } - } - - /* Zero the heap ID out, may leak heap space if user is re-using - * reference and doesn't have garbage collection turned on - */ - HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE); - - /* Get the amount of space required to serialize the selection */ - if ((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") - - /* Increase buffer size to allow for the dataset OID */ - buf_size += (hssize_t)sizeof(haddr_t); - - /* Allocate the space to store the serialized information */ - H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); - if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Serialize information for dataset OID into heap buffer */ - p = (uint8_t *)buf; - H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); - - /* Serialize the selection into heap buffer */ - if (H5S_SELECT_SERIALIZE(space, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") - - /* Save the serialized buffer for later */ - H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); - if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection") - - /* Serialize the heap ID and index for storage in the file */ - p = (uint8_t *)ref; - H5F_addr_encode(loc->oloc->file, &p, hobjid.addr); - UINT32ENCODE(p, hobjid.idx); - - /* Free the buffer we serialized data in */ - H5MM_xfree(buf); - break; - } /* end case H5R_DATASET_REGION */ + +/*------------------------------------------------------------------------- + * Function: H5R__create_attr + * + * Purpose: Creates an attribute reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, + const char *attr_name, H5R_ref_priv_t *ref) +{ + size_t encode_size; + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + + HDassert(attr_name); + HDassert(ref); + + /* Make sure that attribute name is not longer than supported encode size */ + if(HDstrlen(attr_name) > H5R_MAX_STRING_LEN) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "attribute name too long (%d > %d)", (int)HDstrlen(attr_name), H5R_MAX_STRING_LEN) + + /* Create new reference */ + H5MM_memcpy(ref->ref.obj.token, obj_token, token_size); + ref->ref.obj.filename = NULL; + if(NULL == (ref->ref.attr.name = HDstrdup(attr_name))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") + + ref->loc_id = H5I_INVALID_HID; + ref->type = (uint8_t)H5R_ATTR; + ref->token_size = (uint8_t)token_size; + + /* Cache encoding size (assume no external reference) */ + if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size") + ref->encode_size = (uint32_t)encode_size; + + H5R_LOG_DEBUG("Created attribute reference, %d, filename=%s, obj_addr=%s, attr name=%s, encode size=%u", + (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->ref.attr.name, ref->encode_size); + +done: + if(ret_value < 0) + ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__create_attr */ + + +/*------------------------------------------------------------------------- + * Function: H5R__destroy + * + * Purpose: Destroy reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__destroy(H5R_ref_priv_t *ref) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + HDassert(ref != NULL); + + ref->ref.obj.filename = H5MM_xfree(ref->ref.obj.filename); + + switch(ref->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + if(H5S_close(ref->ref.reg.space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace") + ref->ref.reg.space = NULL; + break; + case H5R_ATTR: + ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ -done: - if (obj_found) - H5G_loc_free(&obj_loc); + /* Decrement refcount of attached loc_id */ + if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed") +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__create() */ +} /* end H5R__destroy() */ -/*-------------------------------------------------------------------------- - NAME - H5R__dereference - PURPOSE - Opens the HDF5 object referenced. - USAGE - hid_t H5R__dereference(ref, oapl_id, ref_type, ref) - H5F_t *file; IN: File the object being dereferenced is within - hid_t oapl_id; IN: Object access property list ID - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to open. +/*------------------------------------------------------------------------- + * Function: H5R__set_loc_id + * + * Purpose: Attach location ID to reference and increment location refcount. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref) +{ + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Valid ID on success, Negative on failure - DESCRIPTION - Given a reference to some object, open that object and return an ID for - that object. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Currently only set up to work with references to datasets - EXAMPLES - REVISION LOG - Raymond Lu - 13 July 2011 - I added the OAPL_ID parameter for the object being referenced. It only - supports dataset access property list currently. - - M. Scot Breitenfeld - 3 March 2015 - Added a check for undefined reference pointer. ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE + + HDassert(ref != NULL); + HDassert(id != H5I_INVALID_HID); + + /* If a location ID was previously assigned, decrement refcount and assign new one */ + if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed") + ref->loc_id = id; + + /* Prevent location ID from being freed until reference is destroyed */ + if(inc_ref && H5I_inc_ref(ref->loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINC, FAIL, "incrementing location ID failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__set_loc_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__get_loc_id + * + * Purpose: Retrieve location ID attached to existing reference. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ hid_t -H5R__dereference(H5F_t *file, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) +H5R__get_loc_id(const H5R_ref_priv_t *ref) { - H5O_loc_t oloc; /* Object location */ - H5G_name_t path; /* Path of object */ - H5G_loc_t loc; /* Group location */ - unsigned rc; /* Reference count of object */ - H5O_type_t obj_type; /* Type of object */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ + FUNC_ENTER_PACKAGE_NOERR + + HDassert(ref != NULL); + + ret_value = ref->loc_id; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_loc_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__reopen_file + * + * Purpose: Re-open referenced file using file access property list. + * + * Return: Valid ID on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) +{ + void *new_file = NULL; + H5VL_connector_prop_t connector_prop; + unsigned flags = H5F_ACC_RDWR; /* Must open file read-write to allow for object modifications */ + H5P_genplist_t *plist; + hid_t ret_value = H5I_INVALID_HID; + FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); - HDassert(file); + /* TODO add search path */ - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = file; + /* Verify access property list and set up collective metadata if appropriate */ + if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - switch (ref_type) { - case H5R_OBJECT: - { - oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ - if (!H5F_addr_defined(oloc.addr) || oloc.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") - break; - } + /* Get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file access property list") + if(H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info") - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ + /* Stash a copy of the "top-level" connector property, before any pass-through + * connectors modify or unwrap it. + */ + if(H5CX_set_vol_connector_prop(&connector_prop) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context") - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); + /* Open the file */ + if(NULL == (new_file = H5VL_file_open(&connector_prop, H5R_REF_FILENAME(ref), flags, fapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file") - if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") + /* Get an ID for the file */ + if((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5I_INVALID_HID, "Unable to read dataset region information") + /* Attach loc_id to reference */ + if(H5R__set_loc_id((H5R_ref_priv_t *)ref, ret_value, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "unable to attach location id to reference") - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__reopen_file() */ - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - break; - } /* end case H5R_DATASET_REGION */ + +/*------------------------------------------------------------------------- + * Function: H5R__get_type + * + * Purpose: Given a reference to some object, return the type of that reference. + * + * Return: Type of the reference + * + *------------------------------------------------------------------------- + */ +H5R_type_t +H5R__get_type(const H5R_ref_priv_t *ref) +{ + H5R_type_t ret_value = H5R_BADTYPE; + + FUNC_ENTER_PACKAGE_NOERR + HDassert(ref != NULL); + ret_value = ref->type; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__equal + * + * Purpose: Compare two references + * + * Return: TRUE if equal, FALSE if unequal, FAIL if error + * + *------------------------------------------------------------------------- + */ +htri_t +H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2) +{ + htri_t ret_value = TRUE; + + FUNC_ENTER_PACKAGE + + HDassert(ref1 != NULL); + HDassert(ref2 != NULL); + + /* Compare reference types */ + if(ref1->type != ref2->type) + HGOTO_DONE(FALSE); + + /* Compare object addresses */ + if(ref1->token_size != ref2->token_size) + HGOTO_DONE(FALSE); + if(0 != HDmemcmp(ref1->ref.obj.token, ref2->ref.obj.token, ref1->token_size)) + HGOTO_DONE(FALSE); + + /* Compare filenames */ + if((ref1->ref.obj.filename && (NULL == ref2->ref.obj.filename)) + || ((NULL == ref1->ref.obj.filename) && ref2->ref.obj.filename)) + HGOTO_DONE(FALSE); + if(ref1->ref.obj.filename && ref1->ref.obj.filename + && (0 != HDstrcmp(ref1->ref.obj.filename, ref2->ref.obj.filename))) + HGOTO_DONE(FALSE); + + switch(ref1->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + if((ret_value = H5S_extent_equal(ref1->ref.reg.space, ref2->ref.reg.space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare dataspace extents") + break; + case H5R_ATTR: + HDassert(ref1->ref.attr.name && ref2->ref.attr.name); + if(0 != HDstrcmp(ref1->ref.attr.name, ref2->ref.attr.name)) + HGOTO_DONE(FALSE); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); - HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5I_INVALID_HID, "internal error (unknown reference type)") + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Get the # of links for object, and its type - * (To check to make certain that this object hasn't been deleted - * since the reference was created) - */ - if(H5O_get_rc_and_type(&oloc, &rc, &obj_type) < 0 || 0 == rc) - HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5I_INVALID_HID, "dereferencing deleted object") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__equal() */ - /* Construct a group location for opening the object */ - H5G_name_reset(&path); - loc.oloc = &oloc; - loc.path = &path; + +/*------------------------------------------------------------------------- + * Function: H5R__copy + * + * Purpose: Copy a reference + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) +{ + herr_t ret_value = SUCCEED; - /* Open the object */ - switch (obj_type) { - case H5O_TYPE_GROUP: - { - H5G_t *group; /* Pointer to group to open */ + FUNC_ENTER_PACKAGE - if(NULL == (group = H5G_open(&loc))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5I_INVALID_HID, "not found") + HDassert((src_ref != NULL) && (dst_ref != NULL)); - /* Create an atom for the group */ - if((ret_value = H5I_register(H5I_GROUP, group, TRUE)) < 0) { - H5G_close(group); - HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register group") - } + H5MM_memcpy(dst_ref->ref.obj.token, src_ref->ref.obj.token, src_ref->token_size); + dst_ref->encode_size = src_ref->encode_size; + dst_ref->type = src_ref->type; + dst_ref->token_size = src_ref->token_size; + switch(src_ref->type) { + case H5R_OBJECT2: break; - } - - case H5O_TYPE_NAMED_DATATYPE: - { - H5T_t *type; /* Pointer to datatype to open */ - - if(NULL == (type = H5T_open(&loc))) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, H5I_INVALID_HID, "not found") + case H5R_DATASET_REGION2: + if(NULL == (dst_ref->ref.reg.space = H5S_copy(src_ref->ref.reg.space, FALSE, TRUE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") + break; + case H5R_ATTR: + if(NULL == (dst_ref->ref.attr.name = HDstrdup(src_ref->ref.attr.name))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name") + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ - /* Create an atom for the datatype */ - if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) { - H5T_close(type); - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register datatype") - } + /* We only need to keep a copy of the filename if we don't have the loc_id */ + if(src_ref->loc_id == H5I_INVALID_HID) { + HDassert(src_ref->ref.obj.filename); - break; - } + if(NULL == (dst_ref->ref.obj.filename = HDstrdup(src_ref->ref.obj.filename))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy filename") + dst_ref->loc_id = H5I_INVALID_HID; + } else { + dst_ref->ref.obj.filename = NULL; - case H5O_TYPE_DATASET: - { - H5D_t *dset; /* Pointer to dataset to open */ + /* Set location ID and hold reference to it */ + if(H5R__set_loc_id(dst_ref, src_ref->loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "cannot set reference location ID") + } - /* Open the dataset */ - if(NULL == (dset = H5D_open(&loc, oapl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, H5I_INVALID_HID, "not found") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__copy() */ - /* Create an atom for the dataset */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) { - H5D_close(dset); - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset") - } + +/*------------------------------------------------------------------------- + * Function: H5R__get_obj_token + * + * Purpose: Given a reference to some object, get the encoded object addr. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, + size_t *token_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ - break; - } + FUNC_ENTER_PACKAGE - case H5O_TYPE_MAP: - HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "maps not supported in native VOL connector") + HDassert(ref != NULL); + HDassert(ref->token_size <= H5VL_MAX_TOKEN_SIZE); - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: - HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "can't identify type of object referenced") - } /* end switch */ + if(obj_token) { + if(0 == ref->token_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "NULL token size") + H5MM_memcpy(obj_token, ref->ref.obj.token, ref->token_size); + } + if(token_size) + *token_size = ref->token_size; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__dereference() */ +} /* end H5R__get_obj_token() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_region - PURPOSE - Retrieves a dataspace with the region pointed to selected. - USAGE - H5S_t *H5R__get_region(file, ref) - H5F_t *file; IN: File the object being dereferenced is within - void *ref; IN: Reference to open. +/*------------------------------------------------------------------------- + * Function: H5R__set_obj_token + * + * Purpose: Given a reference to some object, set the encoded object addr. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, + size_t token_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ - RETURNS - Pointer to the dataspace on success, NULL on failure - DESCRIPTION - Given a reference to some object, creates a copy of the dataset pointed - to's dataspace and defines a selection in the copy which is the region - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -H5S_t * -H5R__get_region(H5F_t *file, const void *_ref) + FUNC_ENTER_PACKAGE_NOERR + + HDassert(ref != NULL); + HDassert(obj_token); + HDassert(token_size); + HDassert(token_size <= H5VL_MAX_TOKEN_SIZE); + + H5MM_memcpy(ref->ref.obj.token, obj_token, ref->token_size); + ref->token_size = token_size; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__set_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__get_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy which is the + * region pointed to. + * + * Return: Pointer to the dataspace on success/NULL on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space) { - H5O_loc_t oloc; /* Object location */ - const uint8_t *p; /* Pointer to OID to store */ - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf = NULL; /* Buffer to store serialized selection in */ - H5S_t *ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - HDassert(_ref); - HDassert(file); + HDassert(ref != NULL); + HDassert(ref->type == H5R_DATASET_REGION2); + HDassert(space); - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = file; + /* Copy reference selection to destination */ + if(H5S_select_copy(space, ref->ref.reg.space, FALSE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy selection") - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_region() */ - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information") + +/*------------------------------------------------------------------------- + * Function: H5R__get_file_name + * + * Purpose: Given a reference to some object, determine a file name of the + * object located into. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size) +{ + size_t copy_len; + ssize_t ret_value = -1; /* Return value */ - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + FUNC_ENTER_PACKAGE - /* Open and copy the dataset's dataspace */ - if(NULL == (ret_value = H5S_read(&oloc))) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found") + /* Check args */ + HDassert(ref != NULL); - /* Unserialize the selection */ - if(H5S_SELECT_DESERIALIZE(&ret_value, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") + /* Return if that reference has no filename set */ + if(!ref->ref.obj.filename) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, (-1), "no filename available for that reference") -done: - /* Free the buffer allocated in H5HG_read() */ - if(buf) - H5MM_xfree(buf); + /* Get the file name length */ + copy_len = HDstrlen(ref->ref.obj.filename); + HDassert(copy_len <= H5R_MAX_STRING_LEN); + + /* Copy the file name */ + if(buf) { + copy_len = MIN(copy_len, size - 1); + H5MM_memcpy(buf, ref->ref.obj.filename, copy_len); + buf[copy_len] = '\0'; + } + ret_value = (ssize_t)(copy_len + 1); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_region() */ +} /* end H5R__get_file_name() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_obj_type - PURPOSE - Retrieves the type of object that an object reference points to - USAGE - H5O_type_t H5R__get_obj_type(file, ref_type, ref) - H5F_t *file; IN: File the object being dereferenced is within - H5R_type_t ref_type; IN: Type of reference to query - void *ref; IN: Reference to query. - H5O_type_t *obj_type; OUT: The type of the object, set on success +/*------------------------------------------------------------------------- + * Function: H5R__get_attr_name + * + * Purpose: Given a reference to some attribute, determine its name. + * + * Return: Non-negative length of the path on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +ssize_t +H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size) +{ + ssize_t ret_value = -1; /* Return value */ + size_t attr_name_len; /* Length of the attribute name */ - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Given a reference to some object, this function returns the type of object - pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ + FUNC_ENTER_PACKAGE_NOERR + + /* Check args */ + HDassert(ref != NULL); + HDassert(ref->type == H5R_ATTR); + + /* Get the attribute name length */ + attr_name_len = HDstrlen(ref->ref.attr.name); + HDassert(attr_name_len <= H5R_MAX_STRING_LEN); + + /* Get the attribute name */ + if(buf) { + size_t copy_len = MIN(attr_name_len, size - 1); + H5MM_memcpy(buf, ref->ref.attr.name, copy_len); + buf[copy_len] = '\0'; + } + + ret_value = (ssize_t)(attr_name_len + 1); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_attr_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode + * + * Purpose: Private function for H5Rencode. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref, - H5O_type_t *obj_type) +H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, + size_t *nalloc, unsigned flags) { - H5O_loc_t oloc; /* Object location */ - unsigned rc; /* Reference count of object */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *p = (uint8_t *)buf; + size_t buf_size = 0, encode_size = 0; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - HDassert(file); - HDassert(_ref); + HDassert(ref); + HDassert(nalloc); + + /** + * Encoding format: + * | Reference type (8 bits) | Flags (8 bits) | Token (token size) + * | | + * | |----> H5R_IS_EXTERNAL: File info + * | + * |----> H5R_DATASET_REGION2: Serialized selection + * | + * |----> H5R_ATTR: Attribute name len + name + * + */ + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= H5R_ENCODE_HEADER_SIZE) { + /* Encode the type of the reference */ + *p++ = (uint8_t)ref->type; + + /* Encode the flags */ + *p++ = (uint8_t)flags; - /* Initialize the symbol table entry */ - H5O_loc_reset(&oloc); - oloc.file = file; + buf_size = *nalloc - H5R_ENCODE_HEADER_SIZE; + } + encode_size += H5R_ENCODE_HEADER_SIZE; + + /* Encode object token */ + H5R_ENCODE_VAR(H5R__encode_obj_token, &ref->ref.obj.token, ref->token_size, + p, buf_size, encode_size, "Cannot encode object address"); + + /** + * TODO Encode VOL info + * When we have a better way of storing blobs, we should add + * support for referencing files in external VOLs. + * There are currently multiple limitations: + * - avoid duplicating VOL info on each reference + * - must query terminal VOL connector to avoid passthrough confusion + */ + if(flags & H5R_IS_EXTERNAL) { + /* Encode file name */ + H5R_ENCODE(H5R__encode_string, filename, p, buf_size, encode_size, + "Cannot encode filename"); + } - switch (ref_type) { - case H5R_OBJECT: - { - /* Get the object oid */ - oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + switch(ref->type) { + case H5R_OBJECT2: break; - } + case H5R_DATASET_REGION2: + /* Encode dataspace */ + H5R_ENCODE(H5R__encode_region, ref->ref.reg.space, p, buf_size, + encode_size, "Cannot encode region"); + break; + case H5R_ATTR: + /* Encode attribute name */ + H5R_ENCODE(H5R__encode_string, ref->ref.attr.name, p, buf_size, + encode_size, "Cannot encode attribute name"); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: + case H5R_BADTYPE: + case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - const uint8_t *p; /* Pointer to reference to decode */ - uint8_t *buf; /* Buffer to store serialized selection in */ + *nalloc = encode_size; - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode() */ - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + +/*------------------------------------------------------------------------- + * Function: H5R__decode + * + * Purpose: Private function for H5Rdecode. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size = 0, decode_size = 0; + uint8_t flags; + herr_t ret_value = SUCCEED; - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + FUNC_ENTER_PACKAGE - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); + HDassert(buf); + HDassert(nbytes); + HDassert(ref); + buf_size = *nbytes; - break; - } + /* Don't decode if buffer size isn't big enough */ + if(buf_size < H5R_ENCODE_HEADER_SIZE) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Set new reference */ + ref->type = (H5R_type_t)*p++; + if(ref->type <= H5R_BADTYPE || ref->type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + + /* Set flags */ + flags = *p++; + buf_size -= H5R_ENCODE_HEADER_SIZE; + decode_size += H5R_ENCODE_HEADER_SIZE; + + /* Decode object token */ + H5R_DECODE_VAR(H5R__decode_obj_token, &ref->ref.obj.token, &ref->token_size, + p, buf_size, decode_size, "Cannot decode object address"); + + /* We do not need to store the filename if the reference is internal */ + if(flags & H5R_IS_EXTERNAL) { + /* Decode file name */ + H5R_DECODE(H5R__decode_string, &ref->ref.obj.filename, p, buf_size, + decode_size, "Cannot decode filename"); + } else + ref->ref.obj.filename = NULL; + + switch(ref->type) { + case H5R_OBJECT2: + break; + case H5R_DATASET_REGION2: + /* Decode dataspace */ + H5R_DECODE(H5R__decode_region, &ref->ref.reg.space, p, buf_size, + decode_size, "Cannot decode region"); + break; + case H5R_ATTR: + /* Decode attribute name */ + H5R_DECODE(H5R__decode_string, &ref->ref.attr.name, p, buf_size, + decode_size, "Cannot decode attribute name"); + break; + case H5R_OBJECT1: + case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: + HDassert("invalid reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)") default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - /* Get the # of links for object, and its type */ - /* (To check to make certain that this object hasn't been deleted since the reference was created) */ - if(H5O_get_rc_and_type(&oloc, &rc, obj_type) < 0 || 0 == rc) - HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") + /* Set loc ID to invalid */ + ref->loc_id = H5I_INVALID_HID; + + /* Set encoding size */ + ref->encode_size = decode_size; + + H5R_LOG_DEBUG("Decoded reference, filename=%s, obj_addr=%s, encode size=%u", + ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token), + ref->encode_size); + + *nbytes = decode_size; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_obj_type() */ +} /* end H5R__decode() */ -/*-------------------------------------------------------------------------- - NAME - H5R__get_name - PURPOSE - Internal routine to determine a name for the object referenced - USAGE - ssize_t H5R__get_name(f, ref_type, ref, name, size) - H5F_t *f; IN: Pointer to the file that the reference is pointing - into - hid_t lapl_id; IN: LAPL to use for operation - hid_t id; IN: Location ID given for reference - H5R_type_t ref_type; IN: Type of reference - void *_ref; IN: Reference to query. - char *name; OUT: Buffer to place name of object referenced - size_t size; IN: Size of name buffer +/*------------------------------------------------------------------------- + * Function: H5R__encode_obj_token + * + * Purpose: Encode an object address. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, + unsigned char *buf, size_t *nalloc) +{ + herr_t ret_value = SUCCEED; - RETURNS - Non-negative length of the path on success, -1 on failure - DESCRIPTION - Given a reference to some object, determine a path to the object - referenced in the file. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This may not be the only path to that object. - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -ssize_t -H5R__get_name(H5F_t *f, H5R_type_t ref_type, const void *_ref, - char *name, size_t size) + FUNC_ENTER_STATIC_NOERR + + HDassert(nalloc); + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= token_size) { + uint8_t *p = (uint8_t *)buf; + + /* Encode token size */ + *p++ = (uint8_t)(token_size & 0xff); + + /* Encode token */ + H5MM_memcpy(p, obj_token, token_size); + } + *nalloc = token_size + H5_SIZEOF_UINT8_T; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_obj_token + * + * Purpose: Decode an object address. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, + H5VL_token_t *obj_token, uint8_t *token_size) { - H5O_loc_t oloc; /* Object location describing object for reference */ - ssize_t ret_value = -1; /* Return value */ + const uint8_t *p = (const uint8_t *)buf; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(obj_token); + HDassert(token_size); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < H5_SIZEOF_UINT8_T) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get token size */ + *token_size = *p++; + if(*token_size > sizeof(H5VL_token_t)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Invalid token size (%u)", *token_size) + + /* Decode token */ + H5MM_memcpy(obj_token, p, *token_size); + + *nbytes = *token_size + H5_SIZEOF_UINT8_T; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_obj_token() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_region + * + * Purpose: Encode a selection. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc) +{ + uint8_t *p = NULL; /* Pointer to data to store */ + hssize_t buf_size = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(space); + HDassert(nalloc); + + /* Get the amount of space required to serialize the selection */ + if((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot determine amount of space needed for serializing selection") + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= ((size_t)buf_size + 2 * H5_SIZEOF_UINT32_T)) { + p = (uint8_t *)buf; + int rank; + + /* Encode the size for safety check */ + UINT32ENCODE(p, (uint32_t)buf_size); + + /* Encode the extent rank */ + if((rank = H5S_get_simple_extent_ndims(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get extent rank for selection") + UINT32ENCODE(p, (uint32_t)rank); + + /* Serialize the selection */ + if(H5S_SELECT_SERIALIZE(space, (unsigned char **)&p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't serialize selection") + } + *nalloc = (size_t)buf_size + 2 * H5_SIZEOF_UINT32_T; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_region + * + * Purpose: Decode a selection. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size = 0; + unsigned rank; + H5S_t *space; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(space_ptr); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < (2 * H5_SIZEOF_UINT32_T)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Decode the selection size */ + UINT32DECODE(p, buf_size); + buf_size += H5_SIZEOF_UINT32_T; + + /* Decode the extent rank */ + UINT32DECODE(p, rank); + buf_size += H5_SIZEOF_UINT32_T; + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Deserialize the selection (dataspaces need the extent rank information) */ + if(NULL == (space = H5S_create(H5S_SIMPLE))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + if(H5S_set_extent_simple(space, rank, NULL, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set extent rank for selection") + if(H5S_SELECT_DESERIALIZE(&space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection") + + *nbytes = buf_size; + *space_ptr = space; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_region() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_string + * + * Purpose: Encode a string. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc) +{ + size_t string_len, buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(string); + HDassert(nalloc); + + /* Get the amount of space required to serialize the string */ + string_len = HDstrlen(string); + if(string_len > H5R_MAX_STRING_LEN) + HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "string too long") + + /* Compute buffer size, allow for the attribute name length and object address */ + buf_size = string_len + sizeof(uint16_t); + + if(buf && *nalloc >= buf_size) { + uint8_t *p = (uint8_t *)buf; + /* Serialize information for string length into the buffer */ + UINT16ENCODE(p, string_len); + /* Copy the string into the buffer */ + H5MM_memcpy(p, string, string_len); + } + *nalloc = buf_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_string() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_string + * + * Purpose: Decode a string. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr) +{ + const uint8_t *p = (const uint8_t *)buf; + size_t string_len; + char *string = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(buf); + HDassert(nbytes); + HDassert(string_ptr); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < sizeof(uint16_t)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the string length */ + UINT16DECODE(p, string_len); + HDassert(string_len <= H5R_MAX_STRING_LEN); + + /* Allocate the string */ + if(NULL == (string = H5MM_malloc(string_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "Cannot allocate string") + + /* Copy the string */ + H5MM_memcpy(string, p, string_len); + string[string_len] = '\0'; + + *string_ptr = string; + *nbytes = sizeof(uint16_t) + string_len; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_string() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_heap + * + * Purpose: Encode data and insert into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, + const unsigned char *data, size_t data_size) +{ + size_t buf_size; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - /* Check args */ HDassert(f); - HDassert(_ref); + HDassert(nalloc); - /* Initialize the object location */ - H5O_loc_reset(&oloc); - oloc.file = f; + buf_size = H5HG_HEAP_ID_SIZE(f); + if(buf && *nalloc >= buf_size) { + H5HG_t hobjid; + uint8_t *p = (uint8_t *)buf; - /* Get address for reference */ - switch (ref_type) { - case H5R_OBJECT: - { - oloc.addr = *(const hobj_ref_t *)_ref; - break; - } + /* Write the reference information to disk (allocates space also) */ + if(H5HG_insert(f, data_size, (void *)data, &hobjid) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write reference information") - case H5R_DATASET_REGION: - { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ + /* Encode the heap information */ + H5F_addr_encode(f, &p, hobjid.addr); + UINT32ENCODE(p, hobjid.idx); + } + *nalloc = buf_size; - /* Get the heap ID for the dataset region */ - p = (const uint8_t *)_ref; - H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); - UINT32DECODE(p, hobjid.idx); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_heap() */ - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, (-1), "Unable to read dataset region information") + +/*------------------------------------------------------------------------- + * Function: H5R__decode_heap + * + * Purpose: Decode data inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, + unsigned char **data_ptr, size_t *data_size) +{ + const uint8_t *p = (const uint8_t *)buf; + H5HG_t hobjid; + size_t buf_size; + herr_t ret_value = SUCCEED; - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + FUNC_ENTER_PACKAGE - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); + HDassert(f); + HDassert(buf); + HDassert(nbytes); + HDassert(data_ptr); + + buf_size = H5HG_HEAP_ID_SIZE(f); + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the heap information */ + H5F_addr_decode(f, &p, &(hobjid.addr)); + if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + UINT32DECODE(p, hobjid.idx); - break; - } + /* Read the information from disk */ + if(NULL == (*data_ptr = (unsigned char *)H5HG_read(f, &hobjid, (void *)*data_ptr, data_size))) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read reference data") - case H5R_BADTYPE: - case H5R_MAXTYPE: - default: - HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, (-1), "internal error (unknown reference type)") - } /* end switch */ + *nbytes = buf_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__free_heap + * + * Purpose: Remove data previously inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes) +{ + H5HG_t hobjid; + const uint8_t *p = (const uint8_t *)buf; + size_t buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(buf); - /* Get name, length, etc. */ - if((ret_value = H5G_get_name_by_addr(f, &oloc, name, size)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't determine name") + buf_size = H5HG_HEAP_ID_SIZE(f); + /* Don't decode if buffer size isn't big enough */ + if(nbytes < buf_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + /* Get the heap information */ + H5F_addr_decode(f, &p, &(hobjid.addr)); + if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + UINT32DECODE(p, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) { + /* Free heap object */ + if(H5HG_remove(f, &hobjid) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__get_name() */ +} /* end H5R__free_heap() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_token_compat + * + * Purpose: Decode an object token. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_token_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type, + const unsigned char *buf, H5VL_token_t *obj_token) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + void *vol_obj_file = NULL; + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Get the file for the object */ + if((file_id = H5F_get_file_id(id, type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL object */ + if(NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if(H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + + if(ref_type == H5R_OBJECT1) { + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + /* Get object address */ + if(H5R__decode_token_obj_compat(buf, &buf_size, obj_token, cont_info.token_size) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object token") + } else { + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + H5F_t *f = NULL; + + /* Retrieve file from VOL object */ + if(NULL == (f = (H5F_t *)H5VL_object_data(vol_obj_file))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") + + /* Get object address */ + if(H5R__decode_token_region_compat(f, buf, &buf_size, obj_token, cont_info.token_size, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + } + +done: + if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_token_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_token_obj_compat + * + * Purpose: Encode an object token. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_token_obj_compat(const H5VL_token_t *obj_token, size_t token_size, + unsigned char *buf, size_t *nalloc) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE_NOERR + + HDassert(obj_token); + HDassert(token_size); + HDassert(nalloc); + + /* Don't encode if buffer size isn't big enough or buffer is empty */ + if(buf && *nalloc >= token_size) + H5MM_memcpy(buf, obj_token, token_size); + + *nalloc = token_size; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__encode_token_obj_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_token_obj_compat + * + * Purpose: Decode an object token. (native only) + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, + H5VL_token_t *obj_token, size_t token_size) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(buf); + HDassert(nbytes); + HDassert(obj_token); + HDassert(token_size); + + /* Don't decode if buffer size isn't big enough */ + if(*nbytes < token_size) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") + + H5MM_memcpy(obj_token, buf, token_size); + + *nbytes = token_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__decode_token_obj_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__encode_token_region_compat + * + * Purpose: Encode dataset selection and insert data into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__encode_token_region_compat(H5F_t *f, const H5VL_token_t *obj_token, + size_t token_size, H5S_t *space, unsigned char *buf, size_t *nalloc) +{ + size_t buf_size; + unsigned char *data = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(obj_token); + HDassert(token_size); + HDassert(space); + HDassert(nalloc); + + /* Get required buffer size */ + if(H5R__encode_heap(f, NULL, &buf_size, NULL, (size_t)0) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + if(buf && *nalloc >= buf_size) { + ssize_t data_size; + uint8_t *p; + + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper encode */ + H5CX_set_libver_bounds(f); + + /* Zero the heap ID out, may leak heap space if user is re-using + * reference and doesn't have garbage collection turned on + */ + HDmemset(buf, 0, buf_size); + + /* Get the amount of space required to serialize the selection */ + if((data_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") + + /* Increase buffer size to allow for the dataset token */ + data_size += (hssize_t)token_size; + + /* Allocate the space to store the serialized information */ + H5_CHECK_OVERFLOW(data_size, hssize_t, size_t); + if(NULL == (data = (uint8_t *)H5MM_malloc((size_t)data_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Serialize information for dataset OID into heap buffer */ + p = (uint8_t *)data; + H5MM_memcpy(p, obj_token, token_size); + p += token_size; + + /* Serialize the selection into heap buffer */ + if(H5S_SELECT_SERIALIZE(space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + + /* Write to heap */ + if(H5R__encode_heap(f, buf, nalloc, data, (size_t)data_size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + } + *nalloc = buf_size; + +done: + H5MM_free(data); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__encode_token_region_compat() */ + + +/*------------------------------------------------------------------------- + * Function: H5R__decode_token_region_compat + * + * Purpose: Decode dataset selection from data inserted into heap (native only). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, + size_t *nbytes, H5VL_token_t *obj_token, size_t token_size, + H5S_t **space_ptr) +{ + unsigned char *data = NULL; + H5VL_token_t token = { 0 }; + size_t data_size; + const uint8_t *p; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(f); + HDassert(buf); + HDassert(nbytes); + HDassert(token_size); + + /* Read from heap */ + if(H5R__decode_heap(f, buf, nbytes, &data, &data_size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get object address */ + p = (const uint8_t *)data; + H5MM_memcpy(token, p, token_size); + p += token_size; + + if(space_ptr) { + H5O_loc_t oloc; /* Object location */ + H5S_t *space = NULL; + const uint8_t *q = token; + + /* Initialize the object location */ + H5O_loc_reset(&oloc); + oloc.file = f; + H5F_addr_decode(f, &q, &oloc.addr); + + /* Open and copy the dataset's dataspace */ + if(NULL == (space = H5S_read(&oloc))) + HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "not found") + + /* Unserialize the selection */ + if(H5S_SELECT_DESERIALIZE(&space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection") + + *space_ptr = space; + } + if(obj_token) + H5MM_memcpy(obj_token, token, token_size); + +done: + H5MM_free(data); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_token_region_compat() */ diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 1c1c8eb..19f3115 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -36,11 +36,51 @@ /* Package Private Macros */ /**************************/ +/* Encode flags */ +#define H5R_IS_EXTERNAL 0x1 /* Set when encoding reference to external file */ + +/* Macros for convenience */ +#define H5R_REF_FILENAME(x) ((x)->ref.obj.filename) +#define H5R_REF_ATTRNAME(x) ((x)->ref.attr.name) + +/* Header size */ +#define H5R_ENCODE_HEADER_SIZE (2 * H5_SIZEOF_UINT8_T) /****************************/ /* Package Private Typedefs */ /****************************/ +/* Object reference */ +typedef struct H5R_ref_priv_obj_t { + H5VL_token_t token; /* Object token */ + char *filename; /* File name */ +} H5R_ref_priv_obj_t; + +/* Region reference */ +typedef struct H5R_ref_priv_reg_t { + H5R_ref_priv_obj_t obj; /* Object reference */ + H5S_t *space; /* Selection */ +} H5R_ref_priv_reg_t; + +/* Attribute reference */ +typedef struct H5R_ref_priv_attr_t { + H5R_ref_priv_obj_t obj; /* Object reference */ + char *name; /* Attribute name */ +} H5R_ref_priv_attr_t; + +/* Generic reference type (keep it cache aligned) */ +typedef struct H5R_ref_priv_t { + union { + H5R_ref_priv_obj_t obj;/* Object reference */ + H5R_ref_priv_reg_t reg;/* Region reference */ + H5R_ref_priv_attr_t attr;/* Attribute Reference */ + } ref; + hid_t loc_id; /* Cached location identifier */ + uint32_t encode_size; /* Cached encoding size */ + int8_t type; /* Reference type */ + uint8_t token_size; /* Cached token size */ + char unused[18]; /* Unused */ +} H5R_ref_priv_t; /*****************************/ /* Package Private Variables */ @@ -50,11 +90,41 @@ /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5R__create(void *ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space); -H5_DLL hid_t H5R__dereference(H5F_t *file, hid_t dapl_id, H5R_type_t ref_type, const void *_ref); -H5_DLL H5S_t *H5R__get_region(H5F_t *file, const void *_ref); -H5_DLL herr_t H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type); -H5_DLL ssize_t H5R__get_name(H5F_t *file, H5R_type_t ref_type, const void *_ref, char *name, size_t size); +H5_DLL herr_t H5R__create_object(const H5VL_token_t *obj_token, size_t token_size, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_region(const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size, const char *attr_name, H5R_ref_priv_t *ref); +H5_DLL herr_t H5R__destroy(H5R_ref_priv_t *ref); + +H5_DLL herr_t H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref); +H5_DLL hid_t H5R__get_loc_id(const H5R_ref_priv_t *ref); +H5_DLL hid_t H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id); + +H5_DLL H5R_type_t H5R__get_type(const H5R_ref_priv_t *ref); +H5_DLL htri_t H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2); +H5_DLL herr_t H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref); + +H5_DLL herr_t H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token, size_t *token_size); +H5_DLL herr_t H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token, size_t token_size); +H5_DLL herr_t H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space); + +H5_DLL ssize_t H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size); +H5_DLL ssize_t H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size); + +H5_DLL herr_t H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf, size_t *nalloc, unsigned flags); +H5_DLL herr_t H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref); + +/* Native HDF5 specific routines */ +H5_DLL herr_t H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, const unsigned char *data, size_t data_size); +H5_DLL herr_t H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, unsigned char **data_ptr, size_t *data_size); +H5_DLL herr_t H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes); + +H5_DLL herr_t H5R__decode_token_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type, const unsigned char *buf, H5VL_token_t *obj_token); + +H5_DLL herr_t H5R__encode_token_obj_compat(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, size_t token_size); + +H5_DLL herr_t H5R__encode_token_region_compat(H5F_t *f, const H5VL_token_t *obj_token, size_t token_size, H5S_t *space, unsigned char *buf, size_t *nalloc); +H5_DLL herr_t H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, size_t token_size, H5S_t **space_ptr); #endif /* _H5Rpkg_H */ diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h index 1bf2e92..6afec47 100644 --- a/src/H5Rprivate.h +++ b/src/H5Rprivate.h @@ -25,6 +25,8 @@ /* Library Private Macros */ /**************************/ +#define H5R_ENCODE_VERSION 0x1 /* Version for encoding references */ + /****************************/ /* Library Private Typedefs */ @@ -41,4 +43,3 @@ /******************************/ #endif /* _H5Rprivate_H */ - diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 598bafd..ce54ac4 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -26,47 +26,64 @@ /* Public Macros */ /*****************/ -/* Note! Be careful with the sizes of the references because they should really - * depend on the run-time values in the file. Unfortunately, the arrays need - * to be defined at compile-time, so we have to go with the worst case sizes - * for them. -QAK - */ +/* Deprecated reference buffer sizes that are kept for backward compatibility */ #define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) +#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) -/* 4 is used instead of sizeof(int) to permit portability between the Crays - * and other machines (the heap ID is always encoded as an int32 anyway). +/* Default reference buffer size. + * Note! Be careful with the sizes of the references because they should really + * depend on the run-time values in the file. */ -#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) +#define H5R_REF_BUF_SIZE (64) /*******************/ /* Public Typedefs */ /*******************/ -/* Reference types */ -typedef enum H5R_type_t { - H5R_BADTYPE = (-1), /* Invalid Reference Type */ - H5R_OBJECT, /* Object reference */ - H5R_DATASET_REGION, /* Dataset Region Reference */ - H5R_MAXTYPE /* Highest type (Invalid as true type) */ +/* + * Reference types allowed. + * DO NOT CHANGE THE ORDER or VALUES as reference type values are encoded into + * the datatype message header. + */ +typedef enum { + H5R_BADTYPE = (-1), /* Invalid reference type */ + H5R_OBJECT1 = 0, /* Backward compatibility (object) */ + H5R_DATASET_REGION1 = 1, /* Backward compatibility (region) */ + H5R_OBJECT2 = 2, /* Object reference */ + H5R_DATASET_REGION2 = 3, /* Region reference */ + H5R_ATTR = 4, /* Attribute Reference */ + H5R_MAXTYPE = 5 /* Highest type (invalid) */ } H5R_type_t; -/* Object reference structure for user's code - * This needs to be large enough to store largest haddr_t on a worst case - * machine (8 bytes currently). +/* Deprecated types are kept for backward compatibility with previous versions */ + +/** + * Deprecated object reference type that is used with deprecated reference APIs. + * Note! This type can only be used with the "native" HDF5 VOL connector. */ typedef haddr_t hobj_ref_t; -/* Dataset Region reference structure for user's code +/** + * Dataset region reference type that is used with deprecated reference APIs. * (Buffer to store heap ID and index) * This needs to be large enough to store largest haddr_t in a worst case - * machine (8 bytes currently) plus an int + * machine (8 bytes currently) plus an int. + * Note! This type can only be used with the "native" HDF5 VOL connector. */ typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE]; +/** + * Opaque reference type. The same reference type is used for object, + * dataset region and attribute references. This is the type that + * should always be used with the current reference API. + */ +typedef unsigned char H5R_ref_t[H5R_REF_BUF_SIZE]; + /********************/ /* Public Variables */ /********************/ + /*********************/ /* Public Prototypes */ /*********************/ @@ -75,30 +92,57 @@ typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE]; extern "C" { #endif -H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, - H5R_type_t ref_type, hid_t space_id); -H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); -H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); -H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *_ref, - H5O_type_t *obj_type); -H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, - char *name /*out*/, size_t size); +/* Constructors */ +H5_DLL herr_t H5Rcreate_object(hid_t loc_id, const char *name, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, H5R_ref_t *ref_ptr); +H5_DLL herr_t H5Rdestroy(H5R_ref_t *ref_ptr); + +/* Info */ +H5_DLL H5R_type_t H5Rget_type(const H5R_ref_t *ref_ptr); +H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); +H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr); + +/* Dereference */ +H5_DLL hid_t H5Ropen_object(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_region(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); +H5_DLL hid_t H5Ropen_attr(const H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id); + +/* Get type */ +H5_DLL herr_t H5Rget_obj_type3(const H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type); + +/* Get name */ +H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); +H5_DLL ssize_t H5Rget_obj_name(const H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size); +H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); /* Symbols defined for compatibility with previous versions of the HDF5 API. * - * Use of these symbols is deprecated. + * Use of these symbols is or will be deprecated. */ -#ifndef H5_NO_DEPRECATED_SYMBOLS + +/* Macros */ + +/* Versions for compatibility */ +#define H5R_OBJECT H5R_OBJECT1 +#define H5R_DATASET_REGION H5R_DATASET_REGION1 /* Function prototypes */ -H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *_ref); +#ifndef H5_NO_DEPRECATED_SYMBOLS + +H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref); H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref); #endif /* H5_NO_DEPRECATED_SYMBOLS */ +H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); +H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type); +H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); +H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); +H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, char *name, size_t size); + #ifdef __cplusplus } #endif #endif /* _H5Rpublic_H */ - @@ -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 */ diff --git a/src/H5Smpio.c b/src/H5Smpio.c index aeec566..f605a8a 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -42,11 +42,10 @@ /* Local Macros */ /****************/ #define H5S_MPIO_INITIAL_ALLOC_COUNT 256 -#define TWO_GIG_LIMIT 2147483648 -#ifndef H5S_MAX_MPI_COUNT -#define H5S_MAX_MPI_COUNT 536870911 /* (2^29)-1 */ -#endif +/*******************/ +/* Local Variables */ +/*******************/ /******************/ /* Local Typedefs */ @@ -88,8 +87,6 @@ static herr_t H5S__release_datatype(H5S_mpio_mpitype_list_t *type_list); static herr_t H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, size_t elmt_size, const MPI_Datatype *elmt_type, MPI_Datatype *span_type, H5S_mpio_mpitype_list_t *type_list, uint64_t op_gen); -static herr_t H5S__mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, - MPI_Datatype old_type, MPI_Datatype *new_type); /*****************************/ @@ -102,40 +99,9 @@ static herr_t H5S__mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_ /*********************/ -/*******************/ -/* Local Variables */ -/*******************/ -static hsize_t bigio_count = H5S_MAX_MPI_COUNT; - /* Declare a free list to manage the H5S_mpio_mpitype_node_t struct */ H5FL_DEFINE_STATIC(H5S_mpio_mpitype_node_t); - - -/*------------------------------------------------------------------------- - * Function: H5S_mpio_set_bigio_count - * - * Purpose: Allow us to programatically change the switch point - * when we utilize derived datatypes. This is of - * particular interest for allowing nightly testing - * - * Return: The current/previous value of bigio_count. - * - * Programmer: Richard Warren, March 10, 2017 - * - *------------------------------------------------------------------------- - */ -hsize_t -H5S_mpio_set_bigio_count(hsize_t new_count) -{ - hsize_t orig_count = bigio_count; - - if((new_count > 0) && (new_count < TWO_GIG_LIMIT)) - bigio_count = new_count; - - return orig_count; -} /* end H5S_mpio_set_bigio_count() */ - /*------------------------------------------------------------------------- * Function: H5S__mpio_all_type @@ -160,6 +126,7 @@ H5S__mpio_all_type(const H5S_t *space, size_t elmt_size, hsize_t total_bytes; hssize_t snelmts; /* Total number of elmts (signed) */ hsize_t nelmts; /* Total number of elmts */ + hsize_t bigio_count; /* Transition point to create derived type */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -173,6 +140,7 @@ H5S__mpio_all_type(const H5S_t *space, size_t elmt_size, H5_CHECKED_ASSIGN(nelmts, hsize_t, snelmts, hssize_t); total_bytes = (hsize_t)elmt_size * nelmts; + bigio_count = H5_mpi_get_bigio_count(); /* Verify that the size can be expressed as a 32 bit integer */ if(bigio_count >= total_bytes) { @@ -183,7 +151,7 @@ H5S__mpio_all_type(const H5S_t *space, size_t elmt_size, } /* end if */ else { /* Create a LARGE derived datatype for this transfer */ - if(H5S__mpio_create_large_type(total_bytes, 0, MPI_BYTE, new_type) < 0) + if(H5_mpio_create_large_type(total_bytes, 0, MPI_BYTE, new_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large datatype from the all selection") *count = 1; *is_derived_type = TRUE; @@ -250,6 +218,7 @@ H5S__mpio_create_point_datatype(size_t elmt_size, hsize_t num_points, int *blocks = NULL; /* Array of block sizes for MPI hindexed create call */ hsize_t u; /* Local index variable */ #endif + hsize_t bigio_count; /* Transition point to create derived type */ int mpi_code; /* MPI error code */ herr_t ret_value = SUCCEED; /* Return value */ @@ -260,6 +229,8 @@ H5S__mpio_create_point_datatype(size_t elmt_size, hsize_t num_points, HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) elmt_type_created = TRUE; + bigio_count = H5_mpi_get_bigio_count(); + /* Check whether standard or BIGIO processing will be employeed */ if(bigio_count >= num_points) { #if MPI_VERSION >= 3 @@ -518,7 +489,7 @@ done: * selection and so the memory datatype has to be permuted using the * permutation map created by the file selection. * - * Note: This routine is called from H5S_mpio_space_type(), which is + * Note: This routine is called from H5_mpio_space_type(), which is * called first for the file dataspace and creates * * Return: Non-negative on success, negative on failure. @@ -678,6 +649,7 @@ H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, hsize_t count; } d[H5S_MAX_RANK]; + hsize_t bigio_count; /* Transition point to create derived type */ hsize_t offset[H5S_MAX_RANK]; hsize_t max_xtent[H5S_MAX_RANK]; H5S_hyper_dim_t *diminfo; /* [rank] */ @@ -696,6 +668,7 @@ H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, HDassert(space); HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size)); + bigio_count = H5_mpi_get_bigio_count(); /* Initialize selection iterator */ if(H5S_select_iter_init(&sel_iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") @@ -824,7 +797,7 @@ if(H5DEBUG(S)) { } /* end if */ else /* Create the compound datatype for this operation (> 2GB) */ - if(H5S__mpio_create_large_type(elmt_size, 0, MPI_BYTE, &inner_type) < 0) + if(H5_mpio_create_large_type(elmt_size, 0, MPI_BYTE, &inner_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large inner datatype in hyper selection") /******************************************************* @@ -878,7 +851,7 @@ if(H5DEBUG(S)) * Again we need to check that the number of BLOCKS can fit into * a 32 bit integer */ if(bigio_count < d[i].block) { - if(H5S__mpio_create_large_type(d[i].block, 0, inner_type, &block_type) < 0) + if(H5_mpio_create_large_type(d[i].block, 0, inner_type, &block_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large block datatype in hyper selection") } /* end if */ else @@ -899,7 +872,7 @@ if(H5DEBUG(S)) * we call the large type creation function to handle that */ if(bigio_count < d[i].count) { - if(H5S__mpio_create_large_type(d[i].count, stride_in_bytes, block_type, &outer_type) < 0) + if(H5_mpio_create_large_type(d[i].count, stride_in_bytes, block_type, &outer_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large outer datatype in hyper selection") } /* end if */ /* otherwise a regular create_hvector will do */ @@ -1001,6 +974,7 @@ H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype elmt_type; /* MPI datatype for an element */ hbool_t elmt_type_is_derived = FALSE; /* Whether the element type has been created */ MPI_Datatype span_type; /* MPI datatype for overall span tree */ + hsize_t bigio_count; /* Transition point to create derived type */ hsize_t down[H5S_MAX_RANK]; /* 'down' sizes for each dimension */ uint64_t op_gen; /* Operation generation value */ int mpi_code; /* MPI return code */ @@ -1014,13 +988,14 @@ H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, HDassert(space->select.sel_info.hslab->span_lst); HDassert(space->select.sel_info.hslab->span_lst->head); + bigio_count = H5_mpi_get_bigio_count(); /* Create the base type for an element */ if(bigio_count >= elmt_size) { if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) } /* end if */ else - if(H5S__mpio_create_large_type(elmt_size, 0, MPI_BYTE, &elmt_type) < 0) + if(H5_mpio_create_large_type(elmt_size, 0, MPI_BYTE, &elmt_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large element datatype in span_hyper selection") elmt_type_is_derived = TRUE; @@ -1124,8 +1099,10 @@ H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, H5S_mpio_mpitype_list_t *type_list, uint64_t op_gen) { H5S_hyper_span_t *span; /* Hyperslab span to iterate with */ + hsize_t bigio_count; /* Transition point to create derived type */ + size_t alloc_count = 0; /* Number of span tree nodes allocated at this level */ - size_t outercount; /* Number of span tree nodes at this level */ + size_t outercount = 0; /* Number of span tree nodes at this level */ MPI_Datatype *inner_type = NULL; hbool_t inner_types_freed = FALSE; /* Whether the inner_type MPI datatypes have been freed */ int *blocklen = NULL; @@ -1140,6 +1117,7 @@ H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, HDassert(spans); HDassert(type_list); + bigio_count = H5_mpi_get_bigio_count(); /* Check if we've visited this span tree before */ if(spans->op_gen != op_gen) { H5S_mpio_mpitype_node_t *type_node; /* Pointer to new node in MPI data type list */ @@ -1185,7 +1163,7 @@ H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, H5_CHECK_OVERFLOW(nelmts, hsize_t, int) blocklen[outercount] = (int)nelmts; - if(bigio_count < blocklen[outercount]) + if(bigio_count < (hsize_t)blocklen[outercount]) large_block = TRUE; /* at least one block type is large, so set this flag to true */ span = span->next; @@ -1202,8 +1180,8 @@ H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, MPI_Datatype temp_type = MPI_DATATYPE_NULL; /* create the block type from elmt_type while checking the 32 bit int limit */ - if(blocklen[u] > bigio_count) { - if(H5S__mpio_create_large_type(blocklen[u], 0, *elmt_type, &temp_type) < 0) + if((hsize_t)(blocklen[u]) > bigio_count) { + if(H5_mpio_create_large_type(blocklen[u], 0, *elmt_type, &temp_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large element datatype in span_hyper selection") } /* end if */ else @@ -1453,113 +1431,5 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_mpio_space_type() */ - -/*------------------------------------------------------------------------- - * Function: H5S__mpio_create_large_type - * - * Purpose: Create a large datatype of size larger than what a 32 bit integer - * can hold. - * - * Return: Non-negative on success, negative on failure. - * - * *new_type the new datatype created - * - * Programmer: Mohamad Chaarawi - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, - MPI_Datatype old_type, MPI_Datatype *new_type) -{ - int num_big_types; /* num times the 2G datatype will be repeated */ - int remaining_bytes; /* the number of bytes left that can be held in an int value */ - hsize_t leftover; - int block_len[2]; - int mpi_code; /* MPI return code */ - MPI_Datatype inner_type, outer_type, leftover_type, type[2]; - MPI_Aint disp[2], old_extent; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Calculate how many Big MPI datatypes are needed to represent the buffer */ - num_big_types = (int)(num_elements/bigio_count); - leftover = num_elements - num_big_types * (hsize_t)bigio_count; - H5_CHECKED_ASSIGN(remaining_bytes, int, leftover, hsize_t); - - /* Create a contiguous datatype of size equal to the largest - * number that a 32 bit integer can hold x size of old type. - * If the displacement is 0, then the type is contiguous, otherwise - * use type_hvector to create the type with the displacement provided - */ - if (0 == stride_bytes) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(bigio_count, old_type, &inner_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } /* end if */ - else - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(bigio_count, 1, stride_bytes, old_type, &inner_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - - /* Create a contiguous datatype of the buffer (minus the remaining < 2GB part) - * If a stride is present, use hvector type - */ - if(0 == stride_bytes) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(num_big_types, inner_type, &outer_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } /* end if */ - else - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(num_big_types, 1, stride_bytes, inner_type, &outer_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - - MPI_Type_free(&inner_type); - - /* If there is a remaining part create a contiguous/vector datatype and then - * use a struct datatype to encapsulate everything. - */ - if(remaining_bytes) { - if(stride_bytes == 0) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(remaining_bytes, old_type, &leftover_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } /* end if */ - else - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)(num_elements - (hsize_t)num_big_types * bigio_count), 1, stride_bytes, old_type, &leftover_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - - /* As of version 4.0, OpenMPI now turns off MPI-1 API calls by default, - * so we're using the MPI-2 version even though we don't need the lb - * value. - */ - { - MPI_Aint unused_lb_arg; - MPI_Type_get_extent(old_type, &unused_lb_arg, &old_extent); - } - - /* Set up the arguments for MPI_Type_struct constructor */ - type[0] = outer_type; - type[1] = leftover_type; - block_len[0] = 1; - block_len[1] = 1; - disp[0] = 0; - disp[1] = (old_extent + stride_bytes) * num_big_types * (MPI_Aint)bigio_count; - - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(2, block_len, disp, type, new_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - - MPI_Type_free(&outer_type); - MPI_Type_free(&leftover_type); - } /* end if */ - else - /* There are no remaining bytes so just set the new type to - * the outer type created */ - *new_type = outer_type; - - if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__mpio_create_large_type() */ - #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 0a9d2e7..3d68de0 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -307,7 +307,6 @@ H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter); H5_DLL herr_t H5S_sel_iter_close(H5S_sel_iter_t *sel_iter); #ifdef H5_HAVE_PARALLEL -H5_DLL hsize_t H5S_mpio_set_bigio_count(hsize_t new_count); H5_DLL herr_t H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, /* out: */ MPI_Datatype *new_type, int *count, @@ -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 @@ -1029,7 +1060,11 @@ H5T__init_package(void) status |= H5T__register_int(H5T_PERS_SOFT, "enum_f", enum_type, floatpt, H5T__conv_enum_numeric); 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, "objref", objref, objref, H5T__conv_noop); + 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; @@ -2883,6 +2919,56 @@ done: /*------------------------------------------------------------------------- + * Function: H5Treclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. The dataset transfer property list is required to find the + * correct allocation/free methods for the VL data in the buffer. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Thursday, June 10, 1999 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Treclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf) +{ + H5S_t *space; /* Dataspace for iteration */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iii*x", type_id, space_id, dxpl_id, buf); + + /* Check args */ + if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + + /* Call internal routine */ + ret_value = H5T_reclaim(type_id, space, buf); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Treclaim() */ + + +/*------------------------------------------------------------------------- * Function: H5Tencode * * Purpose: Given an datatype ID, converts the object description into @@ -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; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 48c3282..84642f4 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -30,7 +30,6 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5HGprivate.h" /* Global Heaps */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ @@ -1019,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 @@ -3020,17 +3022,16 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, hbool_t noop_conv = FALSE; /* Flag to indicate a noop conversion */ hbool_t write_to_file = FALSE; /* Flag to indicate writing to file */ htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatyp */ + size_t bg_seq_len = 0; /* The number of elements in the background sequence */ hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */ H5T_t *src = NULL; /*source datatype */ H5T_t *dst = NULL; /*destination datatype */ - H5HG_t bg_hobjid, parent_hobjid; uint8_t *s = NULL; /*source buffer */ uint8_t *d = NULL; /*destination buffer */ uint8_t *b = NULL; /*background buffer */ ssize_t s_stride, d_stride; /*src and dst strides */ ssize_t b_stride; /*bkg stride */ size_t safe; /*how many elements are safe to process in each pass */ - size_t bg_seq_len = 0; size_t src_base_size, dst_base_size;/*source & destination base size*/ void *conv_buf = NULL; /*temporary conversion buffer */ size_t conv_buf_size = 0; /*size of conversion buffer in bytes */ @@ -3055,13 +3056,13 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_VLEN != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") - if(H5T_VLEN != dst->shared->type) + if(H5T_VLEN != dst->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") if(H5T_VLEN_STRING == src->shared->u.vlen.type && H5T_VLEN_STRING == dst->shared->u.vlen.type) { if((H5T_CSET_ASCII == src->shared->u.vlen.cset && H5T_CSET_UTF8 == dst->shared->u.vlen.cset) - || (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) + || (H5T_CSET_ASCII == dst->shared->u.vlen.cset && H5T_CSET_UTF8 == src->shared->u.vlen.cset)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "The library doesn't convert between strings of ASCII and UTF") - } + } /* end if */ /* Variable-length types don't need a background buffer */ cdata->need_bkg = H5T_BKG_NO; @@ -3179,25 +3180,27 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end else */ for(elmtno = 0; elmtno < safe; elmtno++) { + hbool_t is_nil; /* Whether sequence is "nil" */ + /* Check for "nil" source sequence */ - if((*(src->shared->u.vlen.isnull))(src->shared->u.vlen.f, s)) { + if((*(src->shared->u.vlen.cls->isnull))(src->shared->u.vlen.f, s, &is_nil) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check if VL data is 'nil'") + else if(is_nil) { /* Write "nil" sequence to destination location */ - if((*(dst->shared->u.vlen.setnull))(dst->shared->u.vlen.f, d, b) < 0) + if((*(dst->shared->u.vlen.cls->setnull))(dst->shared->u.vlen.f, d, b) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't set VL data to 'nil'") - } /* end if */ + } /* end else-if */ else { - ssize_t sseq_len; /* (signed) The number of elements in the current sequence*/ - size_t seq_len; /* The number of elements in the current sequence*/ + size_t seq_len; /* The number of elements in the current sequence */ /* Get length of element sequences */ - if((sseq_len = (*(src->shared->u.vlen.getlen))(s)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length") - seq_len = (size_t)sseq_len; + if((*(src->shared->u.vlen.cls->getlen))(src->shared->u.vlen.f, s, &seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length") /* If we are reading from memory and there is no conversion, just get the pointer to sequence */ if(write_to_file && noop_conv) { /* Get direct pointer to sequence */ - if(NULL == (conv_buf = (*(src->shared->u.vlen.getptr))(s))) + if(NULL == (conv_buf = (*(src->shared->u.vlen.cls->getptr))(s))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer") } /* end if */ else { @@ -3213,17 +3216,17 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, conv_buf_size = ((1 / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * H5T_VLEN_MIN_CONF_BUF_SIZE; if(NULL == (conv_buf = H5FL_BLK_CALLOC(vlen_seq, conv_buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") - } + } /* end if */ else if(conv_buf_size < MAX(src_size, dst_size)) { /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */ conv_buf_size = ((MAX(src_size, dst_size) / H5T_VLEN_MIN_CONF_BUF_SIZE) + 1) * H5T_VLEN_MIN_CONF_BUF_SIZE; if(NULL == (conv_buf = H5FL_BLK_REALLOC(vlen_seq, conv_buf, conv_buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") HDmemset(conv_buf, 0, conv_buf_size); - } /* end if */ + } /* end else-if */ /* Read in VL sequence */ - if((*(src->shared->u.vlen.read))(src->shared->u.vlen.f, s, conv_buf, src_size) < 0) + if((*(src->shared->u.vlen.cls->read))(src->shared->u.vlen.f, s, conv_buf, src_size) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data") } /* end else */ @@ -3241,9 +3244,14 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* If we are writing and there is a nested VL type, read * the sequence into the background buffer */ if(nested) { - const uint8_t *tmp = b; + /* Sanity check */ + HDassert(write_to_file); + + /* Get length of background element sequence */ + if((*(dst->shared->u.vlen.cls->getlen))(dst->shared->u.vlen.f, b, &bg_seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "bad sequence length") - UINT32DECODE(tmp, bg_seq_len); + /* Read sequence if length > 0 */ if(bg_seq_len > 0) { if(tmp_buf_size < (bg_seq_len * MAX(src_base_size, dst_base_size))) { tmp_buf_size = (bg_seq_len * MAX(src_base_size, dst_base_size)); @@ -3251,10 +3259,10 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") HDmemset(tmp_buf, 0, tmp_buf_size); } /* end if */ - H5F_addr_decode(dst->shared->u.vlen.f, &tmp, &(bg_hobjid.addr)); - UINT32DECODE(tmp, bg_hobjid.idx); - if(NULL == H5HG_read(dst->shared->u.vlen.f, &bg_hobjid, tmp_buf, NULL)) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL sequence into background buffer") + + /* Read in background VL sequence */ + if((*(dst->shared->u.vlen.cls->read))(dst->shared->u.vlen.f, b, tmp_buf, bg_seq_len) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data") } /* end if */ /* If the sequence gets shorter, pad out the original sequence with zeros */ @@ -3268,26 +3276,23 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end if */ /* Write sequence to destination location */ - if((*(dst->shared->u.vlen.write))(dst->shared->u.vlen.f, &vl_alloc_info, d, conv_buf, b, seq_len, dst_base_size) < 0) + if((*(dst->shared->u.vlen.cls->write))(dst->shared->u.vlen.f, &vl_alloc_info, d, conv_buf, b, seq_len, dst_base_size) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data") if(!noop_conv) { /* For nested VL case, free leftover heap objects from the deeper level if the length of new data elements is shorter than the old data elements.*/ if(nested && seq_len < bg_seq_len) { - size_t parent_seq_len; const uint8_t *tmp; size_t u; - /* TMP_P is reset each time in the loop because DST_BASE_SIZE may include some data in addition to VL info. - SLU */ - for(u = seq_len; u < bg_seq_len; u++) { - tmp = (uint8_t *)tmp_buf + u * dst_base_size; - UINT32DECODE(tmp, parent_seq_len); - if(parent_seq_len > 0) { - H5F_addr_decode(dst->shared->u.vlen.f, &tmp, &(parent_hobjid.addr)); - UINT32DECODE(tmp, parent_hobjid.idx); - if(H5HG_remove(dst->shared->u.vlen.f, &parent_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } /* end if */ + /* Sanity check */ + HDassert(write_to_file); + + tmp = (uint8_t *)tmp_buf + seq_len * dst_base_size; + for(u = seq_len; u < bg_seq_len; u++, tmp += dst_base_size) { + /* Delete sequence in destination location */ + if((*(dst->shared->u.vlen.cls->del))(dst->shared->u.vlen.f, tmp) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove heap object") } /* end for */ } /* end if */ } /* end if */ @@ -3474,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 @@ -9305,3 +9499,84 @@ H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) FUNC_LEAVE_NOAPI(SUCCEED) } + +/*------------------------------------------------------------------------- + * Function: H5T_reclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_reclaim(hid_t type_id, H5S_t *space, void *buf) +{ + H5T_t *type; /* Datatype */ + H5S_sel_iter_op_t dset_op; /* Operator for iteration */ + H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ + herr_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(space); + HDassert(buf); + + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype") + + /* Get the allocation info */ + if(H5CX_get_vlen_alloc_info(&vl_alloc_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info") + + /* Call H5S_select_iterate with args, etc. */ + dset_op.op_type = H5S_SEL_ITER_OP_LIB; + dset_op.u.lib_op = H5T_reclaim_cb; + + ret_value = H5S_select_iterate(buf, type, space, &dset_op, &vl_alloc_info); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_reclaim() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_reclaim_cb + * + * Purpose: Iteration callback to reclaim conversion allocated memory for a + * buffer element. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned H5_ATTR_UNUSED ndim, + const hsize_t H5_ATTR_UNUSED *point, void *op_data) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(elem); + HDassert(dt); + + if(dt->shared->type == H5T_REFERENCE) { + if(H5T_ref_reclaim(elem, dt) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim ref elements") + } else { + HDassert(op_data); + + /* Allow vlen reclaim to recurse into that routine */ + if(H5T_vlen_reclaim(elem, dt, (H5T_vlen_alloc_info_t *)op_data) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "can't reclaim vlen elements") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_reclaim_cb() */ diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 6daa544..1d203c7 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -126,7 +126,6 @@ static H5T_t * H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { - H5T_t *dt; /* Datatype to make native */ H5T_t *super_type; /* Super type of VL, array and enum datatypes */ H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ H5T_t *new_type = NULL; /* New native datatype */ @@ -218,26 +217,36 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali case H5T_REFERENCE: { + H5T_t *dt; /* Datatype to make native */ size_t align; size_t ref_size; - int not_equal; if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy reference type") - /* Decide if the data type is object or dataset region reference. */ + /* Decide if the data type is object reference. */ if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") - not_equal = H5T_cmp(ret_value, dt, FALSE); /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { + if(0 == H5T_cmp(ret_value, dt, FALSE)) { align = H5T_HOBJREF_COMP_ALIGN_g; ref_size = sizeof(hobj_ref_t); } /* end if */ else { - align = H5T_HDSETREGREF_COMP_ALIGN_g; - ref_size = sizeof(hdset_reg_ref_t); + /* Decide if the data type is dataset region reference. */ + if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_DSETREG_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") + + if (0 == H5T_cmp(ret_value, dt, FALSE)) { + align = H5T_HDSETREGREF_COMP_ALIGN_g; + ref_size = sizeof(hdset_reg_ref_t); + } /* end if */ + else { + /* Only pointers to underlying opaque reference types */ + align = H5T_REF_COMP_ALIGN_g; + ref_size = sizeof(H5R_ref_t); + } /* end else */ } /* end else */ if(H5T__cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align) < 0) diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 7798e37..9784abd 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -95,9 +95,14 @@ /* This version also encodes array types more efficiently */ #define H5O_DTYPE_VERSION_3 3 +/* This is the version that adds support for new reference types and prevents + * older versions of the library to attempt reading unknown types. + */ +#define H5O_DTYPE_VERSION_4 4 + /* The latest version of the format. Look through the 'encode helper' routine * and 'size' callback for places to change when updating this. */ -#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_3 +#define H5O_DTYPE_VERSION_LATEST H5O_DTYPE_VERSION_4 /* Flags for visiting datatype */ @@ -175,37 +180,52 @@ struct H5T_path_t { H5T_cdata_t cdata; /*data for this function */ }; +/* Reference function pointers */ +typedef size_t (*H5T_ref_getsizefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, hbool_t *dst_copy); +typedef herr_t (*H5T_ref_readfunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5F_t *dst_f, void *dst_buf, size_t dst_size); +typedef herr_t (*H5T_ref_writefunc_t)(H5F_t *src_f, const void *src_buf, size_t src_size, H5R_type_t src_type, H5F_t *dst_f, void *dst_buf, size_t dst_size, void *bg_buf); + +typedef struct H5T_ref_class_t { + H5T_ref_getsizefunc_t getsize; /* get reference size (bytes) */ + H5T_ref_readfunc_t read; /* read reference into buffer */ + H5T_ref_writefunc_t write; /* write reference from buffer */ +} H5T_ref_class_t; + typedef struct H5T_atomic_t { - H5T_order_t order; /*byte order */ - size_t prec; /*precision in bits */ - size_t offset; /*bit position of lsb of value */ - H5T_pad_t lsb_pad;/*type of lsb padding */ - H5T_pad_t msb_pad;/*type of msb padding */ + H5T_order_t order; /* byte order */ + size_t prec; /* precision in bits */ + size_t offset; /* bit position of lsb of value */ + H5T_pad_t lsb_pad; /* type of lsb padding */ + H5T_pad_t msb_pad; /* type of msb padding */ union { - struct { - H5T_sign_t sign; /*type of integer sign */ - } i; /*integer; integer types */ - - struct { - size_t sign; /*bit position of sign bit */ - size_t epos; /*position of lsb of exponent */ - size_t esize; /*size of exponent in bits */ - uint64_t ebias; /*exponent bias */ - size_t mpos; /*position of lsb of mantissa */ - size_t msize; /*size of mantissa */ - H5T_norm_t norm; /*normalization */ - H5T_pad_t pad; /*type of padding for internal bits */ - } f; /*floating-point types */ - - struct { - H5T_cset_t cset; /*character set */ - H5T_str_t pad; /*space or null padding of extra bytes */ - } s; /*string types */ - - struct { - H5R_type_t rtype; /*type of reference stored */ - H5T_loc_t loc; /* Location of data in buffer */ - } r; /*reference types */ + struct { + H5T_sign_t sign; /* type of integer sign */ + } i; /* integer; integer types */ + + struct { + size_t sign; /* bit position of sign bit */ + size_t epos; /* position of lsb of exponent */ + size_t esize; /* size of exponent in bits */ + uint64_t ebias; /* exponent bias */ + size_t mpos; /* position of lsb of mantissa */ + size_t msize; /* size of mantissa */ + H5T_norm_t norm; /* normalization */ + H5T_pad_t pad; /* type of padding for internal bits */ + } f; /* floating-point types */ + + struct { + H5T_cset_t cset; /* character set */ + H5T_str_t pad; /* space or null padding of extra bytes */ + } s; /* string types */ + + struct { + H5R_type_t rtype; /* type of reference stored */ + unsigned version; /* version of encoded reference */ + hbool_t opaque; /* opaque reference type */ + H5T_loc_t loc; /* location of data in buffer */ + H5F_t *f; /* file pointer (if data is on disk) */ + const H5T_ref_class_t *cls; /* Pointer to ref class callbacks */ + } r; /* reference types */ } u; } H5T_atomic_t; @@ -243,14 +263,6 @@ typedef struct H5T_enum_t { char **name; /*array of symbol names */ } H5T_enum_t; -/* VL function pointers */ -typedef ssize_t (*H5T_vlen_getlenfunc_t)(const void *vl_addr); -typedef void * (*H5T_vlen_getptrfunc_t)(void *vl_addr); -typedef htri_t (*H5T_vlen_isnullfunc_t)(const H5F_t *f, void *vl_addr); -typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, void *_vl, void *buf, size_t len); -typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size); -typedef herr_t (*H5T_vlen_setnullfunc_t)(H5F_t *f, void *_vl, void *_bg); - /* VL types */ typedef enum { H5T_VLEN_BADTYPE = -1, /* invalid VL Type */ @@ -259,20 +271,35 @@ typedef enum { H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */ } H5T_vlen_type_t; +/* VL function pointers */ +typedef herr_t (*H5T_vlen_getlen_func_t)(H5F_t *f, const void *vl_addr, size_t *len); +typedef void * (*H5T_vlen_getptr_func_t)(void *vl_addr); +typedef herr_t (*H5T_vlen_isnull_func_t)(const H5F_t *f, void *vl_addr, hbool_t *isnull); +typedef herr_t (*H5T_vlen_setnull_func_t)(H5F_t *f, void *_vl, void *_bg); +typedef herr_t (*H5T_vlen_read_func_t)(H5F_t *f, void *_vl, void *buf, size_t len); +typedef herr_t (*H5T_vlen_write_func_t)(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size); +typedef herr_t (*H5T_vlen_delete_func_t)(H5F_t *f, const void *_vl); + +/* VL datatype callbacks */ +typedef struct H5T_vlen_class_t { + H5T_vlen_getlen_func_t getlen; /* Function to get VL sequence size (in element units, not bytes) */ + H5T_vlen_getptr_func_t getptr; /* Function to get VL sequence pointer */ + H5T_vlen_isnull_func_t isnull; /* Function to check if VL value is NIL */ + H5T_vlen_setnull_func_t setnull;/* Function to set a VL value to NIL */ + H5T_vlen_read_func_t read; /* Function to read VL sequence into buffer */ + H5T_vlen_write_func_t write; /* Function to write VL sequence from buffer */ + H5T_vlen_delete_func_t del; /* Function to delete VL sequence */ +} H5T_vlen_class_t; + /* A VL datatype */ typedef struct H5T_vlen_t { H5T_vlen_type_t type; /* Type of VL data in buffer */ H5T_loc_t loc; /* Location of VL data in buffer */ - H5T_cset_t cset; /* For VL string. character set */ - H5T_str_t pad; /* For VL string. space or null padding of + H5T_cset_t cset; /* For VL string: character set */ + H5T_str_t pad; /* For VL string: space or null padding of * extra bytes */ H5F_t *f; /* File ID (if VL data is on disk) */ - H5T_vlen_getptrfunc_t getptr; /* Function to get VL sequence pointer */ - H5T_vlen_getlenfunc_t getlen; /* Function to get VL sequence size (in element units, not bytes) */ - H5T_vlen_isnullfunc_t isnull; /* Function to check if VL value is NIL */ - H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */ - H5T_vlen_writefunc_t write; /* Function to write VL sequence from buffer */ - H5T_vlen_setnullfunc_t setnull; /* Function to set a VL value to NIL */ + const H5T_vlen_class_t *cls; /* Pointer to VL class callbacks */ } H5T_vlen_t; /* An opaque datatype */ @@ -371,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 @@ -483,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); @@ -1149,6 +1180,9 @@ H5_DLL H5T_t *H5T__array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/ H5_DLL int H5T__get_array_ndims(const H5T_t *dt); H5_DLL int H5T__get_array_dims(const H5T_t *dt, hsize_t dims[]); +/* Reference functions */ +H5_DLL htri_t H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc); + /* Compound functions */ H5_DLL herr_t H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 3dcbb2c..13a0938 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -52,6 +52,9 @@ typedef struct H5T_t H5T_t; typedef struct H5T_stats_t H5T_stats_t; typedef struct H5T_path_t H5T_path_t; +/* Forward reference of H5S_t */ +struct H5S_t; + /* How to copy a datatype */ typedef enum H5T_copy_t { H5T_COPY_TRANSIENT, @@ -130,7 +133,10 @@ H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p); H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p); H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); -H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *_op_data); +H5_DLL herr_t H5T_reclaim(hid_t type_id, struct H5S_t *space, void *buf); +H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data); +H5_DLL herr_t H5T_ref_reclaim(void *elem, const H5T_t *dt); +H5_DLL herr_t H5T_vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info); H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt); H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index fc3e4ee..0ec0c73 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -262,8 +262,9 @@ H5_DLLVAR hid_t H5T_IEEE_F64LE_g; #define H5T_STD_B32LE (H5OPEN H5T_STD_B32LE_g) #define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g) #define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g) -#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) +#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) #define H5T_STD_REF_DSETREG (H5OPEN H5T_STD_REF_DSETREG_g) +#define H5T_STD_REF (H5OPEN H5T_STD_REF_g) H5_DLLVAR hid_t H5T_STD_I8BE_g; H5_DLLVAR hid_t H5T_STD_I8LE_g; H5_DLLVAR hid_t H5T_STD_I16BE_g; @@ -290,6 +291,7 @@ H5_DLLVAR hid_t H5T_STD_B64BE_g; H5_DLLVAR hid_t H5T_STD_B64LE_g; H5_DLLVAR hid_t H5T_STD_REF_OBJ_g; H5_DLLVAR hid_t H5T_STD_REF_DSETREG_g; +H5_DLLVAR hid_t H5T_STD_REF_g; /* * Types which are particular to Unix. @@ -591,6 +593,7 @@ H5_DLL H5T_conv_t H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata); H5_DLL htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id); H5_DLL herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background, hid_t plist_id); +H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Tref.c b/src/H5Tref.c new file mode 100644 index 0000000..937dc92 --- /dev/null +++ b/src/H5Tref.c @@ -0,0 +1,768 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 { + H5VL_token_t token; /* Object token */ + 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: { + size_t token_size = H5F_SIZEOF_ADDR(src_f); + + if(H5R__create_object((const H5VL_token_t *)src_buf, token_size, 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; + size_t token_size = H5F_SIZEOF_ADDR(src_f); + + if(H5R__create_region(&src_reg->token, token_size, 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 *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 = 0; + + FUNC_ENTER_STATIC_NOERR + + HDassert(src_f); + HDassert(src_buf); + HDassert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); + + ret_value = 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 *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 == H5F_SIZEOF_ADDR(src_f)); + + /* Get object address */ + if(H5R__decode_token_obj_compat((const unsigned char *)src_buf, &src_size, + dst_buf, H5F_SIZEOF_ADDR(src_f)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "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_token_region_compat(src_f, (const unsigned char *)src_buf, + &src_size, &dst_reg->token, H5F_SIZEOF_ADDR(src_f), &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_NOAPI_NOINIT + + /* Sanity checks */ + HDassert(elem); + HDassert(dt && (dt->shared->type == H5T_REFERENCE)); + + if(dt->shared->u.atomic.u.r.opaque + && (H5R__destroy((H5R_ref_priv_t *)elem) < 0)) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "cannot free reference") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_ref_reclaim() */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index bafb47f..0253b01 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -16,41 +16,119 @@ * datatypes in the H5T interface. */ -#include "H5Tmodule.h" /* This source code file is part of the H5T module */ - +/****************/ +/* Module Setup */ +/****************/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Dataset functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5HGprivate.h" /* Global Heaps */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ -#include "H5Tpkg.h" /* Datatypes */ - -/* Local functions */ -static herr_t H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info); -static ssize_t H5T_vlen_seq_mem_getlen(const void *_vl); -static void * H5T_vlen_seq_mem_getptr(void *_vl); -static htri_t H5T_vlen_seq_mem_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_seq_mem_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_seq_mem_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_seq_mem_setnull(H5F_t *f, void *_vl, void *_bg); -static ssize_t H5T_vlen_str_mem_getlen(const void *_vl); -static void * H5T_vlen_str_mem_getptr(void *_vl); -static htri_t H5T_vlen_str_mem_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_str_mem_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_str_mem_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_str_mem_setnull(H5F_t *f, void *_vl, void *_bg); -static ssize_t H5T_vlen_disk_getlen(const void *_vl); -static void * H5T_vlen_disk_getptr(void *_vl); -static htri_t H5T_vlen_disk_isnull(const H5F_t *f, void *_vl); -static herr_t H5T_vlen_disk_read(H5F_t *f, void *_vl, void *_buf, size_t len); -static herr_t H5T_vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); -static herr_t H5T_vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg); - -/* Local variables */ +#include "H5Tmodule.h" /* This source code file is part of the H5T module */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ + +/***********/ +/* Headers */ +/***********/ +#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 */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Memory-based VL sequence callbacks */ +static herr_t H5T__vlen_mem_seq_getlen(H5F_t *f, const void *_vl, size_t *len); +static void * H5T__vlen_mem_seq_getptr(void *_vl); +static herr_t H5T__vlen_mem_seq_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_mem_seq_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_mem_seq_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_mem_seq_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); + +/* Memory-based VL string callbacks */ +static herr_t H5T__vlen_mem_str_getlen(H5F_t *f, const void *_vl, size_t *len); +static void * H5T__vlen_mem_str_getptr(void *_vl); +static herr_t H5T__vlen_mem_str_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_mem_str_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_mem_str_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_mem_str_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); + +/* Disk-based VL sequence (and string) callbacks */ +static herr_t H5T__vlen_disk_getlen(H5F_t *f, const void *_vl, size_t *len); +static herr_t H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull); +static herr_t H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg); +static herr_t H5T__vlen_disk_read(H5F_t *f, void *_vl, void *_buf, size_t len); +static herr_t H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, size_t seq_len, size_t base_size); +static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl); + + +/*********************/ +/* Public Variables */ +/*********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Class for VL 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' */ + H5T__vlen_mem_seq_isnull, /* 'isnull' */ + H5T__vlen_mem_seq_setnull, /* 'setnull' */ + H5T__vlen_mem_seq_read, /* 'read' */ + H5T__vlen_mem_seq_write, /* 'write' */ + NULL /* 'delete' */ +}; + +/* Class for VL strings in memory */ +static const H5T_vlen_class_t H5T_vlen_mem_str_g = { + H5T__vlen_mem_str_getlen, /* 'getlen' */ + H5T__vlen_mem_str_getptr, /* 'getptr' */ + H5T__vlen_mem_str_isnull, /* 'isnull' */ + H5T__vlen_mem_str_setnull, /* 'setnull' */ + H5T__vlen_mem_str_read, /* 'read' */ + H5T__vlen_mem_str_write, /* 'write' */ + NULL /* 'delete' */ +}; + +/* Class for both VL strings and sequences in file */ +static const H5T_vlen_class_t H5T_vlen_disk_g = { + H5T__vlen_disk_getlen, /* 'getlen' */ + NULL, /* 'getptr' */ + H5T__vlen_disk_isnull, /* 'isnull' */ + H5T__vlen_disk_setnull, /* 'setnull' */ + H5T__vlen_disk_read, /* 'read' */ + H5T__vlen_disk_write, /* 'write' */ + H5T__vlen_disk_delete /* 'delete' */ +}; @@ -194,32 +272,21 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) dt->shared->u.vlen.loc = H5T_LOC_MEMORY; if(dt->shared->u.vlen.type == H5T_VLEN_SEQUENCE) { - /* size in memory, disk size is different */ + /* Size in memory, disk size is different */ dt->shared->size = sizeof(hvl_t); /* Set up the function pointers to access the VL sequence in memory */ - dt->shared->u.vlen.getlen = H5T_vlen_seq_mem_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_seq_mem_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_seq_mem_isnull; - dt->shared->u.vlen.read = H5T_vlen_seq_mem_read; - dt->shared->u.vlen.write = H5T_vlen_seq_mem_write; - dt->shared->u.vlen.setnull = H5T_vlen_seq_mem_setnull; - } + dt->shared->u.vlen.cls = &H5T_vlen_mem_seq_g; + } /* end if */ else if(dt->shared->u.vlen.type == H5T_VLEN_STRING) { - /* size in memory, disk size is different */ + /* Size in memory, disk size is different */ dt->shared->size = sizeof(char *); /* Set up the function pointers to access the VL string in memory */ - dt->shared->u.vlen.getlen = H5T_vlen_str_mem_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_str_mem_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_str_mem_isnull; - dt->shared->u.vlen.read = H5T_vlen_str_mem_read; - dt->shared->u.vlen.write = H5T_vlen_str_mem_write; - dt->shared->u.vlen.setnull = H5T_vlen_str_mem_setnull; - } - else { + dt->shared->u.vlen.cls = &H5T_vlen_mem_str_g; + } /* end else-if */ + else HDassert(0 && "Invalid VL type"); - } /* Reset file ID (since this VL is in memory) */ dt->shared->u.vlen.f = NULL; @@ -234,18 +301,13 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* * Size of element on disk is 4 bytes for the length, plus the size * of an address in this file, plus 4 bytes for the size of a heap - * ID. Memory size is different + * ID. Memory size is different. */ dt->shared->size = 4 + (size_t)H5F_SIZEOF_ADDR(f) + 4; /* Set up the function pointers to access the VL information on disk */ /* VL sequences and VL strings are stored identically on disk, so use the same functions */ - dt->shared->u.vlen.getlen = H5T_vlen_disk_getlen; - dt->shared->u.vlen.getptr = H5T_vlen_disk_getptr; - dt->shared->u.vlen.isnull = H5T_vlen_disk_isnull; - dt->shared->u.vlen.read = H5T_vlen_disk_read; - dt->shared->u.vlen.write = H5T_vlen_disk_write; - dt->shared->u.vlen.setnull = H5T_vlen_disk_setnull; + dt->shared->u.vlen.cls = &H5T_vlen_disk_g; /* Set file ID (since this VL is on disk) */ dt->shared->u.vlen.f = f; @@ -255,6 +317,13 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined * location for VL type and leaves it for the caller to decide. */ + dt->shared->u.vlen.loc = H5T_LOC_BADLOC; + + /* Reset the function pointers to access the VL information */ + dt->shared->u.vlen.cls = NULL; + + /* Reset file pointer */ + dt->shared->u.vlen.f = NULL; break; case H5T_LOC_MAXLOC: @@ -269,11 +338,11 @@ H5T__vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__vlen_set_loc() */ +} /* end H5T__vlen_set_loc() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_getlen + * Function: H5T__vlen_mem_seq_getlen * * Purpose: Retrieves the length of a memory based VL element. * @@ -284,33 +353,35 @@ done: * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_seq_mem_getlen(const void *_vl) +static herr_t +H5T__vlen_mem_seq_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters, return result */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(vl); + /* Check parameter */ + HDassert(_vl); + HDassert(len); - FUNC_LEAVE_NOAPI((ssize_t)vl->len) +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + *len = vl->len; #else - HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); - FUNC_LEAVE_NOAPI((ssize_t)vl.len) + *len = vl.len; #endif -} /* end H5T_vlen_seq_mem_getlen() */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_getptr + * Function: H5T__vlen_mem_seq_getptr * * Purpose: Retrieves the pointer for a memory based VL element. * @@ -322,15 +393,15 @@ H5T_vlen_seq_mem_getlen(const void *_vl) *------------------------------------------------------------------------- */ static void * -H5T_vlen_seq_mem_getptr(void *_vl) +H5T__vlen_mem_seq_getptr(void *_vl) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters, return result */ #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -343,48 +414,82 @@ H5T_vlen_seq_mem_getptr(void *_vl) FUNC_LEAVE_NOAPI(vl.p) #endif -} /* end H5T_vlen_seq_mem_getptr() */ +} /* end H5T__vlen_mem_seq_getptr() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_isnull + * Function: H5T__vlen_mem_seq_isnull * * Purpose: Checks if a memory sequence is the "null" sequence * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_seq_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) +static herr_t +H5T__vlen_mem_seq_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl, hbool_t *isnull) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters, return result */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(vl); + /* Check parameters */ + HDassert(_vl); - FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE) +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + *isnull = ((vl->len == 0 || vl->p == NULL) ? TRUE : FALSE); #else - HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); - FUNC_LEAVE_NOAPI((vl.len==0 || vl.p==NULL) ? TRUE : FALSE) + *isnull = ((vl.len == 0 || vl.p == NULL) ? TRUE : FALSE); #endif -} /* end H5T_vlen_seq_mem_isnull() */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_isnull() */ + + +/*------------------------------------------------------------------------- + * Function: H5T__vlen_mem_seq_setnull + * + * Purpose: Sets a VL info object in memory to the "nil" value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, November 8, 2003 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__vlen_mem_seq_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) +{ + hvl_t vl; /* Temporary hvl_t to use during operation */ + + FUNC_ENTER_STATIC_NOERR + + /* check parameters */ + HDassert(_vl); + + /* Set the "nil" hvl_t */ + vl.len = 0; + vl.p = NULL; + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + H5MM_memcpy(_vl, &vl, sizeof(hvl_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_seq_setnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_read + * Function: H5T__vlen_mem_seq_read * * Purpose: "Reads" the memory based VL sequence into a buffer * @@ -396,36 +501,36 @@ H5T_vlen_seq_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) +H5T__vlen_mem_seq_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const hvl_t *vl=(const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ + const hvl_t *vl = (const hvl_t *)_vl; /* Pointer to the user's hvl_t information */ #else hvl_t vl; /* User's hvl_t information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters, copy data */ HDassert(buf); #ifdef H5_NO_ALIGNMENT_RESTRICTIONS HDassert(vl && vl->p); - H5MM_memcpy(buf,vl->p,len); + H5MM_memcpy(buf, vl->p, len); #else HDassert(_vl); H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); HDassert(vl.p); - H5MM_memcpy(buf,vl.p,len); + H5MM_memcpy(buf, vl.p, len); #endif FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_seq_mem_read() */ +} /* end H5T__vlen_mem_seq_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_write + * Function: H5T__vlen_mem_seq_write * * Purpose: "Writes" the memory based VL sequence from a buffer * @@ -437,104 +542,104 @@ H5T_vlen_seq_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) +H5T__vlen_mem_seq_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) { hvl_t vl; /* Temporary hvl_t to use during operation */ - size_t len; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(_vl); HDassert(buf); - if(seq_len!=0) { - len=seq_len*base_size; + if(seq_len) { + size_t len = seq_len * base_size; /* Sequence size */ /* Use the user's memory allocation routine is one is defined */ - if(vl_alloc_info->alloc_func!=NULL) { - if(NULL==(vl.p=(vl_alloc_info->alloc_func)(len,vl_alloc_info->alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") + if(vl_alloc_info->alloc_func != NULL) { + if(NULL == (vl.p = (vl_alloc_info->alloc_func)(len, vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "application memory allocation routine failed for VL data") } /* end if */ - else { /* Default to system malloc */ + else /* Default to system malloc */ if(NULL == (vl.p = HDmalloc(len))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end else */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed for VL data") /* Copy the data into the newly allocated buffer */ - H5MM_memcpy(vl.p,buf,len); - + H5MM_memcpy(vl.p, buf, len); } /* end if */ else - vl.p=NULL; + vl.p = NULL; /* Set the sequence length */ - vl.len=seq_len; + vl.len = seq_len; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); + H5MM_memcpy(_vl, &vl, sizeof(hvl_t)); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_seq_mem_write() */ +} /* end H5T__vlen_mem_seq_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_seq_mem_setnull + * Function: H5T__vlen_mem_str_getlen * - * Purpose: Sets a VL info object in memory to the "nil" value + * Purpose: Retrieves the length of a memory based VL string. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Saturday, November 8, 2003 + * Wednesday, June 2, 1999 * *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_seq_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) +H5T__vlen_mem_str_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *len) { - hvl_t vl; /* Temporary hvl_t to use during operation */ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const char *s = *(const char * const *)_vl; /* Pointer to the user's string information */ +#else + const char *s = NULL; /* Pointer to the user's string information */ +#endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters */ HDassert(_vl); - /* Set the "nil" hvl_t */ - vl.len=0; - vl.p=NULL; +#ifndef H5_NO_ALIGNMENT_RESTRICTIONS + H5MM_memcpy(&s, _vl, sizeof(char *)); +#endif - /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); + *len = HDstrlen(s); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_seq_mem_setnull() */ +} /* end H5T__vlen_mem_str_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_getlen + * Function: H5T__vlen_mem_str_getptr * - * Purpose: Retrieves the length of a memory based VL string. + * Purpose: Retrieves the pointer for a memory based VL string. * - * Return: Non-negative on success/Negative on failure + * Return: Non-NULL on success/NULL on failure * * Programmer: Quincey Koziol - * Wednesday, June 2, 1999 + * Saturday, June 12, 2004 * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_str_mem_getlen(const void *_vl) +static void * +H5T__vlen_mem_str_getptr(void *_vl) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const char *s=*(const char * const *)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else - const char *s = NULL; /* Pointer to the user's string information */ + char *s = NULL; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* check parameters */ #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -544,78 +649,71 @@ H5T_vlen_str_mem_getlen(const void *_vl) H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(s)) -} /* end H5T_vlen_str_mem_getlen() */ + FUNC_LEAVE_NOAPI(s) +} /* end H5T__vlen_mem_str_getptr() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_getptr + * Function: H5T__vlen_mem_str_isnull * - * Purpose: Retrieves the pointer for a memory based VL string. + * Purpose: Checks if a memory string is a NULL pointer * - * Return: Non-NULL on success/NULL on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Saturday, June 12, 2004 + * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static void * -H5T_vlen_str_mem_getptr(void *_vl) +static herr_t +H5T__vlen_mem_str_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl, hbool_t *isnull) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else char *s = NULL; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* check parameters */ -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(s); -#else - HDassert(_vl); +#ifndef H5_NO_ALIGNMENT_RESTRICTIONS H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - FUNC_LEAVE_NOAPI(s) -} /* end H5T_vlen_str_mem_getptr() */ + *isnull = (s == NULL ? TRUE : FALSE); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_mem_str_isnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_isnull + * Function: H5T__vlen_mem_str_setnull * - * Purpose: Checks if a memory string is a NULL pointer + * Purpose: Sets a VL info object in memory to the "null" value * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_str_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) +static herr_t +H5T__vlen_mem_str_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) { -#ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ -#else - char *s = NULL; /* Pointer to the user's string information */ -#endif + char *t = NULL; /* Pointer to temporary buffer allocated */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR -#ifndef H5_NO_ALIGNMENT_RESTRICTIONS - H5MM_memcpy(&s, _vl, sizeof(char *)); -#endif + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + H5MM_memcpy(_vl, &t, sizeof(char *)); - FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE) -} /* end H5T_vlen_str_mem_isnull() */ + FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ +} /* end H5T__vlen_mem_str_setnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_read + * Function: H5T__vlen_mem_str_read * * Purpose: "Reads" the memory based VL string into a buffer * @@ -627,17 +725,17 @@ H5T_vlen_str_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) +H5T__vlen_mem_str_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - char *s=*(char **)_vl; /* Pointer to the user's string information */ + char *s = *(char **)_vl; /* Pointer to the user's string information */ #else char *s; /* Pointer to the user's string information */ #endif - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - if(len>0) { + if(len > 0) { /* check parameters */ HDassert(buf); #ifdef H5_NO_ALIGNMENT_RESTRICTIONS @@ -647,15 +745,15 @@ H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - H5MM_memcpy(buf,s,len); + H5MM_memcpy(buf, s, len); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_vlen_str_mem_read() */ +} /* end H5T__vlen_mem_str_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_write + * Function: H5T__vlen_mem_str_write * * Purpose: "Writes" the memory based VL string from a buffer * @@ -667,154 +765,171 @@ H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_str_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, +H5T__vlen_mem_str_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void H5_ATTR_UNUSED *_bg, size_t seq_len, size_t base_size) { char *t; /* Pointer to temporary buffer allocated */ size_t len; /* Maximum length of the string to copy */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(buf); /* Use the user's memory allocation routine if one is defined */ - if(vl_alloc_info->alloc_func!=NULL) { - if(NULL==(t = (char *)(vl_alloc_info->alloc_func)((seq_len+1)*base_size,vl_alloc_info->alloc_info))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end if */ - else { /* Default to system malloc */ + if(vl_alloc_info->alloc_func != NULL) { + if(NULL == (t = (char *)(vl_alloc_info->alloc_func)((seq_len + 1) * base_size, vl_alloc_info->alloc_info))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "application memory allocation routine failed for VL data") + } /* end if */ + else /* Default to system malloc */ if(NULL == (t = (char *)HDmalloc((seq_len + 1) * base_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") - } /* end else */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed for VL data") - len=(seq_len*base_size); - H5MM_memcpy(t,buf,len); - t[len]='\0'; + /* 'write' the string into the buffer, with memcpy() */ + len = (seq_len * base_size); + H5MM_memcpy(t, buf, len); + t[len] = '\0'; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&t,sizeof(char *)); + H5MM_memcpy(_vl, &t, sizeof(char *)); done: FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ -} /* end H5T_vlen_str_mem_write() */ +} /* end H5T__vlen_mem_str_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_str_mem_setnull + * Function: H5T__vlen_disk_getlen * - * Purpose: Sets a VL info object in memory to the "null" value + * Purpose: Retrieves the length of a disk based VL element. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Saturday, November 8, 2003 + * Wednesday, June 2, 1999 * *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_str_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED *_bg) +H5T__vlen_disk_getlen(H5F_t H5_ATTR_UNUSED *f, const void *_vl, size_t *seq_len) { - char *t=NULL; /* Pointer to temporary buffer allocated */ + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR - /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - H5MM_memcpy(_vl,&t,sizeof(char *)); + /* Check parameters */ + HDassert(vl); + HDassert(seq_len); - FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ -} /* end H5T_vlen_str_mem_setnull() */ + /* Get length of sequence (different from blob size) */ + UINT32DECODE(vl, *seq_len); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__vlen_disk_getlen() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_getlen + * Function: H5T__vlen_disk_isnull * - * Purpose: Retrieves the length of a disk based VL element. + * Purpose: Checks if a disk VL info object is the "nil" object * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Wednesday, June 2, 1999 + * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static ssize_t -H5T_vlen_disk_getlen(const void *_vl) +static herr_t +H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) { - const uint8_t *vl=(const uint8_t *)_vl; /* Pointer to the disk VL information */ - size_t seq_len = 0; /* Sequence length */ + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ + HDassert(f); HDassert(vl); + HDassert(isnull); - UINT32DECODE(vl, seq_len); + /* Skip the sequence's length */ + vl += 4; - FUNC_LEAVE_NOAPI((ssize_t)seq_len) -} /* end H5T_vlen_disk_getlen() */ + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id((H5F_t *)f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - -/*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_getptr - * - * Purpose: Retrieves the pointer to a disk based VL element. - * - * Return: Non-NULL on success/NULL on failure - * - * Programmer: Quincey Koziol - * Saturday, June 12, 2004 - * - *------------------------------------------------------------------------- - */ -static void * -H5T_vlen_disk_getptr(void H5_ATTR_UNUSED *vl) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR + /* Check if blob ID is "nil" */ + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_ISNULL, isnull) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") - /* check parameters */ - HDassert(vl); - - FUNC_LEAVE_NOAPI(NULL) -} /* end H5T_vlen_disk_getptr() */ +done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__vlen_disk_isnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_isnull + * Function: H5T__vlen_disk_setnull * - * Purpose: Checks if a disk VL info object is the "nil" object + * Purpose: Sets a VL info object on disk to the "nil" value * - * Return: TRUE/FALSE on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Saturday, November 8, 2003 * *------------------------------------------------------------------------- */ -static htri_t -H5T_vlen_disk_isnull(const H5F_t *f, void *_vl) +static herr_t +H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the disk VL information */ - haddr_t addr; /* Sequence's heap address */ + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC /* check parameters */ + HDassert(f); HDassert(vl); - /* Skip the sequence's length */ - vl += 4; + /* Free heap object for old data */ + if(bg != NULL) + /* Delete sequence in destination location */ + if(H5T__vlen_disk_delete(f, bg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove background heap object") - /* Get the heap address */ - H5F_addr_decode(f, (const uint8_t **)&vl, &addr); + /* Set the length of the sequence */ + UINT32ENCODE(vl, 0); + + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - FUNC_LEAVE_NOAPI(addr == 0 ? TRUE : FALSE) -} /* end H5T_vlen_disk_isnull() */ + /* Set blob ID to "nil" */ + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_SETNULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") + +done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__vlen_disk_setnull() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_read + * Function: H5T__vlen_disk_read * * Purpose: Reads the disk based VL element into a buffer * @@ -826,40 +941,42 @@ H5T_vlen_disk_isnull(const H5F_t *f, void *_vl) *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) +H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) { - uint8_t *vl=(uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - H5HG_t hobjid; - herr_t ret_value=SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ + HDassert(f); HDassert(vl); HDassert(buf); - HDassert(f); /* Skip the length of the sequence */ vl += 4; - /* Get the heap information */ - H5F_addr_decode(f, (const uint8_t **)&vl, &(hobjid.addr)); - UINT32DECODE(vl, hobjid.idx); + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Check if this sequence actually has any data */ - if(hobjid.addr > 0) { - /* Read the VL information from disk */ - if(NULL == H5HG_read(f, &hobjid, buf, NULL)) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read VL information") - } + /* Retrieve blob */ + if(H5VL_blob_get(vol_obj, vl, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_read() */ +} /* end H5T__vlen_disk_read() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_write + * Function: H5T__vlen_disk_write * * Purpose: Writes the disk based VL element from a buffer * @@ -871,146 +988,129 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, +H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size) { - uint8_t *vl = (uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ - uint8_t *bg = (uint8_t *)_bg; /*Pointer to the old data hvl_t */ - H5HG_t hobjid; /* New VL sequence's heap ID */ - size_t len; /* Size of new sequence on disk (in bytes) */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object info */ + hid_t file_id = H5I_INVALID_HID; + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check parameters */ HDassert(vl); HDassert(seq_len == 0 || buf); HDassert(f); - /* Free heap object for old data. */ - if(bg!=NULL) { - H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ - - /* Skip the length of the sequence and heap object ID from background data. */ - bg += 4; - - /* Get heap information */ - H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); - UINT32DECODE(bg, bg_hobjid.idx); - - /* Free heap object for old data */ - if(bg_hobjid.addr > 0) { - /* Free heap object */ - if(H5HG_remove(f, &bg_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } - } /* end if */ + /* Free heap object for old data, if non-NULL */ + if(bg != NULL) + if(H5T__vlen_disk_delete(f, bg) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to remove background heap object") /* Set the length of the sequence */ UINT32ENCODE(vl, seq_len); - /* Write the VL information to disk (allocates space also) */ - len = (seq_len*base_size); - if(H5HG_insert(f, len, buf, &hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write VL information") + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Encode the heap information */ - H5F_addr_encode(f, &vl, hobjid.addr); - UINT32ENCODE(vl, hobjid.idx); + /* Store blob */ + if(H5VL_blob_put(vol_obj, buf, (seq_len * base_size), vl, NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_write() */ +} /* end H5T__vlen_disk_write() */ /*------------------------------------------------------------------------- - * Function: H5T_vlen_disk_setnull + * Function: H5T__vlen_disk_delete * - * Purpose: Sets a VL info object on disk to the "nil" value + * Purpose: Deletes a disk-based VL element * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success / Negative on failure * * Programmer: Quincey Koziol - * Saturday, November 8, 2003 + * Friday, August 15, 2019 * *------------------------------------------------------------------------- */ static herr_t -H5T_vlen_disk_setnull(H5F_t *f, void *_vl, void *_bg) +H5T__vlen_disk_delete(H5F_t *f, const void *_vl) { - uint8_t *vl = (uint8_t *)_vl; /*Pointer to the user's hvl_t information*/ - uint8_t *bg = (uint8_t *)_bg; /*Pointer to the old data hvl_t */ - uint32_t seq_len = 0; /* Sequence length */ - herr_t ret_value = SUCCEED; /* Return value */ + const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + hid_t file_id = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* check parameters */ + /* Check parameters */ HDassert(f); - HDassert(vl); - /* Free heap object for old data. */ - if(bg != NULL) { - H5HG_t bg_hobjid; /* "Background" VL info sequence's ID info */ + /* Free heap object for old data */ + if(vl != NULL) { + size_t seq_len; /* VL sequence's length */ - /* Skip the length of the sequence and heap object ID from background data. */ - bg += 4; + /* Get length of sequence */ + UINT32DECODE(vl, seq_len); - /* Get heap information */ - H5F_addr_decode(f, (const uint8_t **)&bg, &(bg_hobjid.addr)); - UINT32DECODE(bg, bg_hobjid.idx); + /* Delete object, if length > 0 */ + if(seq_len > 0) { + H5VL_object_t *vol_obj = NULL; /* Object info */ - /* Free heap object for old data */ - if(bg_hobjid.addr > 0) { - /* Free heap object */ - if(H5HG_remove(f, &bg_hobjid) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } /* end if */ - } /* end if */ + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Set the length of the sequence */ - UINT32ENCODE(vl, seq_len); - - /* Encode the "nil" heap pointer information */ - H5F_addr_encode(f, &vl, (haddr_t)0); - UINT32ENCODE(vl, 0); + if(H5VL_blob_specific(vol_obj, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") + } + } /* end if */ done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_disk_setnull() */ +} /* 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_NOAPI_NOINIT + 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) { @@ -1022,8 +1122,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset member and recurse on it */ for(u = 0; u < dt->shared->u.array.nelem; u++) { off = ((uint8_t *)elem) + u * (dt->shared->parent->shared->size); - if(H5T_vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free array element") + if(H5T_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 */ break; @@ -1037,8 +1137,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset member and recurse on it */ off = ((uint8_t *)elem) + dt->shared->u.compnd.memb[u].offset; - if(H5T_vlen_reclaim_recurse(off, dt->shared->u.compnd.memb[u].type, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free compound field") + if(H5T_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 */ break; @@ -1057,8 +1157,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi /* Calculate the offset of each array element and recurse on it */ while(vl->len > 0) { off = ((uint8_t *)vl->p) + (vl->len - 1) * dt->shared->parent->shared->size; - if(H5T_vlen_reclaim_recurse(off, dt->shared->parent, free_func, free_info) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "Unable to free VL element") + if(H5T_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 */ } /* end if */ @@ -1087,11 +1187,11 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi 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: @@ -1102,66 +1202,15 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_vlen_reclaim_recurse() */ - - -/*-------------------------------------------------------------------------- - 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) - - 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() */ +} /* end H5T_vlen_reclaim() */ /*------------------------------------------------------------------------- * Function: H5T_vlen_reclaim_elmt * * Purpose: Alternative method to reclaim any VL data for a buffer element. - * - * Use this function when the datatype is already available, but + * + * Use this function when the datatype is already available, but * the allocation info is needed from the context before jumping * into recursion. * @@ -1188,10 +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 */ - +} /* H5T_vlen_reclaim_elmt() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 0131f0e..e486fde 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -177,7 +177,12 @@ static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, va_list arguments); static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls); - +static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, + const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, + const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, + void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); /*********************/ /* Package Variables */ @@ -4185,7 +4190,7 @@ H5VL_link_copy(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_pa vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if(H5VL__link_copy((src_vol_obj->data ? src_vol_obj->data : NULL), loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0) + if(H5VL__link_copy(src_vol_obj->data, loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "link copy failed") done: @@ -4288,13 +4293,13 @@ H5VL_link_move(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_pa FUNC_ENTER_NOAPI(FAIL) /* Set wrapper info in API context */ - vol_obj = (src_vol_obj ? src_vol_obj : dst_vol_obj); + vol_obj = (src_vol_obj->data ? src_vol_obj : dst_vol_obj); if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if(H5VL__link_move((src_vol_obj ? src_vol_obj->data : NULL), loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0) + if(H5VL__link_move(src_vol_obj->data, loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTMOVE, FAIL, "link move failed") done: @@ -6564,6 +6569,350 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL__blob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(obj); + HDassert(cls); + HDassert(size == 0 || buf); + HDassert(blob_id); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.put) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method") + + /* Call the corresponding VOL callback */ + if((cls->blob_cls.put)(obj, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, August 21, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(size == 0 || buf); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*xz*x*x", obj, connector_id, buf, size, blob_id, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(obj, cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, + void *buf, size_t *size, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(obj); + HDassert(cls); + HDassert(blob_id); + HDassert(size || buf); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method") + + /* Call the corresponding VOL callback */ + if((cls->blob_cls.get)(obj, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + HDassert(size || buf); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*x*x*z*x", obj, connector_id, blob_id, buf, size, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(obj, cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, August 17, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(obj); + HDassert(cls); + HDassert(blob_id); + + /* Check if the corresponding VOL callback exists */ + if(NULL == cls->blob_cls.specific) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") + + /* Call the corresponding VOL callback */ + if((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, + H5VL_blob_specific_t specific_type, ...) +{ + va_list arguments; /* Argument list passed from the API call */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + HDva_start(arguments, specific_type); + arg_started = TRUE; + if((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") + +done: + /* End access to the va_list, if we started it */ + if(arg_started) + HDva_end(arguments); + + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_specific() */ + + +/*------------------------------------------------------------------------- * Function: H5VL__optional * * Purpose: Optional operation specific to connectors. diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 98bc521..3597751 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -37,11 +37,23 @@ #define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ #define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +/* Container info version */ +#define H5VL_CONTAINER_INFO_VERSION 0x01 /* Container info struct version */ + +/* The maximum size allowed for blobs */ +#define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ + +/* The maximum size allowed for tokens */ +#define H5VL_MAX_TOKEN_SIZE (16) /* Allow for 128-bits tokens */ /*******************/ /* Public Typedefs */ /*******************/ +/* type for tokens. Token are unique and permanent identifiers that are + * used to reference HDF5 objects. */ +typedef unsigned char H5VL_token_t[H5VL_MAX_TOKEN_SIZE]; + /* types for attribute GET callback */ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_ACPL, /* creation property list */ @@ -92,10 +104,11 @@ typedef enum H5VL_datatype_specific_t { /* types for file GET callback */ typedef enum H5VL_file_get_t { + H5VL_FILE_GET_CONT_INFO, /* file get container info */ H5VL_FILE_GET_FAPL, /* file access property list */ H5VL_FILE_GET_FCPL, /* file creation property list */ - H5VL_FILE_GET_INTENT, /* file intent */ H5VL_FILE_GET_FILENO, /* file number */ + H5VL_FILE_GET_INTENT, /* file intent */ H5VL_FILE_GET_NAME, /* file name */ H5VL_FILE_GET_OBJ_COUNT, /* object count in file */ H5VL_FILE_GET_OBJ_IDS /* object ids in file */ @@ -146,18 +159,16 @@ typedef enum H5VL_link_specific_t { /* types for object GET callback */ typedef enum H5VL_object_get_t { - H5VL_REF_GET_NAME, /* object name, for reference */ - H5VL_REF_GET_REGION, /* dataspace of region */ - H5VL_REF_GET_TYPE, /* type of object */ - H5VL_OBJECT_GET_NAME /* object name */ + H5VL_OBJECT_GET_NAME, /* object name */ + H5VL_OBJECT_GET_TYPE /* object type */ } H5VL_object_get_t; /* types for object SPECIFIC callback */ typedef enum H5VL_object_specific_t { H5VL_OBJECT_CHANGE_REF_COUNT, /* H5Oincr/decr_refcount */ H5VL_OBJECT_EXISTS, /* H5Oexists_by_name */ + H5VL_OBJECT_LOOKUP, /* Lookup object */ H5VL_OBJECT_VISIT, /* H5Ovisit(_by_name) */ - H5VL_REF_CREATE, /* H5Rcreate */ H5VL_OBJECT_FLUSH, /* H5{D|G|O|T}flush */ H5VL_OBJECT_REFRESH /* H5{D|G|O|T}refresh */ } H5VL_object_specific_t; @@ -169,56 +180,67 @@ typedef enum H5VL_request_specific_t { H5VL_REQUEST_WAITALL /* Wait until all requests complete */ } H5VL_request_specific_t; -/* types for different ways that objects are located in an HDF5 container */ +/* types for 'blob' SPECIFIC callback */ +typedef enum H5VL_blob_specific_t { + H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ + H5VL_BLOB_GETSIZE, /* Get size of blob */ + H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ + H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ +} H5VL_blob_specific_t; + +/* Types for different ways that objects are located in an HDF5 container */ typedef enum H5VL_loc_type_t { H5VL_OBJECT_BY_SELF, H5VL_OBJECT_BY_NAME, H5VL_OBJECT_BY_IDX, - H5VL_OBJECT_BY_ADDR, - H5VL_OBJECT_BY_REF + H5VL_OBJECT_BY_TOKEN } H5VL_loc_type_t; -struct H5VL_loc_by_name { +typedef struct H5VL_loc_by_name { const char *name; hid_t lapl_id; -}; +} H5VL_loc_by_name_t; -struct H5VL_loc_by_idx { +typedef struct H5VL_loc_by_idx { const char *name; H5_index_t idx_type; H5_iter_order_t order; hsize_t n; hid_t lapl_id; -}; +} H5VL_loc_by_idx_t; -struct H5VL_loc_by_addr { - haddr_t addr; -}; +typedef struct H5VL_loc_by_token { + void *token; +} H5VL_loc_by_token_t; -struct H5VL_loc_by_ref { - H5R_type_t ref_type; - const void *_ref; - hid_t lapl_id; -}; - -/* Structure to hold parameters for object locations. - * either: BY_ADDR, BY_ID, BY_NAME, BY_IDX, BY_REF +/* Structure to hold parameters for object locations. + * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN * - * Note: Leave loc_by_addr as the first union member so we + * Note: Leave loc_by_token as the first union member so we * can perform the simplest initialization of the struct * without raising warnings. + * + * Note: BY_SELF requires no union members. */ typedef struct H5VL_loc_params_t { H5I_type_t obj_type; H5VL_loc_type_t type; - union{ - struct H5VL_loc_by_addr loc_by_addr; - struct H5VL_loc_by_name loc_by_name; - struct H5VL_loc_by_idx loc_by_idx; - struct H5VL_loc_by_ref loc_by_ref; + union { + H5VL_loc_by_token_t loc_by_token; + H5VL_loc_by_name_t loc_by_name; + H5VL_loc_by_idx_t loc_by_idx; } loc_data; } H5VL_loc_params_t; +/* Info for H5VL_FILE_GET_CONT_INFO */ +typedef struct H5VL_file_cont_info_t { + unsigned version; /* version information (keep first) */ + uint64_t feature_flags; /* Container feature flags */ + /* (none currently defined) */ + size_t token_size; /* Size of tokens */ + size_t blob_id_size; /* Size of blob IDs */ +} H5VL_file_cont_info_t; + /* VOL connector info fields & callbacks */ typedef struct H5VL_info_class_t { size_t size; /* Size of the VOL info */ @@ -355,6 +377,14 @@ typedef struct H5VL_request_class_t { herr_t (*free)(void *req); } H5VL_request_class_t; +/* 'blob' routines */ +typedef struct H5VL_blob_class_t { + herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); + herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); + herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + herr_t (*optional)(void *obj, void *blob_id, va_list arguments); +} H5VL_blob_class_t; + /* * VOL connector identifiers. Values 0 through 255 are for connectors defined * by the HDF5 library. Values 256 through 511 are available for testing new @@ -386,8 +416,9 @@ typedef struct H5VL_class_t { H5VL_link_class_t link_cls; /* Link (H5L*) class callbacks */ H5VL_object_class_t object_cls; /* Object (H5O*) class callbacks */ - /* Services */ + /* Infrastructure / Services */ H5VL_request_class_t request_cls; /* Asynchronous request class callbacks */ + H5VL_blob_class_t blob_cls; /* 'blob' callbacks */ /* Catch-all */ herr_t (*optional)(void *obj, hid_t dxpl_id, void **req, va_list arguments); /* Optional callback */ @@ -398,6 +429,7 @@ typedef struct H5VL_class_t { /* Public Variables */ /********************/ + /*********************/ /* Public Prototypes */ /*********************/ diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 9a2bd52..d0d73d2 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -13,7 +13,7 @@ /* * This file contains public declarations for authoring VOL connectors * which act as "passthrough" connectors that forward their API calls to - * an underlying connector. + * an underlying connector. * * An example of this might be a logging connector, which creates log messages * and then passes the call on to an underlying VOL connector. @@ -158,6 +158,15 @@ H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_s H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); +/* Public wrappers for blob callbacks */ +H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + +/* Public wrappers for generic 'optional' callback */ +H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, hid_t dxpl_id, + void **req, va_list arguments); + #ifdef __cplusplus } #endif diff --git a/src/H5VLint.c b/src/H5VLint.c index f9262f4..09acb2a 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -543,6 +543,7 @@ static H5VL_object_t * H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj) { H5VL_object_t *new_vol_obj = NULL; /* Pointer to new VOL object */ + hbool_t conn_rc_incr = FALSE; /* Whether the VOL connector refcount has been incremented */ H5VL_object_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -569,6 +570,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t /* Bump the reference count on the VOL connector */ H5VL__conn_inc_rc(vol_connector); + conn_rc_incr = TRUE; /* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */ if(H5I_DATATYPE == type) { @@ -579,6 +581,12 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t ret_value = (H5VL_object_t *)new_vol_obj; done: + /* Cleanup on error */ + if(NULL == ret_value) { + if(conn_rc_incr && H5VL__conn_dec_rc(vol_connector) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector") + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__new_vol_obj() */ @@ -759,16 +767,17 @@ done: * get the connector information instead of it being passed in. * * Return: Success: A valid HDF5 ID - * Failure: H5I_INVALID_HID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) { - H5VL_class_t *cls = NULL; - H5VL_t *connector = NULL; /* VOL connector struct */ - hid_t ret_value = H5I_INVALID_HID; + H5VL_class_t *cls = NULL; /* VOL connector class */ + H5VL_t *connector = NULL; /* VOL connector struct */ + hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ + hid_t ret_value = H5I_INVALID_HID;/* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -783,12 +792,24 @@ H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool connector->id = connector_id; if(H5I_inc_ref(connector->id, FALSE) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + conn_id_incr = TRUE; /* Get an ID for the VOL object */ if((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: + /* Clean up on error */ + if(ret_value < 0) { + /* Decrement VOL connector ID ref count on error */ + if(conn_id_incr && H5I_dec_ref(connector_id) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to decrement ref count on VOL connector") + + /* Free VOL connector struct */ + if(NULL != connector) + connector = H5FL_FREE(H5VL_t, connector); + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_register_using_vol_id() */ diff --git a/src/H5VLnative.c b/src/H5VLnative.c index 7848c5d..78eaee4 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -11,8 +11,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Purpose: The native VOL connector where access is to a single HDF5 file - * using HDF5 VFDs. + * Purpose: The native VOL connector where access is to a single HDF5 file + * using HDF5 VFDs. */ #include "H5private.h" /* Generic Functions */ @@ -120,6 +120,12 @@ static H5VL_class_t H5VL_native_cls_g = { NULL, /* optional */ NULL /* free */ }, + { /* blob_cls */ + H5VL__native_blob_put, /* put */ + H5VL__native_blob_get, /* get */ + H5VL__native_blob_specific, /* specific */ + NULL /* optional */ + }, NULL /* optional */ }; diff --git a/src/H5VLnative.h b/src/H5VLnative.h index b2dd13d..5b51e66 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -17,6 +17,9 @@ #ifndef _H5VLnative_H #define _H5VLnative_H +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ + /* Identifier for the native VOL connector */ #define H5VL_NATIVE (H5VL_native_register()) diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c new file mode 100644 index 0000000..b16b407 --- /dev/null +++ b/src/H5VLnative_blob.c @@ -0,0 +1,237 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Blob callbacks for the native VOL connector + */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5VLnative_private.h" /* Native VOL connector */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_put + * + * Purpose: Handles the blob 'put' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, + void H5_ATTR_UNUSED *ctx) +{ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + uint8_t *id = (uint8_t *)blob_id; /* Pointer to blob ID */ + H5HG_t hobjid; /* New VL sequence's heap ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check parameters */ + HDassert(f); + HDassert(size == 0 || buf); + HDassert(id); + + /* Write the VL information to disk (allocates space also) */ + if(H5HG_insert(f, size, (void *)buf, &hobjid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write blob information") + + /* Encode the heap information */ + H5F_addr_encode(f, &id, hobjid.addr); + UINT32ENCODE(id, hobjid.idx); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_get + * + * Purpose: Handles the blob 'get' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, + void H5_ATTR_UNUSED *ctx) +{ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the disk blob ID */ + H5HG_t hobjid; /* Global heap ID for sequence */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(f); + HDassert(id); + HDassert(buf); + + /* Get the heap information */ + H5F_addr_decode(f, &id, &hobjid.addr); + UINT32DECODE(id, hobjid.idx); + + /* Check if this sequence actually has any data */ + if(hobjid.addr > 0) + /* Read the VL information from disk */ + if(NULL == H5HG_read(f, &hobjid, buf, size)) + HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read VL information") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_blob_specific + * + * Purpose: Handles the blob 'specific' callback + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, August 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__native_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(f); + HDassert(blob_id); + + switch(specific_type) { + case H5VL_BLOB_GETSIZE: + { + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ + size_t *size = HDva_arg(arguments, size_t *); + H5HG_t hobjid; /* blob's heap ID */ + + /* Get heap information */ + H5F_addr_decode(f, &id, &(hobjid.addr)); + UINT32DECODE(id, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) { + if(H5HG_get_obj_size(f, &hobjid, size) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") + } /* end if */ + else + *size = 0; /* Return '0' size for 'nil' blob ID */ + + break; + } + + case H5VL_BLOB_ISNULL: + { + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ + hbool_t *isnull = HDva_arg(arguments, hbool_t *); + haddr_t addr; /* Sequence's heap address */ + + /* Get the heap address */ + H5F_addr_decode(f, &id, &addr); + + /* Check if heap address is 'nil' */ + *isnull = (addr == 0 ? TRUE : FALSE); + + break; + } + + case H5VL_BLOB_SETNULL: + { + uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */ + /* Encode the "nil" heap pointer information */ + H5F_addr_encode(f, &id, (haddr_t)0); + UINT32ENCODE(id, 0); + + break; + } + + case H5VL_BLOB_DELETE: + { + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ + H5HG_t hobjid; /* VL sequence's heap ID */ + + /* Get heap information */ + H5F_addr_decode(f, &id, &hobjid.addr); + UINT32DECODE(id, hobjid.idx); + + /* Free heap object */ + if(hobjid.addr > 0) + if(H5HG_remove(f, &hobjid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_blob_specific() */ diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 1cb7533..63574c6 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -129,6 +129,18 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, FUNC_ENTER_PACKAGE switch(get_type) { + /* "get container info" */ + case H5VL_FILE_GET_CONT_INFO: + { + H5VL_file_cont_info_t *info = HDva_arg(arguments, H5VL_file_cont_info_t *); + + /* Retrieve the file's container info */ + if(H5F__get_cont_info((H5F_t *)obj, info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file container info") + + break; + } + /* H5Fget_access_plist */ case H5VL_FILE_GET_FAPL: { @@ -139,7 +151,7 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, /* Retrieve the file's access property list */ if((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file access property list") if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") @@ -163,42 +175,6 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, break; } - /* H5Fget_obj_count */ - case H5VL_FILE_GET_OBJ_COUNT: - { - unsigned types = HDva_arg(arguments, unsigned); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") - - /* Set the return value */ - *ret = (ssize_t)obj_count; - break; - } - - /* H5Fget_obj_ids */ - case H5VL_FILE_GET_OBJ_IDS: - { - unsigned types = HDva_arg(arguments, unsigned); - size_t max_objs = HDva_arg(arguments, size_t); - hid_t *oid_list = HDva_arg(arguments, hid_t *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") - - /* Set the return value */ - *ret = (ssize_t)obj_count; - break; - } - /* H5Fget_intent */ case H5VL_FILE_GET_INTENT: { @@ -266,6 +242,42 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, break; } + /* H5Fget_obj_count */ + case H5VL_FILE_GET_OBJ_COUNT: + { + unsigned types = HDva_arg(arguments, unsigned); + ssize_t *ret = HDva_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + + /* H5Fget_obj_ids */ + case H5VL_FILE_GET_OBJ_IDS: + { + unsigned types = HDva_arg(arguments, unsigned); + size_t max_objs = HDva_arg(arguments, size_t); + hid_t *oid_list = HDva_arg(arguments, hid_t *); + ssize_t *ret = HDva_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") } /* end switch */ @@ -397,7 +409,6 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, break; } - default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index 49d4b2c..675d8cf 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -16,7 +16,6 @@ */ #define H5O_FRIEND /* Suppress error about including H5Opkg */ -#define H5R_FRIEND /* Suppress error about including H5Rpkg */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ @@ -25,7 +24,6 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ -#include "H5Rpkg.h" /* References */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ @@ -71,31 +69,17 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ break; } - case H5VL_OBJECT_BY_ADDR: + case H5VL_OBJECT_BY_TOKEN: { - /* Open the object */ - if(NULL == (ret_value = H5O_open_by_addr(&loc, loc_params->loc_data.loc_by_addr.addr, opened_type))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by address") - break; - } + const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; + haddr_t addr; - case H5VL_OBJECT_BY_REF: - { - hid_t temp_id = H5I_INVALID_HID; - H5F_t *file = NULL; - - /* Get the file pointer from the entry */ - file = loc.oloc->file; + /* Decode token */ + H5F_addr_decode(loc.oloc->file, &p, &addr); - /* Create reference */ - if((temp_id = H5R__dereference(file, loc_params->loc_data.loc_by_ref.lapl_id, - loc_params->loc_data.loc_by_ref.ref_type, - loc_params->loc_data.loc_by_ref._ref)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, NULL, "unable to dereference object") - - *opened_type = H5I_get_type(temp_id); - if(NULL == (ret_value = H5I_remove(temp_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + /* Open the object */ + if(NULL == (ret_value = H5O_open_by_addr(&loc, addr, opened_type))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by address") break; } @@ -166,53 +150,6 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") switch(get_type) { - /* H5Rget_region */ - case H5VL_REF_GET_REGION: - { - hid_t *ret = HDva_arg(arguments, hid_t *); - H5R_type_t H5_ATTR_UNUSED ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - H5S_t *space = NULL; /* Dataspace object */ - - /* Get the dataspace with the correct region selected */ - if((space = H5R__get_region(loc.oloc->file, ref)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve region") - - /* Atomize */ - if((*ret = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") - - break; - } - - /* H5Rget_obj_type1/2 */ - case H5VL_REF_GET_TYPE: - { - H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - - /* Get the object information */ - if(H5R__get_obj_type(loc.oloc->file, ref_type, ref, obj_type) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object type") - break; - } - - /* H5Rget_name */ - case H5VL_REF_GET_NAME: - { - ssize_t *ret = HDva_arg(arguments, ssize_t *); - char *name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - void *ref = HDva_arg(arguments, void *); - - /* Get name */ - if((*ret = H5R__get_name(loc.oloc->file, ref_type, ref, name, size)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object path") - break; - } - /* Object name */ case H5VL_OBJECT_GET_NAME: { @@ -225,13 +162,15 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve object name") } /* end if */ - else if(loc_params->type == H5VL_OBJECT_BY_ADDR) { + else if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { H5O_loc_t obj_oloc; /* Object location */ + const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; /* Initialize the object location */ H5O_loc_reset(&obj_oloc); obj_oloc.file = loc.oloc->file; - obj_oloc.addr = loc_params->loc_data.loc_by_addr.addr; + /* Decode token */ + H5F_addr_decode(obj_oloc.file, &p, &obj_oloc.addr); /* Retrieve object's name */ if((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) @@ -242,6 +181,31 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj break; } + /* Object type */ + case H5VL_OBJECT_GET_TYPE: + { + H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); + + if(loc_params->type == H5VL_OBJECT_BY_TOKEN) { + H5O_loc_t obj_oloc; /* Object location */ + unsigned rc; /* Reference count of object */ + const uint8_t *p = (const uint8_t *)loc_params->loc_data.loc_by_token.token; + + /* Initialize the object location */ + H5O_loc_reset(&obj_oloc); + obj_oloc.file = loc.oloc->file; + /* Decode token */ + H5F_addr_decode(obj_oloc.file, &p, &obj_oloc.addr); + + /* Get the # of links for object, and its type */ + /* (To check to make certain that this object hasn't been deleted) */ + if(H5O_get_rc_and_type(&obj_oloc, &rc, obj_type) < 0 || 0 == rc) + HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") + } else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_type parameters") + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") } /* end switch */ @@ -300,6 +264,40 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V break; } + /* Lookup object */ + case H5VL_OBJECT_LOOKUP: + { + void *token = va_arg(arguments, void *); + + HDassert(token); + + if(loc_params->type == H5VL_OBJECT_BY_NAME) { + H5G_loc_t obj_loc; /* Group hier. location of object */ + H5G_name_t obj_path; /* Object group hier. path */ + H5O_loc_t obj_oloc; /* Object object location */ + uint8_t *p = (uint8_t *)token; /* Pointer to token */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object */ + if(H5G_loc_find(&loc, loc_params->loc_data.loc_by_name.name, &obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + + /* Encode token */ + H5F_addr_encode(obj_oloc.file, &p, obj_loc.oloc->addr); + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + break; + } + case H5VL_OBJECT_VISIT: { H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ @@ -347,24 +345,6 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V break; } - case H5VL_REF_CREATE: - { - void *ref = HDva_arg(arguments, void *); - const char *name = HDva_arg(arguments, char *); - H5R_type_t ref_type = (H5R_type_t)HDva_arg(arguments, int); /* enum work-around */ - hid_t space_id = HDva_arg(arguments, hid_t); - H5S_t *space = NULL; /* Pointer to dataspace containing region */ - - if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - - /* Create reference */ - if(H5R__create(ref, &loc, name, ref_type, space) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create reference") - - break; - } - default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") } /* end switch */ diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index 714b73c..5ed0b1f 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -17,13 +17,34 @@ #ifndef _H5VLnative_private_H #define _H5VLnative_private_H +/* Private headers needed by this file */ #include "H5VLnative.h" /* Native VOL connector */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + #ifdef __cplusplus extern "C" { #endif -/* Atrribute callbacks */ +/* Attribute callbacks */ H5_DLL void *H5VL__native_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req); void *H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req); @@ -80,6 +101,11 @@ H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_t get_type, H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); +/* Blob callbacks */ +H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + #ifdef __cplusplus } #endif diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 24070fa..85c2211 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -178,6 +178,12 @@ static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specifi static herr_t H5VL_pass_through_request_optional(void *req, va_list arguments); static herr_t H5VL_pass_through_request_free(void *req); +/* Blob callbacks */ +static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + + /*******************/ /* Local variables */ /*******************/ @@ -196,14 +202,14 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_info_cmp, /* compare */ H5VL_pass_through_info_free, /* free */ H5VL_pass_through_info_to_str, /* to_str */ - H5VL_pass_through_str_to_info, /* from_str */ + H5VL_pass_through_str_to_info /* from_str */ }, { /* wrap_cls */ H5VL_pass_through_get_object, /* get_object */ H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */ H5VL_pass_through_wrap_object, /* wrap_object */ H5VL_pass_through_unwrap_object, /* unwrap_object */ - H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */ + H5VL_pass_through_free_wrap_ctx /* free_wrap_ctx */ }, { /* attribute_cls */ H5VL_pass_through_attr_create, /* create */ @@ -255,14 +261,14 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_link_move, /* move */ H5VL_pass_through_link_get, /* get */ H5VL_pass_through_link_specific, /* specific */ - H5VL_pass_through_link_optional, /* optional */ + H5VL_pass_through_link_optional /* optional */ }, { /* object_cls */ H5VL_pass_through_object_open, /* open */ H5VL_pass_through_object_copy, /* copy */ H5VL_pass_through_object_get, /* get */ H5VL_pass_through_object_specific, /* specific */ - H5VL_pass_through_object_optional, /* optional */ + H5VL_pass_through_object_optional /* optional */ }, { /* request_cls */ H5VL_pass_through_request_wait, /* wait */ @@ -272,6 +278,12 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_request_optional, /* optional */ H5VL_pass_through_request_free /* free */ }, + { /* blob_cls */ + H5VL_pass_through_blob_put, /* put */ + H5VL_pass_through_blob_get, /* get */ + H5VL_pass_through_blob_specific, /* specific */ + NULL /* optional */ + }, NULL /* optional */ }; @@ -2834,3 +2846,83 @@ H5VL_pass_through_request_free(void *obj) return ret_value; } /* end H5VL_pass_through_request_free() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_put + * + * Purpose: Handles the blob 'put' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Put\n"); +#endif + + ret_value = H5VLblob_put(o->under_object, o->under_vol_id, buf, size, + blob_id, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_get + * + * Purpose: Handles the blob 'get' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Get\n"); +#endif + + ret_value = H5VLblob_get(o->under_object, o->under_vol_id, blob_id, buf, + size, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_specific + * + * Purpose: Handles the blob 'specific' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Specific\n"); +#endif + + ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, + specific_type, arguments); + + return ret_value; +} /* end H5VL_pass_through_blob_specific() */ diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h index e640636..d145bcd 100644 --- a/src/H5VLpassthru.h +++ b/src/H5VLpassthru.h @@ -17,6 +17,9 @@ #ifndef _H5VLpassthru_H #define _H5VLpassthru_H +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ + /* Identifier for the pass-through VOL connector */ #define H5VL_PASSTHRU (H5VL_pass_through_register()) diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 1752b0c..2889524 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -193,6 +193,11 @@ H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_s H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, ...); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); +/* Blob functions */ +H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...); + /* Generic functions */ H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, hid_t dxpl_id,void **req, ...); diff --git a/src/H5detect.c b/src/H5detect.c index 32b7d34..d01ee9f 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -107,8 +107,8 @@ typedef struct detected_t { unsigned int comp_align; /* alignment for structure */ } detected_t; -/* This structure holds structure alignment for pointers, hvl_t, hobj_ref_t, - * hdset_reg_ref_t */ +/* This structure holds structure alignment for pointers, vlen and reference + * types. */ typedef struct malign_t { const char *name; unsigned int comp_align; /* alignment for structure */ @@ -383,9 +383,8 @@ precision (detected_t *d) /*------------------------------------------------------------------------- * Function: DETECT_M * - * Purpose: This macro takes only miscellaneous structures or pointer - * (pointer, hvl_t, hobj_ref_t, hdset_reg_ref_t). It - * constructs the names and decides the alignment in structure. + * Purpose: This macro takes only miscellaneous structures or pointer. + * It constructs the names and decides the alignment in structure. * * Return: void *------------------------------------------------------------------------- @@ -761,8 +760,8 @@ H5T__init_native(void)\n\ H5T_native_order_g = H5T_ORDER_%s;\n", "BE"); } - /* Structure alignment for pointers, hvl_t, hobj_ref_t, hdset_reg_ref_t */ - fprintf(rawoutstream, "\n /* Structure alignment for pointers, hvl_t, hobj_ref_t, hdset_reg_ref_t */\n"); + /* Structure alignment for pointers, vlen and reference types */ + fprintf(rawoutstream, "\n /* Structure alignment for pointers, vlen and reference types */\n"); for(j=0; 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++; } diff --git a/src/H5mpi.c b/src/H5mpi.c index d48790b..f529b3d 100644 --- a/src/H5mpi.c +++ b/src/H5mpi.c @@ -22,6 +22,64 @@ #ifdef H5_HAVE_PARALLEL + +/****************/ +/* Local Macros */ +/****************/ +#define TWO_GIG_LIMIT (1 << 31) +#ifndef H5_MAX_MPI_COUNT +#define H5_MAX_MPI_COUNT (1 << 30) +#endif + +/*******************/ +/* Local Variables */ +/*******************/ +static hsize_t bigio_count = H5_MAX_MPI_COUNT; + + +/*------------------------------------------------------------------------- + * Function: H5_mpi_set_bigio_count + * + * Purpose: Allow us to programatically change the switch point + * when we utilize derived datatypes. This is of + * particular interest for allowing nightly testing + * + * Return: The current/previous value of bigio_count. + * + * Programmer: Richard Warren, March 10, 2017 + * + *------------------------------------------------------------------------- + */ +hsize_t +H5_mpi_set_bigio_count(hsize_t new_count) +{ + hsize_t orig_count = bigio_count; + + if((new_count > 0) && (new_count < (hsize_t)TWO_GIG_LIMIT)) { + bigio_count = new_count; + } + return orig_count; +} /* end H5_mpi_set_bigio_count() */ + + +/*------------------------------------------------------------------------- + * Function: H5_mpi_get_bigio_count + * + * Purpose: Allow other HDF5 library functions to access + * the current value for bigio_count. + * + * Return: The current/previous value of bigio_count. + * + * Programmer: Richard Warren, October 7, 2019 + * + *------------------------------------------------------------------------- + */ +hsize_t +H5_mpi_get_bigio_count() +{ + return bigio_count; +} + /*------------------------------------------------------------------------- * Function: H5_mpi_comm_dup @@ -392,5 +450,114 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5_mpi_info_cmp() */ + +/*------------------------------------------------------------------------- + * Function: H5_mpio_create_large_type + * + * Purpose: Create a large datatype of size larger than what a 32 bit integer + * can hold. + * + * Return: Non-negative on success, negative on failure. + * + * *new_type the new datatype created + * + * Programmer: Mohamad Chaarawi + * + *------------------------------------------------------------------------- + */ +herr_t +H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, + MPI_Datatype old_type, MPI_Datatype *new_type) +{ + int num_big_types; /* num times the 2G datatype will be repeated */ + int remaining_bytes; /* the number of bytes left that can be held in an int value */ + hsize_t leftover; + int block_len[2]; + int mpi_code; /* MPI return code */ + MPI_Datatype inner_type, outer_type, leftover_type, type[2]; + MPI_Aint disp[2], old_extent; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Calculate how many Big MPI datatypes are needed to represent the buffer */ + num_big_types = (int)(num_elements/bigio_count); + leftover = num_elements - num_big_types * (hsize_t)bigio_count; + H5_CHECKED_ASSIGN(remaining_bytes, int, leftover, hsize_t); + + /* Create a contiguous datatype of size equal to the largest + * number that a 32 bit integer can hold x size of old type. + * If the displacement is 0, then the type is contiguous, otherwise + * use type_hvector to create the type with the displacement provided + */ + if (0 == stride_bytes) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(bigio_count, old_type, &inner_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(bigio_count, 1, stride_bytes, old_type, &inner_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) + + /* Create a contiguous datatype of the buffer (minus the remaining < 2GB part) + * If a stride is present, use hvector type + */ + if(0 == stride_bytes) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(num_big_types, inner_type, &outer_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(num_big_types, 1, stride_bytes, inner_type, &outer_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) + + MPI_Type_free(&inner_type); + + /* If there is a remaining part create a contiguous/vector datatype and then + * use a struct datatype to encapsulate everything. + */ + if(remaining_bytes) { + if(stride_bytes == 0) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(remaining_bytes, old_type, &leftover_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)(num_elements - (hsize_t)num_big_types * bigio_count), 1, stride_bytes, old_type, &leftover_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) + + /* As of version 4.0, OpenMPI now turns off MPI-1 API calls by default, + * so we're using the MPI-2 version even though we don't need the lb + * value. + */ + { + MPI_Aint unused_lb_arg; + MPI_Type_get_extent(old_type, &unused_lb_arg, &old_extent); + } + + /* Set up the arguments for MPI_Type_struct constructor */ + type[0] = outer_type; + type[1] = leftover_type; + block_len[0] = 1; + block_len[1] = 1; + disp[0] = 0; + disp[1] = (old_extent + stride_bytes) * num_big_types * (MPI_Aint)bigio_count; + + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(2, block_len, disp, type, new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + MPI_Type_free(&outer_type); + MPI_Type_free(&leftover_type); + } /* end if */ + else + /* There are no remaining bytes so just set the new type to + * the outer type created */ + *new_type = outer_type; + + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5_mpio_create_large_type() */ + + #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5private.h b/src/H5private.h index 62951b7..b5ee984 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -2687,12 +2687,16 @@ H5_DLL herr_t H5_combine_path(const char *path1, const char *path2, char **ful #ifdef H5_HAVE_PARALLEL /* Generic MPI functions */ +H5_DLL hsize_t H5_mpi_set_bigio_count(hsize_t new_count); +H5_DLL hsize_t H5_mpi_get_bigio_count(); H5_DLL herr_t H5_mpi_comm_dup(MPI_Comm comm, MPI_Comm *comm_new); H5_DLL herr_t H5_mpi_info_dup(MPI_Info info, MPI_Info *info_new); H5_DLL herr_t H5_mpi_comm_free(MPI_Comm *comm); H5_DLL herr_t H5_mpi_info_free(MPI_Info *info); H5_DLL herr_t H5_mpi_comm_cmp(MPI_Comm comm1, MPI_Comm comm2, int *result); H5_DLL herr_t H5_mpi_info_cmp(MPI_Info info1, MPI_Info info2, int *result); +H5_DLL herr_t H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, + MPI_Datatype old_type, MPI_Datatype *new_type); #endif /* H5_HAVE_PARALLEL */ /* Functions for debugging */ diff --git a/src/H5trace.c b/src/H5trace.c index b1301dd..79dfbc8 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -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_REGION1: + HDfprintf(out, "H5R_DATASET_REGION1"); break; - case H5R_DATASET_REGION: - HDfprintf(out, "H5R_DATASET_REGION"); + 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: @@ -2592,6 +2634,35 @@ H5_trace(const double *returning, const char *func, const char *type, ...) } /* end switch */ } /* end else */ break; + case 'B': + if(ptr) { + if(vp) + HDfprintf (out, "0x%lx", (unsigned long)vp); + else + HDfprintf(out, "NULL"); + } /* end if */ + else { + H5VL_blob_specific_t specific = (H5VL_blob_specific_t)HDva_arg(ap, int); + + switch(specific) { + case H5VL_BLOB_DELETE: + HDfprintf(out, "H5VL_BLOB_DELETE"); + break; + case H5VL_BLOB_GETSIZE: + HDfprintf(out, "H5VL_BLOB_GETSIZE"); + break; + case H5VL_BLOB_ISNULL: + HDfprintf(out, "H5VL_BLOB_ISNULL"); + break; + case H5VL_BLOB_SETNULL: + HDfprintf(out, "H5VL_BLOB_SETNULL"); + break; + default: + HDfprintf(out, "%ld", (long)specific); + break; + } /* end switch */ + } /* end else */ + break; case 'C': if(ptr) { if(vp) @@ -2729,18 +2800,21 @@ H5_trace(const double *returning, const char *func, const char *type, ...) H5VL_file_get_t get = (H5VL_file_get_t)HDva_arg(ap, int); switch(get) { + case H5VL_FILE_GET_CONT_INFO: + HDfprintf(out, "H5VL_FILE_GET_CONT_INFO"); + break; case H5VL_FILE_GET_FAPL: HDfprintf(out, "H5VL_FILE_GET_FAPL"); break; case H5VL_FILE_GET_FCPL: HDfprintf(out, "H5VL_FILE_GET_FCPL"); break; - case H5VL_FILE_GET_INTENT: - HDfprintf(out, "H5VL_FILE_GET_INTENT"); - break; case H5VL_FILE_GET_FILENO: HDfprintf(out, "H5VL_FILE_GET_FILENO"); break; + case H5VL_FILE_GET_INTENT: + HDfprintf(out, "H5VL_FILE_GET_INTENT"); + break; case H5VL_FILE_GET_NAME: HDfprintf(out, "H5VL_FILE_GET_NAME"); break; @@ -2926,18 +3000,12 @@ H5_trace(const double *returning, const char *func, const char *type, ...) H5VL_object_get_t get = (H5VL_object_get_t)HDva_arg(ap, int); switch(get) { - case H5VL_REF_GET_REGION: - HDfprintf(out, "H5VL_REF_GET_REGION"); - break; - case H5VL_REF_GET_TYPE: - HDfprintf(out, "H5VL_REF_GET_TYPE"); - break; - case H5VL_REF_GET_NAME: - HDfprintf(out, "H5VL_REF_GET_NAME"); - break; case H5VL_OBJECT_GET_NAME: HDfprintf(out, "H5VL_OBJECT_GET_NAME"); break; + case H5VL_OBJECT_GET_TYPE: + HDfprintf(out, "H5VL_OBJECT_GET_TYPE"); + break; default: HDfprintf(out, "%ld", (long)get); break; @@ -2961,12 +3029,12 @@ H5_trace(const double *returning, const char *func, const char *type, ...) case H5VL_OBJECT_EXISTS: HDfprintf(out, "H5VL_OBJECT_EXISTS"); break; + case H5VL_OBJECT_LOOKUP: + HDfprintf(out, "H5VL_OBJECT_LOOKUP"); + break; case H5VL_OBJECT_VISIT: HDfprintf(out, "H5VL_OBJECT_VISIT"); break; - case H5VL_REF_CREATE: - HDfprintf(out, "H5VL_REF_CREATE"); - break; case H5VL_OBJECT_FLUSH: HDfprintf(out, "H5VL_OBJECT_FLUSH"); break; diff --git a/src/Makefile.am b/src/Makefile.am index ccee69b..fa412c9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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,10 +114,12 @@ 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_dataset.c H5VLnative_datatype.c \ - H5VLnative_file.c H5VLnative_group.c H5VLnative_link.c H5VLnative_object.c \ + H5VLnative_attr.c H5VLnative_blob.c H5VLnative_dataset.c \ + H5VLnative_datatype.c H5VLnative_file.c H5VLnative_group.c \ + H5VLnative_link.c H5VLnative_object.c \ H5VLpassthru.c \ H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8184d7f..c7a945e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 diff --git a/test/Makefile.am b/test/Makefile.am index a19079d..57080aa 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 diff --git a/test/dsets.c b/test/dsets.c index 649e001..21d5431 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -4085,8 +4085,8 @@ test_nbit_compound_3(hid_t file) * Cleanup *---------------------------------------------------------------------- */ - if(H5Dvlen_reclaim(cmpd_tid, space, H5P_DEFAULT, new_data) < 0) goto error; - if(H5Dvlen_reclaim(cmpd_tid, space, H5P_DEFAULT, orig_data) < 0) goto error; + if(H5Treclaim(cmpd_tid, space, H5P_DEFAULT, new_data) < 0) goto error; + if(H5Treclaim(cmpd_tid, space, H5P_DEFAULT, orig_data) < 0) goto error; if(H5Tclose(i_tid) < 0) goto error; if(H5Tclose(str_tid) < 0) goto error; if(H5Tclose(vl_str_tid) < 0) goto error; diff --git a/test/dtypes.c b/test/dtypes.c index 98a3f87..689336f 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1809,7 +1809,7 @@ test_compound_9(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -1875,7 +1875,7 @@ test_compound_9(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(dup_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't read data\n"); goto error; @@ -2063,12 +2063,12 @@ test_compound_10(void) goto error; } } /* end for */ - if(H5Dvlen_reclaim(arr_tid, space_id, H5P_DEFAULT, &rdata) < 0) { + if(H5Treclaim(arr_tid, space_id, H5P_DEFAULT, &rdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ - if(H5Dvlen_reclaim(arr_tid, space_id, H5P_DEFAULT, &wdata) < 0) { + if(H5Treclaim(arr_tid, space_id, H5P_DEFAULT, &wdata) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -2226,7 +2226,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid2, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid2, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2270,7 +2270,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2308,7 +2308,7 @@ test_compound_11(void) TEST_ERROR } /* end if */ } /* end for */ - if(H5Dvlen_reclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { + if(H5Treclaim(little_tid, space_id, H5P_DEFAULT, buf) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim data\n"); goto error; @@ -2811,13 +2811,13 @@ test_compound_14(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { + if(H5Treclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ rdata1.str = NULL; - if(H5Dvlen_reclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { + if(H5Treclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; @@ -2898,13 +2898,13 @@ test_compound_14(void) goto error; } /* end if */ - if(H5Dvlen_reclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { + if(H5Treclaim(cmpd_m1_tid, space_id, H5P_DEFAULT, &rdata1) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; } /* end if */ rdata1.str = NULL; - if(H5Dvlen_reclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { + if(H5Treclaim(cmpd_m2_tid, space_id, H5P_DEFAULT, &rdata2) < 0) { H5_FAILED(); AT(); HDprintf("Can't reclaim read data\n"); goto error; diff --git a/test/fillval.c b/test/fillval.c index 0454bde..47cd53a 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -1516,7 +1516,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1572,7 +1572,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1613,7 +1613,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1652,7 +1652,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1693,7 +1693,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1739,7 +1739,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(H5Dwrite(dset, dtype, mspace, fspace, H5P_DEFAULT, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1758,7 +1758,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, fillval) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); @@ -1786,7 +1786,7 @@ test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name, if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR /* Release any VL components */ - if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR + if(H5Treclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR /* Clear the read buffer */ HDmemset(val_rd, 0, val_size); diff --git a/test/genall5.c b/test/genall5.c index 4cc0a2d..849d97c 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -2735,11 +2735,11 @@ ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) { } if ((pass) && (write_data)) { - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, wdata); if (ret < 0) { pass = FALSE; - failure_mssg = "ds_ctg_v: H5Dvlen_reclaim() failed."; + failure_mssg = "ds_ctg_v: H5Treclaim() failed."; } HDassert(ret >= 0); @@ -3003,11 +3003,11 @@ vrfy_ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) { } if ((pass) && (write_data)) { - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rdata); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, rdata); if (ret < 0) { pass = FALSE; - failure_mssg = "vrfy_ds_ctg_v: H5Dvlen_reclaim() failed."; + failure_mssg = "vrfy_ds_ctg_v: H5Treclaim() failed."; } HDassert(ret >= 0); diff --git a/test/links.c b/test/links.c index 4eb4126..916ad88 100644 --- a/test/links.c +++ b/test/links.c @@ -1576,6 +1576,10 @@ test_deprec(hid_t fapl, hbool_t new_format) if(H5Gget_linkval(group2_id, "soft_link_to_group1", sb_soft1.linklen, tmpstr) < 0) FAIL_STACK_ERROR if(HDstrcmp("link_to_group1", tmpstr)) TEST_ERROR + /* Test non-existing links with H5Gget_objinfo */ + H5E_BEGIN_TRY { + if(H5Gget_objinfo(file_id, "/group2/soft_link_no_exist", TRUE, NULL) >= 0) FAIL_STACK_ERROR + } H5E_END_TRY; /* Test the dangling soft link */ if(H5Gget_objinfo(file_id, "/group2/dangle_soft_link", FALSE, &sb_soft2) < 0) FAIL_STACK_ERROR @@ -14103,7 +14107,8 @@ main(void) nerrors += group_info_old(fapl) < 0 ? 1 : 0; if (minimize_dset_oh) { - if (H5Pclose(dcpl_g) < 0) TEST_ERROR; + if (H5Pclose(dcpl_g) < 0) + TEST_ERROR; dcpl_g = -1; } } /* [un]minimized dataset object headers */ @@ -14141,5 +14146,5 @@ main(void) error: HDputs("*** TESTS FAILED ***"); HDexit(EXIT_FAILURE); -} +} /* end main() */ diff --git a/test/ntypes.c b/test/ntypes.c index 83cdfd2..34558f5 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -1779,10 +1779,10 @@ test_vl_dtype(hid_t file) } /* end for */ /* Reclaim the read VL data */ - if(H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, rdata) < 0) TEST_ERROR; + if(H5Treclaim(native_type, space, H5P_DEFAULT, rdata) < 0) TEST_ERROR; /* Reclaim the write VL data */ - if(H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, wdata) < 0) TEST_ERROR; + if(H5Treclaim(native_type, space, H5P_DEFAULT, wdata) < 0) TEST_ERROR; /* Close Dataset */ if(H5Dclose(dataset) < 0) TEST_ERROR; @@ -1808,8 +1808,8 @@ error: H5E_BEGIN_TRY { if(native_type > 0) { - H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, rdata); - H5Dvlen_reclaim(native_type, space, H5P_DEFAULT, wdata); + H5Treclaim(native_type, space, H5P_DEFAULT, rdata); + H5Treclaim(native_type, space, H5P_DEFAULT, wdata); } /* end if */ H5Sclose(space); H5Dclose(dataset); diff --git a/test/objcopy.c b/test/objcopy.c index 05ddfa4..083d9af 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -547,7 +547,7 @@ done: if(tid >0 && sid > 0) { hid_t dxpl_id = H5Pcreate(H5P_DATASET_XFER); H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL); - H5Dvlen_reclaim(tid, sid, dxpl_id, buf); + H5Treclaim(tid, sid, dxpl_id, buf); H5Pclose(dxpl_id); } if(sid > 0) @@ -794,9 +794,9 @@ compare_attribute(hid_t aid, hid_t aid2, hid_t pid, const void *wbuf, hid_t obj_ /* Reclaim vlen data, if necessary */ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR /* Release raw data buffers */ HDfree(rbuf); @@ -1306,9 +1306,9 @@ compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf) /* Reclaim vlen data, if necessary */ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) - if(H5Dvlen_reclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR /* Release raw data buffers */ HDfree(rbuf); @@ -5290,7 +5290,7 @@ test_copy_dataset_contig_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_ if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5307,7 +5307,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -5473,7 +5473,7 @@ test_copy_dataset_chunked_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5490,7 +5490,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -5618,7 +5618,7 @@ test_copy_dataset_compact_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -5635,7 +5635,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -5896,8 +5896,8 @@ compare_attribute_compound_vlstr(hid_t loc, hid_t loc2) /* Reclaim vlen buffer */ if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, &rbuf) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, &rbuf2) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, &rbuf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, &rbuf2) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR /* Close the dataspaces */ @@ -5917,8 +5917,8 @@ error: H5E_BEGIN_TRY { H5Aclose(aid); H5Aclose(aid2); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, &rbuf); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, &rbuf2); + H5Treclaim(tid, sid, H5P_DEFAULT, &rbuf); + H5Treclaim(tid, sid, H5P_DEFAULT, &rbuf2); H5Sclose(sid); H5Sclose(sid2); H5Tclose(tid); @@ -6219,7 +6219,7 @@ test_copy_dataset_compressed_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -6239,7 +6239,7 @@ error: H5Dclose(did2); H5Dclose(did); H5Pclose(pid); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Sclose(sid); @@ -8050,7 +8050,7 @@ test_copy_dataset_compact_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8068,7 +8068,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8197,7 +8197,7 @@ test_copy_dataset_contig_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8214,7 +8214,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8364,7 +8364,7 @@ test_copy_dataset_chunked_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8382,7 +8382,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8521,7 +8521,7 @@ test_copy_dataset_compressed_named_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_ if(H5Tdetect_class(tid_copy, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid_copy, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8539,7 +8539,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid_copy, sid, H5P_DEFAULT, buf); + H5Treclaim(tid_copy, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid_copy); @@ -8683,7 +8683,7 @@ test_copy_dataset_compact_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8701,7 +8701,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -8856,7 +8856,7 @@ test_copy_dataset_contig_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, h if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -8874,7 +8874,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid); @@ -9057,7 +9057,7 @@ test_copy_dataset_chunked_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9076,7 +9076,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid2); @@ -9233,7 +9233,7 @@ test_copy_dataset_compressed_vl_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fap if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid2, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9252,7 +9252,7 @@ error: H5Pclose(pid); H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid2, sid, H5P_DEFAULT, buf); + H5Treclaim(tid2, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid); H5Tclose(tid2); @@ -9389,7 +9389,7 @@ test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9407,7 +9407,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Tclose(tid2); H5Tclose(tid); @@ -9542,7 +9542,7 @@ test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9560,7 +9560,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid2); @@ -9695,7 +9695,7 @@ test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR if(H5Pset_vlen_mem_manager(dxpl_id, NULL, NULL, NULL, NULL) < 0) TEST_ERROR - if(H5Dvlen_reclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR + if(H5Treclaim(tid, sid, dxpl_id, buf) < 0) TEST_ERROR if(H5Pclose(dxpl_id) < 0) TEST_ERROR } /* end if */ @@ -9713,7 +9713,7 @@ error: H5E_BEGIN_TRY { H5Dclose(did2); H5Dclose(did); - H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf); + H5Treclaim(tid, sid, H5P_DEFAULT, buf); H5Pclose(dxpl_id); H5Pclose(pid); H5Tclose(tid2); diff --git a/test/objcopy_ref.c b/test/objcopy_ref.c new file mode 100644 index 0000000..721a7c6 --- /dev/null +++ b/test/objcopy_ref.c @@ -0,0 +1,1739 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Peter X. Cao + * May 01, 2005 + * + * Purpose: Test H5Ocopy() for references. + */ + +#include "testhdf5.h" + +#define H5F_FRIEND /*suppress error about including H5Fpkg */ +#define H5F_TESTING +#include "H5Fpkg.h" /* File access */ + +const char *FILENAME[] = { + "objcopy_ref_src", + "objcopy_ref_dst", + "objcopy_ref_ext", + "objcopy_ref_src2", + "verbound_ref_src", + "verbound_ref_dst", + NULL +}; + +/* Configuration, really a series of bit flags. Maximum value is all three + * bit flags enabled. + */ +#define CONFIG_SHARE_SRC 1 +#define CONFIG_SHARE_DST 2 +#define CONFIG_SRC_NEW_FORMAT 4 +#define CONFIG_DST_NEW_FORMAT 8 +#define CONFIG_DENSE 16 +#define MAX_CONFIGURATION 31 + +#define NAME_DATATYPE_SIMPLE "H5T_NATIVE_INT" +#define NAME_DATATYPE_SIMPLE2 "H5T_NATIVE_INT-2" +#define NAME_DATATYPE_VL "vlen of int" +#define NAME_DATATYPE_VL_VL "vlen of vlen of int" +#define NAME_DATASET_SIMPLE "dataset_simple" +#define NAME_DATASET_SIMPLE2 "dataset_simple_copy" +#define NAME_DATASET_SIMPLE3 "dataset_simple_another_copy" +#define NAME_DATASET_COMPOUND "dataset_compound" +#define NAME_DATASET_CHUNKED "dataset_chunked" +#define NAME_DATASET_CHUNKED_SINGLE "dataset_chunked_single" +#define NAME_DATASET_CHUNKED2 "dataset_chunked2" +#define NAME_DATASET_CHUNKED2_SINGLE "dataset_chunked2_single" +#define NAME_DATASET_CHUNKED3 "dataset_chunked3" +#define NAME_DATASET_CHUNKED3_SINGLE "dataset_chunked3_single" +#define NAME_DATASET_CHUNKED4 "dataset_chunked4" +#define NAME_DATASET_CHUNKED4_SINGLE "dataset_chunked4_single" +#define NAME_DATASET_COMPACT "dataset_compact" +#define NAME_DATASET_EXTERNAL "dataset_ext" +#define NAME_DATASET_NAMED_DTYPE "dataset_named_dtype" +#define NAME_DATASET_NAMED_DTYPE2 "dataset_named_dtype2" +#define NAME_DATASET_MULTI_OHDR "dataset_multi_ohdr" +#define NAME_DATASET_MULTI_OHDR2 "dataset_multi_ohdr2" +#define NAME_DATASET_VL "dataset_vl" +#define NAME_DATASET_VL2 "dataset_vl2" +#define NAME_DATASET_VL_VL "dataset_vl_vl" +#define NAME_DATASET_VL_VL2 "dataset_vl_vl2" +#define NAME_DATASET_CMPD_VL "dataset_cmpd_vl" +#define NAME_DATASET_SUB_SUB "/g0/g00/g000/dataset_simple" +#define NAME_GROUP_UNCOPIED "/uncopied" +#define NAME_GROUP_EMPTY "/empty" +#define NAME_GROUP_TOP "/g0" +#define NAME_GROUP_TOP2 "/g1" +#define NAME_GROUP_TOP3 "/g2" +#define NAME_GROUP_TOP4 "/g3" +#define NAME_GROUP_SUB "/g0/g00" +#define NAME_GROUP_SUB_2 "/g0/g01" +#define NAME_GROUP_SUB_SUB "/g0/g00/g000" +#define NAME_GROUP_SUB_SUB2 "g000" +#define NAME_GROUP_DATASET "/g0/dataset_simple" +#define NAME_GROUP_LINK "/g_links" +#define NAME_GROUP_LINK2 "/g_links2" +#define NAME_GROUP_LOOP "g_loop" +#define NAME_GROUP_LOOP2 "g_loop2" +#define NAME_GROUP_LOOP3 "g_loop3" +#define NAME_GROUP_REF "ref_grp" +#define NAME_LINK_DATASET "/g_links/dataset_simple" +#define NAME_LINK_HARD "/g_links/hard_link_to_dataset_simple" +#define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple" +#define NAME_LINK_SOFT2 "/g_links2/soft_link_to_dataset_simple" +#define NAME_LINK_EXTERN "/g_links/external_link_to_dataset_simple" +#define NAME_LINK_EXTERN2 "/g_links2/external_link_to_dataset_simple" +#define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere" +#define NAME_LINK_SOFT_DANGLE2 "/g_links2/soft_link_to_nowhere" +#define NAME_LINK_EXTERN_DANGLE "/g_links/external_link_to_nowhere" +#define NAME_LINK_EXTERN_DANGLE2 "/g_links2/external_link_to_nowhere" +#define NAME_OLD_FORMAT "/dset1" + +#define NAME_BUF_SIZE 1024 +#define ATTR_NAME_LEN 80 +#define DIM_SIZE_1 12 +#define DIM_SIZE_2 6 +#define MAX_DIM_SIZE_1 100 +#define MAX_DIM_SIZE_2 80 +#define CHUNK_SIZE_1 5 /* Not an even fraction of dimension sizes, so we test copying partial chunks */ +#define CHUNK_SIZE_2 5 +#define NUM_SUB_GROUPS 20 +#define NUM_WIDE_LOOP_GROUPS 10 +#define NUM_DATASETS 10 + +unsigned num_attributes_g; /* Number of attributes created */ + +/* Table containing object id and object name */ +/* (Used for detecting duplicate objects when comparing groups */ +static struct { + size_t nalloc; /* number of slots allocated */ + size_t nobjs; /* number of objects */ + haddr_t *obj; /* Addresses of objects seen */ +} idtab_g; + +/* Local function prototypes */ +static int +compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, + const void *buf1, const void *buf2, hid_t obj_owner); +static int +compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf); +static int +compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags); + +/*------------------------------------------------------------------------- + * Function: addr_insert + * + * Purpose: Add an address to the table. + * + * Return: void + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static void +addr_insert(H5O_info_t *oi) +{ + size_t n; + + /* Don't add it if the link count is 1 because such an object can only + * be encountered once. */ + if(oi->rc < 2) + return; + + /* Extend the table */ + if(idtab_g.nobjs >= idtab_g.nalloc) { + idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc); + idtab_g.obj = (haddr_t *)HDrealloc(idtab_g.obj, idtab_g.nalloc * sizeof(idtab_g.obj[0])); + } /* end if */ + + /* Insert the entry */ + n = idtab_g.nobjs++; + idtab_g.obj[n] = oi->addr; +} /* end addr_insert() */ + + +/*------------------------------------------------------------------------- + * Function: addr_lookup + * + * Purpose: Check if address has already been encountered + * + * Return: Success: TRUE/FALSE + * + * Failure: (can't fail) + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static H5_ATTR_PURE hbool_t +addr_lookup(H5O_info_t *oi) +{ + size_t n; + + if(oi->rc < 2) return FALSE; /*only one link possible*/ + + for(n = 0; n < idtab_g.nobjs; n++) + if(H5F_addr_eq(idtab_g.obj[n], oi->addr)) + return TRUE; + + return FALSE; +} /* end addr_lookup() */ + + +/*------------------------------------------------------------------------- + * Function: addr_reset + * + * Purpose: Reset the address tracking data structures + * + * Return: void + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static void +addr_reset(void) +{ + if(idtab_g.obj) + HDfree(idtab_g.obj); + idtab_g.obj = NULL; + idtab_g.nalloc = idtab_g.nobjs = 0; +} /* end addr_reset() */ + + +/*------------------------------------------------------------------------- + * Function: attach_ref_attr + * + * Purpose: Create an attribute with object references + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +attach_ref_attr(hid_t file_id, hid_t loc_id) +{ + char dsetname1[] = "dataset1_pointed_by_ref_attr"; + char dsetname2[] = "dataset2_pointed_by_ref_attr"; + hid_t did1 = (-1), did2 = (-1), aid = (-1), sid = (-1), sid_ref = (-1); + hsize_t dims[2] = {2,9}; + hsize_t dims_ref[1] = {2}; + H5R_ref_t ref[2]; + int data1[2][9] = {{1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,18}}; + int data2[2][9] = {{2,2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2,18}}; + + /* creates two simple datasets */ + if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR + if((sid_ref = H5Screate_simple(1, dims_ref, NULL)) < 0) TEST_ERROR + if((did1 = H5Dcreate2(file_id, dsetname1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data1) < 0) TEST_ERROR + if((did2 = H5Dcreate2(file_id, dsetname2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data2) < 0) TEST_ERROR + + /* create an attribute with two object references */ + if(H5Rcreate_object(file_id, dsetname1, &ref[0]) < 0) TEST_ERROR + if(H5Rcreate_object(file_id, dsetname2, &ref[1]) < 0) TEST_ERROR + if((aid = H5Acreate2(loc_id, "obj_ref_attr", H5T_STD_REF, sid_ref, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + if(H5Sclose(sid) < 0) TEST_ERROR + if(H5Sclose(sid_ref) < 0) TEST_ERROR + if(H5Dclose(did1) < 0) TEST_ERROR + if(H5Dclose(did2) < 0) TEST_ERROR + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + H5Sclose(sid_ref); + H5Dclose(did1); + H5Dclose(did2); + H5Aclose(aid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + +/*------------------------------------------------------------------------- + * Function: attach_reg_ref_attr + * + * Purpose: Create an attribute with object references + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Monday, March 5, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +attach_reg_ref_attr(hid_t file_id, hid_t loc_id) +{ + const char dsetnamev[] = "dataset_pointed_by_reg_ref_attr"; + hid_t aid = (-1); + hid_t space_id = (-1); /* dataspace identifiers */ + hid_t spacer_id = (-1); /* dataspace identifiers */ + hid_t dsetv_id = (-1); /*dataset identifiers*/ + hsize_t dims[2] = {2,9}; + hsize_t dimsr[1] = {2}; + int rank = 2; + int rankr =1; + H5R_ref_t ref[2]; + int data[2][9] = {{1,1,2,3,3,4,5,5,999},{1,2,2,3,4,4,5,6,999}}; + hsize_t start[2] = {0, 3}; + hsize_t count[2] = {2, 3}; + hsize_t coord[3][2] = {{0, 0}, {1, 6}, {0, 8}}; + size_t num_points = 3; + + /* create a 2D dataset */ + if((space_id = H5Screate_simple(rank, dims, NULL)) < 0) TEST_ERROR + if((spacer_id = H5Screate_simple(rankr, dimsr, NULL)) < 0) TEST_ERROR + if((dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data) < 0) TEST_ERROR + + /* create reg_ref of block selection */ + if(H5Sselect_hyperslab(space_id,H5S_SELECT_SET,start,NULL,count,NULL) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[0]) < 0) TEST_ERROR + + /* create reg_ref of point selection */ + if(H5Sselect_none(space_id) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[1]) < 0) TEST_ERROR + + /* create reg_ref attribute */ + if((aid = H5Acreate2(loc_id, "reg_ref_attr", H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + /* attach the reg_ref attribute to the dataset itself */ + if(H5Aclose(aid) < 0) TEST_ERROR + if((aid = H5Acreate2(dsetv_id, "reg_ref_attr", H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Awrite(aid, H5T_STD_REF, ref) < 0) TEST_ERROR + + if(H5Sclose(spacer_id) < 0) TEST_ERROR + if(H5Sclose(space_id) < 0) TEST_ERROR + if(H5Dclose(dsetv_id) < 0) TEST_ERROR + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(spacer_id); + H5Sclose(space_id); + H5Dclose(dsetv_id); + H5Aclose(aid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + + +/*------------------------------------------------------------------------- + * Function: create_reg_ref_dataset + * + * Purpose: Create a dataset with region references + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Friday, August 4, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +create_reg_ref_dataset(hid_t file_id, hid_t loc_id) +{ + const char dsetnamev[] = "dataset_pointed_by_ref_dset"; + const char dsetnamer[] = "dataset_with_reg_ref"; + const char dsetnamer1[] = "compact_dataset_with_reg_ref"; + const char dsetnamer2[] = "compressed_dataset_with_reg_ref"; + hid_t space_id = (-1); /* dataspace identifiers */ + hid_t spacer_id = (-1); + hid_t dsetv_id = (-1); /*dataset identifiers*/ + hid_t dsetr_id = (-1); + hsize_t dims[2] = {2,9}; + hsize_t dimsr[1] = {2}; + int rank = 2; + int rankr =1; + hsize_t chunk_size=1; + H5R_ref_t ref[2]; + int data[2][9] = {{1,1,2,3,3,4,5,5,6},{1,2,2,3,4,4,5,6,6}}; + hsize_t start[2]; + hsize_t count[2]; + hsize_t coord[3][2] = {{0, 0}, {1, 6}, {0, 8}}; + size_t num_points = 3; + hid_t pid = (-1); + + if((space_id = H5Screate_simple(rank, dims, NULL)) < 0) TEST_ERROR + if((spacer_id = H5Screate_simple(rankr, dimsr, NULL)) < 0) TEST_ERROR + if((dsetv_id = H5Dcreate2(file_id, dsetnamev, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(dsetv_id, H5T_NATIVE_INT, H5S_ALL , H5S_ALL, H5P_DEFAULT,data) < 0) TEST_ERROR + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer, H5T_STD_REF, spacer_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + start[0] = 0; + start[1] = 3; + count[0] = 2; + count[1] = 3; + if(H5Sselect_hyperslab(space_id,H5S_SELECT_SET,start,NULL,count,NULL) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[0]) < 0) TEST_ERROR + if(H5Sselect_none(space_id) < 0) TEST_ERROR + if(H5Sselect_elements(space_id, H5S_SELECT_SET, num_points, (const hsize_t *)coord) < 0) TEST_ERROR + if(H5Rcreate_region(file_id, dsetnamev, space_id, &ref[1]) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + /* create and set compact plist */ + if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR + if(H5Pset_layout(pid, H5D_COMPACT) < 0) TEST_ERROR + + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer1, H5T_STD_REF, spacer_id, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Pclose(pid) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + /* create and set comp & chunk plist */ + if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR + if(H5Pset_chunk(pid, 1, &chunk_size) < 0) TEST_ERROR + if(H5Pset_deflate(pid, 9) < 0) TEST_ERROR + + if((dsetr_id = H5Dcreate2(loc_id, dsetnamer2, H5T_STD_REF, spacer_id, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Pclose(pid) < 0) TEST_ERROR + if(H5Dwrite(dsetr_id, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT,ref) < 0) TEST_ERROR + if(H5Dclose(dsetr_id) < 0) TEST_ERROR + + if(H5Sclose(space_id) < 0) TEST_ERROR + if(H5Sclose(spacer_id) < 0) TEST_ERROR + if(H5Dclose(dsetv_id) < 0) TEST_ERROR + if(H5Rdestroy(&ref[0]) < 0) TEST_ERROR + if(H5Rdestroy(&ref[1]) < 0) TEST_ERROR + + return 0; + + +error: + H5E_BEGIN_TRY { + H5Sclose(space_id); + H5Sclose(spacer_id); + H5Dclose(dsetr_id); + H5Dclose(dsetv_id); + H5Pclose(pid); + H5Rdestroy(&ref[0]); + H5Rdestroy(&ref[1]); + } H5E_END_TRY; + + return(-1); +} + +/*------------------------------------------------------------------------- + * Function: test_copy_attach_attributes + * + * Purpose: Attach NUM_ATTRIBUTES attributes to the object to be copied + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Friday, September 30, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_attach_attributes(hid_t loc_id, hid_t type_id) +{ + hid_t aid = -1, sid = -1; + char attr_name[ATTR_NAME_LEN]; + int attr_data[2]; + hsize_t dim1 = 2; + hid_t acpl = -1; + unsigned u; + int ret_value = -1; + + if((sid = H5Screate_simple(1, &dim1, NULL)) < 0 ) + goto done; + + /* Create attribute creation plist */ + if((acpl = H5Pcreate(H5P_ATTRIBUTE_CREATE)) < 0) + goto done; + + for(u = 0; u < num_attributes_g; u++) { + HDsprintf(attr_name, "%u attr", u); + + /* Set attribute data */ + attr_data[0] = (int)(100 * u); + attr_data[1] = (int)(200 * u); + + /* Set attribute character set (alternate) */ + if(u % 2) { + if(H5Pset_char_encoding(acpl, H5T_CSET_ASCII) < 0) + goto done; + } /* end if */ + else + if(H5Pset_char_encoding(acpl, H5T_CSET_UTF8) < 0) + goto done; + + if((aid = H5Acreate2(loc_id, attr_name, type_id, sid, acpl, H5P_DEFAULT)) < 0) + goto done; + + if(H5Awrite(aid, H5T_NATIVE_INT, attr_data) < 0) + goto done; + + if(aid > 0) + H5Aclose(aid); + + aid = -1; + } + + ret_value = 0; + +done: + if(sid > 0) + H5Sclose(sid); + if(aid > 0) + H5Aclose(aid); + if(acpl > 0) + H5Pclose(acpl); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: compare_attribute + * + * Purpose: Compare two attributes to check that they are equal + * + * Return: TRUE if attributes are equal/FALSE if they are different + * + * Programmer: Peter Cao + * Saturday, December 17, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_attribute(hid_t aid, hid_t aid2, hid_t pid, const void *wbuf, hid_t obj_owner) +{ + hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + size_t elmt_size; /* Size of datatype */ + htri_t is_committed; /* If the datatype is committed */ + htri_t is_committed2; /* If the datatype is committed */ + H5A_info_t ainfo; /* Attribute info */ + H5A_info_t ainfo2; /* Attribute info */ + hssize_t nelmts; /* # of elements in dataspace */ + void *rbuf = NULL; /* Buffer for reading raw data */ + void *rbuf2 = NULL; /* Buffer for reading raw data */ + + /* Check the character sets are equal */ + if(H5Aget_info(aid, &ainfo) < 0) TEST_ERROR + if(H5Aget_info(aid2, &ainfo2) < 0) TEST_ERROR + if(ainfo.cset != ainfo2.cset) TEST_ERROR + + /* Check the creation orders are equal (if appropriate) */ + if(ainfo.corder_valid != ainfo2.corder_valid) TEST_ERROR + if(ainfo.corder_valid) + if(ainfo.corder != ainfo2.corder) TEST_ERROR + + /* Check the datatypes are equal */ + + /* Open the datatype for the source attribute */ + if((tid = H5Aget_type(aid)) < 0) TEST_ERROR + + /* Open the datatype for the destination attribute */ + if((tid2 = H5Aget_type(aid2)) < 0) TEST_ERROR + + /* Check that both datatypes are committed/not committed */ + if((is_committed = H5Tcommitted(tid)) < 0) TEST_ERROR + if((is_committed2 = H5Tcommitted(tid2)) < 0) TEST_ERROR + if(is_committed != is_committed2) TEST_ERROR + + /* Compare the datatypes */ + if(H5Tequal(tid, tid2) != TRUE) TEST_ERROR + + /* Determine the size of datatype (for later) */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + /* Check the dataspaces are equal */ + + /* Open the dataspace for the source attribute */ + if((sid = H5Aget_space(aid)) < 0) TEST_ERROR + + /* Open the dataspace for the destination attribute */ + if((sid2 = H5Aget_space(aid2)) < 0) TEST_ERROR + + /* Compare the dataspaces */ + if(H5Sextent_equal(sid, sid2) != TRUE) TEST_ERROR + + /* Determine the number of elements in dataspace (for later) */ + if((nelmts = H5Sget_simple_extent_npoints(sid2)) < 0) TEST_ERROR + + /* Check the raw data is equal */ + + /* Allocate & initialize space for the raw data buffers */ + if((rbuf = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + if((rbuf2 = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + + /* Read data from the source attribute */ + if(H5Aread(aid, tid, rbuf) < 0) TEST_ERROR + + /* Read data from the destination attribute */ + if(H5Aread(aid2, tid2, rbuf2) < 0) TEST_ERROR + + /* Check raw data read in against data written out */ + if(wbuf) { + if(!compare_data(aid, (hid_t)0, pid, tid, (size_t)nelmts, wbuf, rbuf, obj_owner)) TEST_ERROR + if(!compare_data(aid2, (hid_t)0, pid, tid2, (size_t)nelmts, wbuf, rbuf2, obj_owner)) TEST_ERROR + } /* end if */ + /* Don't have written data, just compare data between the two attributes */ + else + if(!compare_data(aid, aid2, pid, tid, (size_t)nelmts, rbuf, rbuf2, obj_owner)) TEST_ERROR + + /* Reclaim vlen data, if necessary */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE || H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE || H5Tdetect_class(tid2, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Release raw data buffers */ + HDfree(rbuf); + rbuf = NULL; + HDfree(rbuf2); + rbuf2 = NULL; + + /* close the source dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + + /* close the destination dataspace */ + if(H5Sclose(sid2) < 0) TEST_ERROR + + /* close the source datatype */ + if(H5Tclose(tid) < 0) TEST_ERROR + + /* close the destination datatype */ + if(H5Tclose(tid2) < 0) TEST_ERROR + + return TRUE; + +error: + if(rbuf) + HDfree(rbuf); + if(rbuf2) + HDfree(rbuf2); + H5E_BEGIN_TRY { + H5Sclose(sid2); + H5Sclose(sid); + H5Tclose(tid2); + H5Tclose(tid); + } H5E_END_TRY; + return FALSE; +} /* end compare_attribute() */ + + +/*------------------------------------------------------------------------- + * Function: compare_std_attributes + * + * Purpose: Compare "standard" attributes on two objects to check that they are equal + * + * Return: TRUE if objects have same attributes/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, October 31, 2005 + * + * Note: This isn't very general, the attributes are assumed to be + * those written in test_copy_attach_attributes(). + * + *------------------------------------------------------------------------- + */ +static int +compare_std_attributes(hid_t oid, hid_t oid2, hid_t pid) +{ + hid_t aid = -1, aid2 = -1; /* Attribute IDs */ + H5O_info_t oinfo1, oinfo2; /* Object info */ + unsigned cpy_flags; /* Object copy flags */ + + /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ + if(pid != H5P_DEFAULT) { + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + } /* end if */ + else + cpy_flags = 0; + + /* Check the number of attributes on source dataset */ + if(H5Oget_info2(oid, &oinfo1, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + + /* Check the number of attributes on destination dataset */ + if(H5Oget_info2(oid2, &oinfo2, H5O_INFO_NUM_ATTRS) < 0) TEST_ERROR + + if(cpy_flags & H5O_COPY_WITHOUT_ATTR_FLAG) { + /* Check that the destination has no attributes */ + if(oinfo2.num_attrs != 0) TEST_ERROR + } /* end if */ + else { + char attr_name[ATTR_NAME_LEN]; /* Attribute name */ + unsigned i; /* Local index variable */ + + /* Compare the number of attributes */ + if(oinfo1.num_attrs != oinfo2.num_attrs) TEST_ERROR + + /* Check the attributes are equal */ + for(i = 0; i < (unsigned)oinfo1.num_attrs; i++) { + if((aid = H5Aopen_by_idx(oid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)i, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Aget_name(aid, (size_t)ATTR_NAME_LEN, attr_name) < 0) TEST_ERROR + + if((aid2 = H5Aopen(oid2, attr_name, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check the attributes are equal */ + if(!compare_attribute(aid, aid2, pid, NULL, oid)) TEST_ERROR + + /* Close the attributes */ + if(H5Aclose(aid) < 0) TEST_ERROR + if(H5Aclose(aid2) < 0) TEST_ERROR + } /* end for */ + } /* end if */ + + /* Objects should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + H5Aclose(aid2); + H5Aclose(aid); + } H5E_END_TRY; + return FALSE; +} /* end compare_std_attributes() */ + + +/*------------------------------------------------------------------------- + * Function: compare_data + * + * Purpose: Compare two buffers of data to check that they are equal + * + * Return: TRUE if buffer are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, + const void *buf1, const void *buf2, hid_t obj_owner) +{ + size_t elmt_size; /* Size of an element */ + + /* Check size of each element */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + /* If the type is a compound containing a vlen, loop over all elements for + * each compound member. Compounds containing reference are not supported + * yet. */ + if((H5Tget_class(tid) == H5T_COMPOUND) + && (H5Tdetect_class(tid, H5T_VLEN) == TRUE)) { + hid_t memb_id; /* Member id */ + const uint8_t *memb1; /* Pointer to current member */ + const uint8_t *memb2; /* Pointer to current member */ + int nmembs; /* Number of members */ + size_t memb_off; /* Member offset */ + size_t memb_size; /* Member size */ + unsigned memb_idx; /* Member index */ + size_t elmt; /* Current element */ + + /* Get number of members in compound */ + if((nmembs = H5Tget_nmembers(tid)) < 0) TEST_ERROR + + /* Loop over members */ + for(memb_idx=0; memb_idx<(unsigned)nmembs; memb_idx++) { + /* Get member offset. Note that we cannot check for an error here. + */ + memb_off = H5Tget_member_offset(tid, memb_idx); + + /* Get member id */ + if((memb_id = H5Tget_member_type(tid, memb_idx)) < 0) TEST_ERROR + + /* Get member size */ + if((memb_size = H5Tget_size(memb_id)) == 0) TEST_ERROR + + /* Set up pointers to member in the first element */ + memb1 = (const uint8_t *)buf1 + memb_off; + memb2 = (const uint8_t *)buf2 + memb_off; + + /* Check if this member contains (or is) a vlen */ + if(H5Tget_class(memb_id) == H5T_VLEN) { + hid_t base_id; /* vlen base type id */ + + /* Get base type of vlen datatype */ + if((base_id = H5Tget_super(memb_id)) < 0) TEST_ERROR + + /* Iterate over all elements, recursively calling this function + * for each */ + for(elmt=0; elmt<nelmts; elmt++) { + /* Check vlen lengths */ + if(((const hvl_t *)((const void *)memb1))->len + != ((const hvl_t *)((const void *)memb2))->len) + TEST_ERROR + + /* Check vlen data */ + if(!compare_data(parent1, parent2, pid, base_id, + ((const hvl_t *)((const void *)memb1))->len, + ((const hvl_t *)((const void *)memb1))->p, + ((const hvl_t *)((const void *)memb2))->p, obj_owner)) + TEST_ERROR + + /* Update member pointers */ + memb1 += elmt_size; + memb2 += elmt_size; + } /* end for */ + } else { + /* vlens cannot currently be nested below the top layer of a + * compound */ + HDassert(H5Tdetect_class(memb_id, H5T_VLEN) == FALSE); + + /* Iterate over all elements, calling memcmp() for each */ + for(elmt=0; elmt<nelmts; elmt++) { + if(HDmemcmp(memb1, memb2, memb_size)) + TEST_ERROR + + /* Update member pointers */ + memb1 += elmt_size; + memb2 += elmt_size; + } /* end for */ + } /* end else */ + } /* end for */ + } else if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { + const hvl_t *vl_buf1, *vl_buf2; /* Aliases for buffers to compare */ + hid_t base_tid; /* Base type of vlen datatype */ + size_t u; /* Local index variable */ + + /* Check for "simple" vlen datatype */ + if(H5Tget_class(tid) != H5T_VLEN) TEST_ERROR + + /* Get base type of vlen datatype */ + if((base_tid = H5Tget_super(tid)) < 0) TEST_ERROR + + /* Loop over elements in buffers */ + vl_buf1 = (const hvl_t *)buf1; + vl_buf2 = (const hvl_t *)buf2; + for(u = 0; u < nelmts; u++, vl_buf1++, vl_buf2++) { + /* Check vlen lengths */ + if(vl_buf1->len != vl_buf2->len) TEST_ERROR + + /* Check vlen data */ + if(!compare_data(parent1, parent2, pid, base_tid, vl_buf1->len, vl_buf1->p, vl_buf2->p, obj_owner)) TEST_ERROR + } /* end for */ + + if(H5Tclose(base_tid) < 0) TEST_ERROR + } /* end if */ + else if(H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) { + size_t u; /* Local index variable */ + + /* Check for "simple" reference datatype */ + if(H5Tget_class(tid) != H5T_REFERENCE) TEST_ERROR + + /* Check for object or region reference */ + if(H5Tequal(tid, H5T_STD_REF) > 0) { + const H5R_ref_t *ref_buf1, *ref_buf2; /* Aliases for buffers to compare */ + + /* Loop over elements in buffers */ + ref_buf1 = (const H5R_ref_t *)buf1; + ref_buf2 = (const H5R_ref_t *)buf2; + for(u = 0; u < nelmts; u++, ref_buf1++, ref_buf2++) { + hid_t obj1_id, obj2_id; /* IDs for objects referenced */ + H5O_type_t obj1_type, obj2_type; /* Types of objects referenced */ + + /* Check for types of objects handled */ + if(H5Rget_obj_type3(ref_buf1, H5P_DEFAULT, &obj1_type) < 0) TEST_ERROR + if(H5Rget_obj_type3(ref_buf2, H5P_DEFAULT, &obj2_type) < 0) TEST_ERROR + if(obj1_type != obj2_type) TEST_ERROR + + /* Open referenced objects */ + if((obj1_id = H5Ropen_object(ref_buf1, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if((obj2_id = H5Ropen_object(ref_buf2, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* break the infinite loop when the ref_object points to itself */ + if(obj_owner > 0) { + H5O_info_t oinfo1, oinfo2; + + if(H5Oget_info2(obj_owner, &oinfo1, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5Oget_info2(obj1_id, &oinfo2, H5O_INFO_BASIC) < 0) TEST_ERROR + if(H5F_addr_eq(oinfo1.addr, oinfo2.addr)) { + if(H5Oclose(obj1_id) < 0) TEST_ERROR + if(H5Oclose(obj2_id) < 0) TEST_ERROR + return TRUE; + } + } + + /* Check for types of objects handled */ + switch(obj1_type) { + case H5O_TYPE_DATASET: + if(compare_datasets(obj1_id, obj2_id, pid, NULL) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_GROUP: + if(compare_groups(obj1_id, obj2_id, pid, -1, 0) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_NAMED_DATATYPE: + if(H5Tequal(obj1_id, obj2_id) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_MAP: + /* Maps not supported in native VOL connector */ + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + TEST_ERROR + } /* end switch */ + + /* Close objects */ + if(H5Oclose(obj1_id) < 0) TEST_ERROR + if(H5Oclose(obj2_id) < 0) TEST_ERROR + + if(H5Rget_type(ref_buf1) == H5R_DATASET_REGION2) { + hid_t obj1_sid, obj2_sid; /* Dataspace IDs for objects referenced */ + + /* Get regions for referenced datasets */ + if((obj1_sid = H5Ropen_region(ref_buf1, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if((obj2_sid = H5Ropen_region(ref_buf2, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Check if dataspaces are the same shape */ + if(H5Sselect_shape_same(obj1_sid, obj2_sid) < 0) TEST_ERROR + + /* Close dataspaces */ + if(H5Sclose(obj1_sid) < 0) TEST_ERROR + if(H5Sclose(obj2_sid) < 0) TEST_ERROR + } /* end if */ + } /* end for */ + } /* end if */ + else + TEST_ERROR + } /* end else */ + else + if(HDmemcmp(buf1, buf2, (elmt_size * nelmts))) TEST_ERROR + + /* Data should be the same. :-) */ + return TRUE; + +error: + return FALSE; +} /* end compare_data() */ + + +/*------------------------------------------------------------------------- + * Function: compare_datasets + * + * Purpose: Compare two datasets to check that they are equal + * + * Return: TRUE if datasets are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Tuesday, October 25, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf) +{ + hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + hid_t dcpl = -1, dcpl2 = -1; /* Dataset creation property list IDs */ + size_t elmt_size; /* Size of datatype */ + htri_t is_committed; /* If the datatype is committed */ + htri_t is_committed2; /* If the datatype is committed */ + int nfilters; /* Number of filters applied to dataset */ + hssize_t nelmts; /* # of elements in dataspace */ + void *rbuf = NULL; /* Buffer for reading raw data */ + void *rbuf2 = NULL; /* Buffer for reading raw data */ + H5D_space_status_t space_status; /* Dataset's raw dataspace status */ + H5D_space_status_t space_status2; /* Dataset's raw dataspace status */ + + /* Check the datatypes are equal */ + + /* Open the datatype for the source dataset */ + if((tid = H5Dget_type(did)) < 0) TEST_ERROR + + /* Open the datatype for the destination dataset */ + if((tid2 = H5Dget_type(did2)) < 0) TEST_ERROR + + /* Check that both datatypes are committed/not committed */ + if((is_committed = H5Tcommitted(tid)) < 0) TEST_ERROR + if((is_committed2 = H5Tcommitted(tid2)) < 0) TEST_ERROR + if(is_committed != is_committed2) TEST_ERROR + + /* Compare the datatypes */ + if(H5Tequal(tid, tid2) != TRUE) TEST_ERROR + + /* Determine the size of datatype (for later) */ + if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR + + + /* Check the dataspaces are equal */ + + /* Open the dataspace for the source dataset */ + if((sid = H5Dget_space(did)) < 0) TEST_ERROR + + /* Open the dataspace for the destination dataset */ + if((sid2 = H5Dget_space(did2)) < 0) TEST_ERROR + + /* Compare the dataspaces */ + if(H5Sextent_equal(sid, sid2) != TRUE) TEST_ERROR + + /* Determine the number of elements in dataspace (for later) */ + if((nelmts = H5Sget_simple_extent_npoints(sid)) < 0) TEST_ERROR + + + /* Check the dataset creation property lists are equal */ + + /* Open the dataset creation property list for the source dataset */ + if((dcpl = H5Dget_create_plist(did)) < 0) TEST_ERROR + + /* Open the dataset creation property list for the destination dataset */ + if((dcpl2 = H5Dget_create_plist(did2)) < 0) TEST_ERROR + + /* Compare the rest of the dataset creation property lists */ + if(H5Pequal(dcpl, dcpl2) != TRUE) TEST_ERROR + + /* Get the number of filters on dataset (for later) */ + if((nfilters = H5Pget_nfilters(dcpl)) < 0) TEST_ERROR + + /* close the source dataset creation property list */ + if(H5Pclose(dcpl) < 0) TEST_ERROR + + /* close the destination dataset creation property list */ + if(H5Pclose(dcpl2) < 0) TEST_ERROR + + + /* Check the allocated storage is the same */ + + /* Check that the space allocation status is the same */ + if(H5Dget_space_status(did, &space_status) < 0) TEST_ERROR + if(H5Dget_space_status(did2, &space_status2) < 0) TEST_ERROR + if(space_status != space_status2) TEST_ERROR + + /* Check that the space used is the same */ + /* (Don't check if the dataset is filtered (i.e. compressed, etc.) and + * the datatype is VLEN, since the addresses for the vlen + * data in each dataset will (probably) be different and the storage + * size will thus vary) + */ + if(!(nfilters > 0 && (H5Tdetect_class(tid, H5T_VLEN) || + (H5Tdetect_class(tid, H5T_REFERENCE) && H5Tequal(tid, H5T_STD_REF))))) { + hsize_t storage_size = H5Dget_storage_size(did); /* Dataset's raw data storage size */ + hsize_t storage_size2 = H5Dget_storage_size(did2); /* 2nd Dataset's raw data storage size */ + + if(storage_size != storage_size2) TEST_ERROR + } /* end if */ + + /* Check the raw data is equal */ + + /* Allocate & initialize space for the raw data buffers */ + if((rbuf = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + if((rbuf2 = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR + + /* Read data from datasets */ + if(H5Dread(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Check raw data read in against data written out */ + if(wbuf) { + if(!compare_data(did, (hid_t)0, pid, tid, (size_t)nelmts, wbuf, rbuf, did)) TEST_ERROR + if(!compare_data(did2, (hid_t)0, pid, tid2, (size_t)nelmts, wbuf, rbuf2, did2)) TEST_ERROR + } /* end if */ + /* Don't have written data, just compare data between the two datasets */ + else + if(!compare_data(did, did2, pid, tid, (size_t)nelmts, rbuf, rbuf2, did)) TEST_ERROR + + /* Reclaim vlen data, if necessary */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE || H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE || H5Tdetect_class(tid2, H5T_REFERENCE) == TRUE) + if(H5Treclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR + + /* Release raw data buffers */ + HDfree(rbuf); + rbuf = NULL; + HDfree(rbuf2); + rbuf2 = NULL; + + /* close the source dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + + /* close the destination dataspace */ + if(H5Sclose(sid2) < 0) TEST_ERROR + + /* close the source datatype */ + if(H5Tclose(tid) < 0) TEST_ERROR + + /* close the destination datatype */ + if(H5Tclose(tid2) < 0) TEST_ERROR + + + /* Check if the attributes are equal */ + if(compare_std_attributes(did, did2, pid) != TRUE) TEST_ERROR + + + /* Datasets should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + if(rbuf) + HDfree(rbuf); + if(rbuf2) + HDfree(rbuf2); + H5Pclose(dcpl2); + H5Pclose(dcpl); + H5Sclose(sid2); + H5Sclose(sid); + H5Tclose(tid2); + H5Tclose(tid); + } H5E_END_TRY; + return FALSE; +} /* end compare_datasets() */ + + +/*------------------------------------------------------------------------- + * Function: compare_groups + * + * Purpose: Compare two groups to check that they are "equal" + * + * Return: TRUE if group are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, October 31, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags) +{ + H5G_info_t ginfo; /* Group info struct */ + H5G_info_t ginfo2; /* Group info struct */ + hsize_t idx; /* Index over the objects in group */ + unsigned cpy_flags; /* Object copy flags */ + + /* Retrieve the object copy flags from the property list, if it's non-DEFAULT */ + if(pid != H5P_DEFAULT) { + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + } /* end if */ + else + cpy_flags = 0; + + /* Check if both groups have the same # of objects */ + if(H5Gget_info(gid, &ginfo) < 0) TEST_ERROR + if(H5Gget_info(gid2, &ginfo2) < 0) TEST_ERROR + if((cpy_flags & H5O_COPY_SHALLOW_HIERARCHY_FLAG) && depth == 0) { + if(ginfo2.nlinks != 0) TEST_ERROR + } /* end if */ + else { + if(ginfo.nlinks != ginfo2.nlinks) TEST_ERROR + } /* end if */ + + /* Check contents of groups */ + if(ginfo2.nlinks > 0) { + char objname[NAME_BUF_SIZE]; /* Name of object in group */ + char objname2[NAME_BUF_SIZE]; /* Name of object in group */ + H5L_info_t linfo; /* Link information */ + H5L_info_t linfo2; /* Link information */ + + /* Loop over contents of groups */ + for(idx = 0; idx < ginfo.nlinks; idx++) { + /* Check name of objects */ + if(H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, idx, objname, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_name_by_idx(gid2, ".", H5_INDEX_NAME, H5_ITER_INC, idx, objname2, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(HDstrcmp(objname, objname2)) TEST_ERROR + + /* Get link info */ + if(H5Lget_info(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_info(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.type != linfo2.type) TEST_ERROR + + /* Extra checks for "real" objects */ + if(linfo.type == H5L_TYPE_HARD) { + hid_t oid, oid2; /* IDs of objects within group */ + H5O_info_t oinfo, oinfo2; /* Object info */ + + /* Compare some pieces of the object info */ + if(H5Oget_info_by_name2(gid, objname, &oinfo, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Oget_info_by_name2(gid2, objname2, &oinfo2, H5O_INFO_BASIC|H5O_INFO_HDR, H5P_DEFAULT) < 0) TEST_ERROR + + if(oinfo.type != oinfo2.type) TEST_ERROR + if(oinfo.rc != oinfo2.rc) TEST_ERROR + + /* If NULL messages are preserved, the number of messages + * should be the same in the destination. + * Otherwise, it should simply be true that the number + * of messages hasn't increased. + */ + if(H5O_COPY_PRESERVE_NULL_FLAG & copy_flags) { + if(oinfo.hdr.nmesgs != oinfo2.hdr.nmesgs) + ; + else + if(oinfo.hdr.nmesgs < oinfo2.hdr.nmesgs) TEST_ERROR + } + + /* Check for object already having been compared */ + if(addr_lookup(&oinfo)) + continue; + else + addr_insert(&oinfo); + + /* Open objects */ + if((oid = H5Oopen(gid, objname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((oid2 = H5Oopen(gid2, objname2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Compare objects within group */ + switch(oinfo.type) { + case H5O_TYPE_GROUP: + /* Compare groups */ + if(compare_groups(oid, oid2, pid, depth - 1, copy_flags) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_DATASET: + /* Compare datasets */ + if(compare_datasets(oid, oid2, pid, NULL) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_NAMED_DATATYPE: + /* Compare datatypes */ + if(H5Tequal(oid, oid2) != TRUE) TEST_ERROR + break; + + case H5O_TYPE_MAP: + HDassert(0 && "maps not supported in native VOL connector"); + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + HDassert(0 && "Unknown type of object"); + break; + } /* end switch */ + + /* Close objects */ + if(H5Oclose(oid) < 0) TEST_ERROR + if(H5Oclose(oid2) < 0) TEST_ERROR + } /* end if */ + else { + /* Check that both links are the same size */ + if(linfo.u.val_size != linfo2.u.val_size) TEST_ERROR + + /* Compare link values */ + if(linfo.type == H5L_TYPE_SOFT || + (linfo.type >= H5L_TYPE_UD_MIN && linfo.type <= H5L_TYPE_MAX)) { + char linkval[NAME_BUF_SIZE]; /* Link value */ + char linkval2[NAME_BUF_SIZE]; /* Link value */ + + /* Get link values */ + HDassert(linfo.u.val_size <= NAME_BUF_SIZE); + if(H5Lget_val(gid, objname, linkval, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_val(gid2, objname2, linkval2, (size_t)NAME_BUF_SIZE, H5P_DEFAULT) < 0) TEST_ERROR + + /* Compare link data */ + if(HDmemcmp(linkval, linkval2, linfo.u.val_size)) TEST_ERROR + } /* end else-if */ + else { +HDassert(0 && "Unknown type of link"); + } /* end else */ + } /* end else */ + } /* end for */ + } /* end if */ + + /* Check if the attributes are equal */ + if(compare_std_attributes(gid, gid2, pid) != TRUE) TEST_ERROR + + /* Groups should be the same. :-) */ + return TRUE; + +error: + H5E_BEGIN_TRY { + } H5E_END_TRY; + return FALSE; +} /* end compare_groups() */ + +/*------------------------------------------------------------------------- + * Function: test_copy_option + * + * Purpose: Create a group in SRC file and copy it to DST file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Peter Cao + * March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_option(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, + unsigned flag, hbool_t crt_intermediate_grp, const char* test_desciption) +{ + hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */ + hid_t sid = -1; /* Dataspace ID */ + hid_t did = -1; /* Dataset ID */ + hid_t gid=-1, gid2=-1, gid_ref=-1; /* Group IDs */ + hid_t gid_sub=-1, gid_sub_sub=-1; /* Sub-group ID */ + hid_t pid=-1, lcpl_id=-1; /* Property IDs */ + unsigned cpy_flags; /* Object copy flags */ + int depth = -1; /* Copy depth */ + hsize_t dim2d[2]; + int buf[DIM_SIZE_1][DIM_SIZE_2]; + int i, j; + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING(test_desciption); + + /* set initial data values */ + for (i=0; i<DIM_SIZE_1; i++) + for (j=0; j<DIM_SIZE_2; j++) + buf[i][j] = 10000 + 100*i+j; + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename); + h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename); + + /* Reset file address checking info */ + addr_reset(); + + /* create source file */ + if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR + + /* create group at the SRC file */ + if((gid = H5Gcreate2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* attach attributes to the group */ + if(test_copy_attach_attributes(gid, H5T_NATIVE_INT) < 0) TEST_ERROR + + /* Set dataspace dimensions */ + dim2d[0]=DIM_SIZE_1; + dim2d[1]=DIM_SIZE_2; + + /* create dataspace */ + if((sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR + + /* add a dataset to the top group */ + if((did = H5Dcreate2(gid, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* create a sub-group */ + if((gid_sub = H5Gcreate2(fid_src, NAME_GROUP_SUB, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* add a dataset to the sub group */ + if((did = H5Dcreate2(gid_sub, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* create sub-sub-group */ + if((gid_sub_sub = H5Gcreate2(gid_sub, NAME_GROUP_SUB_SUB2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* add a dataset to the sub sub group */ + if((did = H5Dcreate2(gid_sub_sub, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + + /* close dataset */ + if(H5Dclose(did) < 0) TEST_ERROR + + /* close dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + + if(H5Gclose(gid_sub_sub) < 0) TEST_ERROR + + if(H5Gclose(gid_sub) < 0) TEST_ERROR + + /* close the group */ + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) { + /* Create group to copy */ + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft(NAME_DATASET_SUB_SUB, fid_src, NAME_LINK_SOFT, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Create group to compare with */ + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Lcreate_hard(fid_src, NAME_DATASET_SUB_SUB, H5L_SAME_LOC, NAME_LINK_SOFT2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Lcreate_soft("nowhere", fid_src, NAME_LINK_SOFT_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + } /* end if */ + + if((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0) { + char ext_filename[NAME_BUF_SIZE]; + + h5_fixname(FILENAME[2], src_fapl, ext_filename, sizeof ext_filename); + + /* Create the external file and dataset */ + if((fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR + if((sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR + if((did = H5Dcreate2(fid_ext, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + if(H5Fclose(fid_ext) < 0) TEST_ERROR + + /* Create group to copy */ + if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) { + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + } /* end if */ + else + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Lcreate_external(ext_filename, NAME_DATASET_SIMPLE, fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create group to compare with */ + if(!(flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG)) { + if((gid = H5Gcreate2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + } /* end if */ + else + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) TEST_ERROR + if((did = H5Dcreate2(fid_src, NAME_LINK_EXTERN2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR + if(H5Lcreate_external("no_file", "no_object", fid_src, NAME_LINK_EXTERN_DANGLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close dataspace */ + if(H5Sclose(sid) < 0) TEST_ERROR + } /* end if */ + + if((flag & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) { + if((gid_ref = H5Gcreate2(fid_src, NAME_GROUP_REF, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* create an attribute of new object references */ + if(attach_ref_attr(fid_src, gid_ref) < 0) TEST_ERROR + + /* create an attribute of region references */ + if(attach_reg_ref_attr(fid_src, gid_ref) < 0) TEST_ERROR + + /* create a dataset of region references */ + if(create_reg_ref_dataset(fid_src, gid_ref) < 0) TEST_ERROR + + /* Close group holding reference objects */ + if(H5Gclose(gid_ref) < 0) TEST_ERROR + } /* end if */ + + /* close the SRC file */ + if(H5Fclose(fid_src) < 0) TEST_ERROR + + /* open the source file with read-only */ + /* (except when expanding soft links */ + if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) { + if((fid_src = H5Fopen(src_filename, H5F_ACC_RDWR, src_fapl)) < 0) TEST_ERROR + } /* end if */ + else + if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR + + /* create destination file */ + if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR + + /* Create an uncopied object in destination file so that addresses in source and destination + files aren't the same */ + if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* create property to pass copy options */ + if((pid = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR + + /* set options for object copy */ + if(H5Pset_copy_object(pid, flag) < 0) TEST_ERROR + + /* Verify object copy flags */ + if(H5Pget_copy_object(pid, &cpy_flags) < 0) TEST_ERROR + if(cpy_flags != flag) TEST_ERROR + + /* copy the group from SRC to DST */ + if(crt_intermediate_grp) { + /* Create link creation plist to pass in intermediate group creation */ + if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR + + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, "/new_g0/new_g00", pid, lcpl_id) < 0) TEST_ERROR + + if(H5Pclose(lcpl_id) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, "/new_g0/new_g00", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + } else if(((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + || ((flag & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0)) { + if(H5Ocopy(fid_src, NAME_GROUP_LINK, fid_dst, NAME_GROUP_LINK, pid, H5P_DEFAULT) < 0) TEST_ERROR + + if((flag & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + /* Unlink dataset to copy from original location */ + /* (So group comparison works properly) */ + if(H5Ldelete(fid_src, NAME_DATASET_SUB_SUB, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_LINK2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_LINK, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + } else if(flag & (H5O_COPY_WITHOUT_ATTR_FLAG | H5O_COPY_PRESERVE_NULL_FLAG)) { + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + } else if(flag & H5O_COPY_SHALLOW_HIERARCHY_FLAG) { + if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Set the copy depth */ + depth = 1; + } else if((flag & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) { + if(H5Ocopy(fid_src, NAME_GROUP_REF, fid_dst, NAME_GROUP_REF, pid, H5P_DEFAULT) < 0) TEST_ERROR + + /* open the group for copy */ + if((gid = H5Gopen2(fid_src, NAME_GROUP_REF, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* open the destination group */ + if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_REF, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + } else { + /* Unknown flag */ + TEST_ERROR + } /* end else */ + + /* Check if the groups are equal */ + if(compare_groups(gid, gid2, pid, depth, flag) != TRUE) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* close the SRC file */ + if(H5Fclose(fid_src) < 0) TEST_ERROR + + /* close the DST file */ + if(H5Fclose(fid_dst) < 0) TEST_ERROR + + /* close properties */ + if(H5Pclose(pid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(lcpl_id); + H5Pclose(pid); + H5Sclose(sid); + H5Dclose(did); + H5Gclose(gid_ref); + H5Gclose(gid_sub); + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + H5Fclose(fid_ext); + } H5E_END_TRY; + return 1; +} /* end test_copy_option */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Test H5Ocopy() + * + * Tests a number of cases: messages can be stored in the + * new or old format, messages can be shared in either, + * both, or neither of the source and destination files. + * + * Return: EXIT_SUCCESS/EXIT_FAILURE + * + * Programmer: Peter Cao + * Friday, September 30, 2005 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + int nerrors = 0; + hid_t fapl, fapl2; + hid_t fcpl_shared, ocpl; + unsigned max_compact, min_dense; + int configuration; /* Configuration of tests. */ + int ExpressMode; + hbool_t same_file; /* Whether to run tests that only use one file */ + + /* Setup */ + h5_reset(); + fapl = h5_fileaccess(); + + ExpressMode = GetTestExpress(); + if (ExpressMode > 1) + HDprintf("***Express test mode on. Some tests may be skipped\n"); + + /* Copy the file access property list */ + if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR + + /* Set the "use the latest version of the format" bounds for creating objects in the file */ + if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR + + /* Create an FCPL with sharing enabled */ + if((fcpl_shared = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR + if(H5Pset_shared_mesg_nindexes(fcpl_shared, 1) < 0) TEST_ERROR + if(H5Pset_shared_mesg_index(fcpl_shared, 0, H5O_SHMESG_ALL_FLAG, 10) < 0) TEST_ERROR + + /* Obtain the default attribute storage phase change values */ + if((ocpl = H5Pcreate(H5P_OBJECT_CREATE)) < 0) TEST_ERROR + if(H5Pget_attr_phase_change(ocpl, &max_compact, &min_dense) < 0) TEST_ERROR + if(H5Pclose(ocpl) < 0) TEST_ERROR + + /* Test in all configurations */ + for(configuration = 0; configuration <= MAX_CONFIGURATION; configuration++) { + hid_t src_fapl; + hid_t dst_fapl; + hid_t fcpl_src; + hid_t fcpl_dst; + + /* Start with same_file == TRUE. Use source file settings for these + * tests. Don't run with a non-default destination file setting, as + * destination settings have no effect. */ + same_file = TRUE; + + /* No need to test dense attributes with old format */ + if(!(configuration & CONFIG_SRC_NEW_FORMAT) && (configuration & CONFIG_DENSE)) + continue; + + /* TODO Region references currently do not support copy from new format to old format + * (this may be fixed once H5Sencode/decode and H5CXis fixed) */ + if((configuration & CONFIG_SRC_NEW_FORMAT) && !(configuration & CONFIG_DST_NEW_FORMAT)) + continue; + + /* Test with and without shared messages */ + if(configuration & CONFIG_SHARE_SRC) { + HDputs("\nTesting with shared src messages:"); + fcpl_src = fcpl_shared; + } + else { + HDputs("\nTesting without shared src messages:"); + fcpl_src = H5P_DEFAULT; + } + if(configuration & CONFIG_SHARE_DST) { + HDputs("Testing with shared dst messages:"); + fcpl_dst = fcpl_shared; + same_file = FALSE; + } + else { + HDputs("Testing without shared dst messages:"); + fcpl_dst = H5P_DEFAULT; + } + + /* Set the FAPL for the source file's type of format */ + if(configuration & CONFIG_SRC_NEW_FORMAT) { + HDputs("Testing with latest format for source file:"); + src_fapl = fapl2; + + /* Test with and without dense attributes */ + if(configuration & CONFIG_DENSE) { + HDputs("Testing with dense attributes:"); + num_attributes_g = max_compact + 1; + } + else { + HDputs("Testing without dense attributes:"); + num_attributes_g = MAX(min_dense, 2) - 2; + } + } /* end if */ + else { + HDputs("Testing with oldest file format for source file:"); + src_fapl = fapl; + num_attributes_g = 4; + } /* end else */ + + /* Set the FAPL for the destination file's type of format */ + if(configuration & CONFIG_DST_NEW_FORMAT) { + HDputs("Testing with latest format for destination file:"); + dst_fapl = fapl2; + same_file = FALSE; + } /* end if */ + else { + HDputs("Testing with oldest file format for destination file:"); + dst_fapl = fapl; + } /* end else */ + + /* The tests... */ + nerrors += test_copy_option(fcpl_src, fcpl_dst, src_fapl, dst_fapl, + H5O_COPY_EXPAND_REFERENCE_FLAG, + FALSE, "H5Ocopy(): expand object reference"); + } /* end for */ + + /* Reset file address checking info */ + addr_reset(); + + /* Verify symbol table messages are cached */ + nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); + + /* Results */ + if(nerrors) { + HDprintf("***** %d OBJECT COPY TEST%s FAILED! *****\n", + nerrors, (1 == nerrors ? "" : "S")); + HDexit(EXIT_FAILURE); + } /* end if */ + + HDputs ("All object copying tests passed."); + + /* close property list. + * NOTE: if this property list is not closed and the test is + * run with the split or multi driver, an interesting + * problem is exposed in the property list shutdown code. + * + * Namely, since the split/multi driver copies property + * lists for internal use, there's a (high) chance that + * leaving the FAPL open and having the library's shutdown + * code close it will cause the underlying property lists + * to be cleaned up first, causing the actual property list + * close operation to fail (since it won't be able to close + * the already closed underlying property list). + * + * The could be addressed by converting the split/multi to + * use non-public API routines, or putting some way into the + * public H5I routines to indicate ordering at shutdown. + * + * For now, we just make certain to close the property list. + * (QAK - 2016/04/06) + * + */ + H5Pclose(fapl2); + + h5_cleanup(FILENAME, fapl); + + HDexit(EXIT_SUCCESS); + +error: + HDexit(EXIT_FAILURE); +} /* main */ + diff --git a/test/set_extent.c b/test/set_extent.c index 20322a3..78d2b0b 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -2658,7 +2658,7 @@ static int test_random_rank4_vl( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue, } /* end else */ /* Free read buffer */ - if(H5Dvlen_reclaim(type, mspace, H5P_DEFAULT, rbuf) < 0) + if(H5Treclaim(type, mspace, H5P_DEFAULT, rbuf) < 0) TEST_ERROR } /* end if */ @@ -2678,7 +2678,7 @@ static int test_random_rank4_vl( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue, /* Close */ if(H5Sselect_all(mspace) < 0) TEST_ERROR - if(H5Dvlen_reclaim(type, mspace, H5P_DEFAULT, wbuf) < 0) + if(H5Treclaim(type, mspace, H5P_DEFAULT, wbuf) < 0) TEST_ERROR free(fill_value.p); if(H5Sclose(mspace) < 0) diff --git a/test/tarray.c b/test/tarray.c index 0024746..e643fb0 100644 --- a/test/tarray.c +++ b/test/tarray.c @@ -1268,15 +1268,15 @@ test_array_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close dataset transfer property list */ ret = H5Pclose(xfer_pid); @@ -1523,15 +1523,15 @@ test_array_vlen_array(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close dataset transfer property list */ ret = H5Pclose(xfer_pid); diff --git a/test/testhdf5.c b/test/testhdf5.c index e136086..72acf6c 100644 --- a/test/testhdf5.c +++ b/test/testhdf5.c @@ -57,7 +57,8 @@ main(int argc, char *argv[]) AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL); AddTest("select", test_select, cleanup_select, "Selections", NULL); AddTest("time", test_time, cleanup_time, "Time Datatypes", NULL); - AddTest("reference", test_reference, cleanup_reference, "References", NULL); + AddTest("ref_deprec", test_reference_deprec, cleanup_reference_deprec, "Deprecated References", NULL); + AddTest("ref", test_reference, cleanup_reference, "References", NULL); AddTest("vltypes", test_vltypes, cleanup_vltypes, "Variable-Length Datatypes", NULL); AddTest("vlstrings", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL); AddTest("iterate", test_iterate, cleanup_iterate, "Group & Attribute Iteration", NULL); diff --git a/test/testhdf5.h b/test/testhdf5.h index ef3b784..6b13cae 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -192,6 +192,7 @@ void test_attr(void); void test_select(void); void test_time(void); void test_reference(void); +void test_reference_deprec(void); void test_vltypes(void); void test_vlstrings(void); void test_iterate(void); @@ -215,6 +216,7 @@ void cleanup_attr(void); void cleanup_select(void); void cleanup_time(void); void cleanup_reference(void); +void cleanup_reference_deprec(void); void cleanup_vltypes(void); void cleanup_vlstrings(void); void cleanup_iterate(void); diff --git a/test/tfile.c b/test/tfile.c index cf4403c..4fb2bc9 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -2640,8 +2640,8 @@ test_file_double_file_dataset_open(hbool_t new_format) HDmemset(buffer, 0, sizeof(char*) * 5); ret = H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); CHECK(ret, FAIL, "H5Dread"); - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, buffer); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer); + CHECK(ret, FAIL, "H5Treclaim"); /* Second file's dataset close */ ret = H5Dclose(did2); @@ -2655,8 +2655,8 @@ test_file_double_file_dataset_open(hbool_t new_format) HDmemset(buffer, 0, sizeof(char*) * 5); ret = H5Dread(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); CHECK(ret, FAIL, "H5Dread"); - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, buffer); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer); + CHECK(ret, FAIL, "H5Treclaim"); /* First file's dataset close */ ret = H5Dclose(did1); diff --git a/test/tmisc.c b/test/tmisc.c index 5225333..d637802 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -460,8 +460,8 @@ static void test_misc2_write_attribute(void) ret = H5Aread(att1, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, dataspace, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, dataspace, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Aclose(att1); CHECK(ret, FAIL, "H5Aclose"); @@ -486,8 +486,8 @@ static void test_misc2_write_attribute(void) ret = H5Aread(att2, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, dataspace, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, dataspace, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Aclose(att2); CHECK(ret, FAIL, "H5Aclose"); @@ -535,8 +535,8 @@ static void test_misc2_read_attribute(const char *filename, const char *att_name ret = H5Aread(att, type, &data_check); CHECK(ret, FAIL, "H5Aread"); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &data_check); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, space, H5P_DEFAULT, &data_check); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Sclose(space); CHECK(ret, FAIL, "H5Sclose"); @@ -994,8 +994,8 @@ test_misc5(void) } /* Reclaim the memory for the VL information */ - ret=H5Dvlen_reclaim(mem_type_id, space_id, H5P_DEFAULT, &buf); - CHECK(ret,FAIL,"H5Dvlen_reclaim"); + ret=H5Treclaim(mem_type_id, space_id, H5P_DEFAULT, &buf); + CHECK(ret,FAIL,"H5Treclaim"); /* Close dataspace */ ret=H5Sclose(space_id); @@ -2061,8 +2061,8 @@ test_misc12(void) CHECK(ret, FAIL, "H5Sselect_all"); /* Reclaim VL data memory */ - ret = H5Dvlen_reclaim(tid1, space, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, space, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Everything */ ret = H5Dclose(dataset); diff --git a/test/trefer.c b/test/trefer.c index 7158984..7d87ea9 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -21,9 +21,16 @@ #include "testhdf5.h" -#define FILE1 "trefer1.h5" -#define FILE2 "trefer2.h5" -#define FILE3 "trefer3.h5" +#define FILE_REF_PARAM "trefer_param.h5" +#define FILE_REF_OBJ "trefer_obj.h5" +#define FILE_REF_REG "trefer_reg.h5" +#define FILE_REF_REG_1D "trefer_reg_1d.h5" +#define FILE_REF_OBJ_DEL "trefer_obj_del.h5" +#define FILE_REF_GRP "trefer_grp.h5" +#define FILE_REF_ATTR "trefer_attr.h5" +#define FILE_REF_EXT1 "trefer_ext1.h5" +#define FILE_REF_EXT2 "trefer_ext2.h5" +#define FILE_REF_COMPAT "trefer_compat.h5" /* 1-D dataset with fixed dimensions */ #define SPACE1_RANK 1 @@ -55,6 +62,10 @@ typedef struct s1_t { #define DSETNAME2 "dset2" #define NAME_SIZE 16 +#define MAX_ITER_CREATE 1000 +#define MAX_ITER_WRITE MAX_ITER_CREATE +#define MAX_ITER_READ MAX_ITER_CREATE + /**************************************************************** ** @@ -65,47 +76,57 @@ typedef struct s1_t { static void test_reference_params(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t group; /* Group ID */ - hid_t sid1; /* Dataspace ID */ - hid_t tid1; /* Datatype ID */ - hid_t dapl_id; /* Dataset access property list */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hid_t aapl_id; /* Attribute access property list */ + hid_t dapl_id; /* Dataset access property list */ hsize_t dims1[] = {SPACE1_DIM1}; - hobj_ref_t *wbuf, /* buffer to write to disk */ - *rbuf, /* buffer read from disk */ - *tbuf; /* temp. buffer read from disk */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + H5R_type_t type; /* Reference type */ unsigned *tu32; /* Temporary pointer to uint32 data */ - int i; /* counting variables */ - const char *write_comment = "Foo!"; /* Comments for group */ - hid_t ret_id; /* Generic hid_t return value */ - ssize_t name_size; /* Size of reference name */ - herr_t ret; /* Generic return value */ + int i; /* Counters */ + const char *write_comment = "Foo!"; /* Comments for group */ + hid_t ret_id; /* Generic hid_t return value */ + ssize_t name_size; /* Size of reference name */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Reference Parameters\n")); /* Allocate write & read buffers */ - wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_PARAM, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create attribute access property list */ + aapl_id = H5Pcreate(H5P_ATTRIBUTE_ACCESS); + CHECK(aapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a group */ group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); /* Set group's comment */ ret = H5Oset_comment(group, write_comment); @@ -113,10 +134,7 @@ test_reference_params(void) /* Create a dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); - - for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) - *tu32++ = (unsigned)i * 3; + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); @@ -128,7 +146,19 @@ test_reference_params(void) /* Create another dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -136,7 +166,7 @@ test_reference_params(void) /* Create a datatype to refer to */ tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); @@ -161,58 +191,88 @@ test_reference_params(void) CHECK(ret, FAIL, "H5Gclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); - - /* Test parameters to H5Rcreate */ - ret = H5Rcreate(NULL, fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate ref"); - ret = H5Rcreate(&wbuf[0], (hid_t)-1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate loc_id"); - ret = H5Rcreate(&wbuf[0], fid1, NULL, H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate name"); - ret = H5Rcreate(&wbuf[0], fid1, "", H5R_OBJECT, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate null name"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate type"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, (hid_t)-1); - VERIFY(ret, FAIL, "H5Rcreate region space"); - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)0); - VERIFY(ret, FAIL, "H5Rcreate space"); - - /* Test parameters to H5Rdereference */ - dset2 = H5Rdereference2((hid_t)-1, H5P_DEFAULT, H5R_OBJECT, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 loc_id"); - dset2 = H5Rdereference2(dataset, (hid_t)-1, H5R_OBJECT, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 oapl_id"); - dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, NULL); - VERIFY(dset2, FAIL, "H5Rdereference2 ref"); - dset2 = H5Rdereference2(dataset, dapl_id, H5R_MAXTYPE, &rbuf[0]); - VERIFY(dset2, FAIL, "H5Rdereference2 type"); - - /* Test parameters to H5Rget_obj_type2 */ - ret = H5Rget_obj_type2((hid_t)-1, H5R_OBJECT, &rbuf[0], NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 loc_id"); - ret = H5Rget_obj_type2(fid1, H5R_OBJECT, NULL, NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 ref"); - ret = H5Rget_obj_type2(fid1, H5R_MAXTYPE, &rbuf[0], NULL); - VERIFY(ret, FAIL, "H5Rget_obj_type2 type"); - - /* Test parameters to H5Rget_name */ - name_size = H5Rget_name((hid_t)-1, H5R_DATASET_REGION, &rbuf[0], NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name loc_id"); - name_size = H5Rget_name(fid1, H5R_DATASET_REGION, NULL, NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name ref"); - name_size = H5Rget_name(fid1, H5R_MAXTYPE, &rbuf[0], NULL, 0); - VERIFY(name_size, FAIL, "H5Rget_name type"); - - /* Test parameters to H5Rget_region */ - ret_id = H5Rget_region((hid_t)-1, H5R_OBJECT, &rbuf[0]); - VERIFY(ret_id, FAIL, "H5Rget_region loc_id"); - ret_id = H5Rget_region(fid1, H5R_OBJECT, NULL); - VERIFY(ret_id, FAIL, "H5Rget_region ref"); - ret_id = H5Rget_region(fid1, H5R_OBJECT, &rbuf[0]); - VERIFY(ret_id, FAIL, "H5Rget_region type"); + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dcreate2"); + + /* Test parameters to H5Rcreate_object */ + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", NULL); + VERIFY(ret, FAIL, "H5Rcreate_object ref"); + ret = H5Rcreate_object(H5I_INVALID_HID, "/Group1/Dataset1", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object loc_id"); + ret = H5Rcreate_object(fid1, NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object name"); + ret = H5Rcreate_object(fid1, "", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_object null name"); + + /* Test parameters to H5Rcreate_region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, NULL); + VERIFY(ret, FAIL, "H5Rcreate_region ref"); + ret = H5Rcreate_region(H5I_INVALID_HID, "/Group1/Dataset1", sid1, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region loc_id"); + ret = H5Rcreate_region(fid1, NULL, sid1, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region name"); + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", H5I_INVALID_HID, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_region dataspace"); + + /* Test parameters to H5Rcreate_attr */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", "Attr", NULL); + VERIFY(ret, FAIL, "H5Rcreate_attr ref"); + ret = H5Rcreate_attr(H5I_INVALID_HID, "/Group1/Dataset2", "Attr", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr loc_id"); + ret = H5Rcreate_attr(fid1, NULL, "Attr", &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr name"); + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcreate_attr attr_name"); + + /* Test parameters to H5Rdestroy */ + ret = H5Rdestroy(NULL); + VERIFY(ret, FAIL, "H5Rdestroy"); + + /* Test parameters to H5Rget_type */ + type = H5Rget_type(NULL); + VERIFY(type, H5R_BADTYPE, "H5Rget_type ref"); + + /* Test parameters to H5Requal */ + ret = H5Requal(NULL, (const H5R_ref_t *)&rbuf[0]); + VERIFY(ret, FAIL, "H5Requal ref1"); + ret = H5Requal((const H5R_ref_t *)&rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Requal ref2"); + + /* Test parameters to H5Rcopy */ + ret = H5Rcopy(NULL, &wbuf[0]); + VERIFY(ret, FAIL, "H5Rcopy src_ref"); + ret = H5Rcopy((const H5R_ref_t *)&rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rcopy dest_ref"); + + /* Test parameters to H5Ropen_object */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5I_INVALID_HID, H5I_INVALID_HID); + VERIFY(dset2, FAIL, "H5Ropen_object oapl_id"); + dset2 = H5Ropen_object(NULL, H5P_DEFAULT, dapl_id); + VERIFY(dset2, FAIL, "H5Ropen_object ref"); + + /* Test parameters to H5Ropen_region */ + ret_id = H5Ropen_region(NULL, H5I_INVALID_HID, H5I_INVALID_HID); + VERIFY(ret_id, H5I_INVALID_HID, "H5Ropen_region ref"); + + /* Test parameters to H5Ropen_attr */ + ret_id = H5Ropen_attr(NULL, H5P_DEFAULT, aapl_id); + VERIFY(ret_id, H5I_INVALID_HID, "H5Ropen_attr ref"); + + /* Test parameters to H5Rget_obj_type3 */ + ret = H5Rget_obj_type3(NULL, H5P_DEFAULT, NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type3 ref"); + + /* Test parameters to H5Rget_file_name */ + name_size = H5Rget_file_name(NULL, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_file_name ref"); + + /* Test parameters to H5Rget_obj_name */ + name_size = H5Rget_obj_name(NULL, H5P_DEFAULT, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_obj_name ref"); + + /* Test parameters to H5Rget_attr_name */ + name_size = H5Rget_attr_name(NULL, NULL, 0); + VERIFY(name_size, (-1), "H5Rget_attr_name ref"); /* Close disk dataspace */ ret = H5Sclose(sid1); @@ -222,6 +282,10 @@ test_reference_params(void) ret = H5Pclose(dapl_id); CHECK(ret, FAIL, "H5Pclose"); + /* Close attribute access property list */ + ret = H5Pclose(aapl_id); + CHECK(ret, FAIL, "H5Pclose"); + /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); @@ -234,7 +298,7 @@ test_reference_params(void) HDfree(wbuf); HDfree(rbuf); HDfree(tbuf); -} /* test_reference_obj() */ +} /* test_reference_params() */ /**************************************************************** ** @@ -245,60 +309,52 @@ test_reference_params(void) static void test_reference_obj(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t group; /* Group ID */ - hid_t sid1; /* Dataspace ID */ - hid_t tid1; /* Datatype ID */ - hsize_t dims1[] = {SPACE1_DIM1}; - hid_t dapl_id; /* Dataset access property list */ - hobj_ref_t *wbuf, /* buffer to write to disk */ - *rbuf, /* buffer read from disk */ - *tbuf; /* temp. buffer read from disk */ - hobj_ref_t nvrbuf[3]={0,101,1000000000}; /* buffer with non-valid refs */ - unsigned *tu32; /* Temporary pointer to uint32 data */ - int i, j; /* counting variables */ - const char *write_comment="Foo!"; /* Comments for group */ - char read_comment[10]; - H5O_type_t obj_type; /* Object type */ - ssize_t size; /* Comment length */ - herr_t ret; /* Generic return value */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* Counters */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Object Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); - tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_OBJ, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a group */ group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); - - /* Set group's comment */ - ret = H5Oset_comment(group, write_comment); - CHECK(ret, FAIL, "H5Oset_comment"); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); /* Create a dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); - - for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) - *tu32++ = (unsigned)i * 3; + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); @@ -318,7 +374,7 @@ test_reference_obj(void) /* Create a datatype to refer to */ tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); @@ -343,39 +399,39 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Gclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[1], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Dataset2", &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Create reference to group */ - ret = H5Rcreate(&wbuf[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[2], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1", &wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); /* Create reference to named datatype */ - ret = H5Rcreate(&wbuf[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[3], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Group1/Datatype1", &wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); /* Write selection to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); /* Close disk dataspace */ @@ -391,27 +447,27 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_OBJ, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); /* Open dataset object */ - dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, &rbuf[0]); - CHECK(dset2, FAIL, "H5Rdereference2"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset2); - CHECK(sid1, FAIL, "H5Dget_space"); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 4, "H5Sget_simple_extent_npoints"); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); /* Read from disk */ ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); @@ -425,24 +481,16 @@ test_reference_obj(void) CHECK(ret, FAIL, "H5Dclose"); /* Open group object. GAPL isn't supported yet. But it's harmless to pass in */ - group = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[2]); - CHECK(group, FAIL, "H5Rdereference2"); - - /* Get group's comment */ - size = H5Oget_comment(group, read_comment, (size_t)10); - CHECK(size, FAIL, "H5Oget_comment"); - - /* Check for correct comment value */ - if(HDstrcmp(write_comment, read_comment) != 0) - TestErrPrintf("Error! Incorrect group comment, wanted: %s, got: %s\n",write_comment,read_comment); + group = H5Ropen_object((const H5R_ref_t *)&rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Ropen_object"); /* Close group */ ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); /* Open datatype object. TAPL isn't supported yet. But it's harmless to pass in */ - tid1 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[3]); - CHECK(tid1, FAIL, "H5Rdereference2"); + tid1 = H5Ropen_object((const H5R_ref_t *)&rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(tid1, H5I_INVALID_HID, "H5Ropen_object"); /* Verify correct datatype */ { @@ -455,14 +503,6 @@ test_reference_obj(void) VERIFY(ret, 3, "H5Tget_nmembers"); } - /* Attempting to retrieve type of object using non-valid refs */ - for(j = 0; j < 3; j++) { - H5E_BEGIN_TRY { - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &nvrbuf[j], &obj_type); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Rget_obj_type2"); - } /* end for */ - /* Close datatype */ ret = H5Tclose(tid1); CHECK(ret, FAIL, "H5Tclose"); @@ -479,6 +519,14 @@ test_reference_obj(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(j = 0; j < SPACE1_DIM1; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -498,13 +546,13 @@ test_reference_obj(void) static void test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) { - hid_t fid1; /* HDF5 File IDs */ - hid_t fapl = -1; /* File access property list */ - hid_t dset1, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t sid1, /* Dataspace ID #1 */ - sid2; /* Dataspace ID #2 */ - hid_t dapl_id; /* Dataset access property list */ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid2; /* Dataspace ID #2 */ + hid_t dapl_id; /* Dataset access property list */ hsize_t dims1[] = {SPACE1_DIM1}, dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ @@ -512,62 +560,60 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ - hsize_t *coords; /* Coordinate buffer */ - hsize_t low[SPACE2_RANK]; /* Selection bounds */ - hsize_t high[SPACE2_RANK]; /* Selection bounds */ - hdset_reg_ref_t *wbuf, /* buffer to write to disk */ - *rbuf; /* buffer read from disk */ - hdset_reg_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ - uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ - *drbuf; /* Buffer for reading numeric data from disk */ - uint8_t *tu8; /* Temporary pointer to uint8 data */ - H5O_type_t obj_type; /* Type of object */ - int i, j; /* counting variables */ - hssize_t hssize_ret; /* hssize_t return value */ - htri_t tri_ret; /* htri_t return value */ - herr_t ret; /* Generic return value */ - hdset_reg_ref_t undef_reg[1]; /* test for undefined reference */ - hid_t dset_NA; /* Dataset id for undefined reference */ - hid_t space_NA; /* Dataspace id for undefined reference */ - hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ - hdset_reg_ref_t wdata_NA[1], /* Write buffer */ - rdata_NA[1]; /* Read buffer */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE2_RANK]; /* Selection bounds */ + hsize_t high[SPACE2_RANK]; /* Selection bounds */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + H5R_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Type of object */ + int i, j; /* Counters */ + hssize_t hssize_ret; /* hssize_t return value */ + htri_t tri_ret; /* htri_t return value */ + herr_t ret; /* Generic return value */ + hid_t dset_NA; /* Dataset id for undefined reference */ + hid_t space_NA; /* Dataspace id for undefined reference */ + hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ + H5R_ref_t rdata_NA[1]; /* Read buffer */ /* Output message about test being performed */ MESSAGE(5, ("Testing Dataset Region Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); - rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); - dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE2_DIM1 * SPACE2_DIM2); + wbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + dwbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); + for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) + *tu8++ = (uint8_t)(i * 3); + /* Create file access property list */ fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); /* Set the low/high version bounds in fapl */ ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create file with the fapl */ - fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_REG, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); - CHECK(sid2, FAIL, "H5Screate_simple"); + CHECK(sid2, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a dataset */ dset2 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset2, FAIL, "H5Dcreate2"); - - for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) - *tu8++ = (uint8_t)(i * 3); + CHECK(dset2, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); @@ -579,11 +625,11 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Create dataspace for the reference dataset */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset */ - dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset1, H5I_INVALID_HID, "H5Dcreate2"); /* Create references */ @@ -599,11 +645,11 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(ret, 36, "H5Sget_select_npoints"); /* Store first dataset region */ - ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Select sequence of ten points for second reference */ coord1[0][0] = 6; coord1[0][1] = 9; @@ -620,17 +666,21 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_npoints"); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_npoints"); /* Store second dataset region */ - ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_region"); /* Select unlimited hyperslab for third reference */ - start[0] = 1; start[1] = 8; - stride[0] = 4; stride[1] = 1; - count[0] = H5S_UNLIMITED; count[1] = 1; - block[0] = 2; block[1] = 2; + start[0] = 1; + start[1] = 8; + stride[0] = 4; + stride[1] = 1; + count[0] = H5S_UNLIMITED; + count[1] = 1; + block[0] = 2; + block[1] = 2; ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); @@ -638,41 +688,39 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); /* Store third dataset region */ + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Store fourth dataset region */ + ret = H5Rcreate_region(fid1, "/Dataset2", sid2, &wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + /* Write selection to disk */ H5E_BEGIN_TRY { - ret = H5Rcreate(&wbuf[2], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + ret = H5Dwrite(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); } H5E_END_TRY; if(libver_high < H5F_LIBVER_V110) - VERIFY(ret, FAIL, "H5Rcreate"); + VERIFY(ret, FAIL, "H5Dwrite"); else - CHECK(ret, FAIL, "H5Rcreate"); - - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); - - /* Write selection to disk */ - ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); - CHECK(ret, FAIL, "H5Dwrite"); + CHECK(ret, FAIL, "H5Dwrite"); /* * Store a dataset region reference which will not get written to disk */ - /* Create reference to an element in dset1 */ - ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); - CHECK(ret, FAIL, "H5Sselect_elements"); - ret = H5Rcreate(&wdata_NA[0], fid1, "/Dataset1", H5R_DATASET_REGION, sid2); - CHECK(ret, FAIL, "H5Rcreate"); - /* Create the dataspace of the region references */ space_NA = H5Screate_simple(1, dims_NA, NULL); - CHECK(space_NA, FAIL, "H5Screate_simple"); + CHECK(space_NA, H5I_INVALID_HID, "H5Screate_simple"); /* Create the dataset and write the region references to it */ - dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF_DSETREG, space_NA, H5P_DEFAULT, + dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF, space_NA, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset_NA, FAIL, "H5Dcreate"); + CHECK(dset_NA, H5I_INVALID_HID, "H5Dcreate"); /* Close and release resources for undefined region reference tests */ ret = H5Dclose(dset_NA); @@ -697,8 +745,8 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_REG, H5F_ACC_RDWR, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* * Start the test of an undefined reference @@ -706,25 +754,25 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Open the dataset of the undefined references */ dset_NA = H5Dopen2(fid1, "DS_NA", H5P_DEFAULT); - CHECK(dset_NA, FAIL, "H5Dopen2"); + CHECK(dset_NA, H5I_INVALID_HID, "H5Dopen2"); /* Read the data */ - ret = H5Dread(dset_NA, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); + ret = H5Dread(dset_NA, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); CHECK(ret, FAIL, "H5Dread"); /* * Dereference an undefined reference (should fail) */ H5E_BEGIN_TRY { - dset2 = H5Rdereference2(dset_NA, H5P_DEFAULT, H5R_DATASET_REGION, &rdata_NA[0]); + dset2 = H5Ropen_object((const H5R_ref_t *)&rdata_NA[0], H5P_DEFAULT, H5P_DEFAULT); } H5E_END_TRY; - VERIFY(dset2, FAIL, "H5Rdereference2"); + VERIFY(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Close and release resources. */ ret = H5Dclose(dset_NA); CHECK(ret, FAIL, "H5Dclose"); - /* This close should fail since H5Rdereference2 never created + /* This close should fail since H5Ropen_object never created * the id of the referenced object. */ H5E_BEGIN_TRY { ret = H5Dclose(dset2); @@ -737,115 +785,116 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Open the dataset */ dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dopen2"); + CHECK(dset1, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); - CHECK(ret, FAIL, "H5Dread"); - - /* Try to read an unaddressed dataset */ - dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, undef_reg); - VERIFY(dset2, FAIL, "H5Rdereference2 haddr_undef"); + H5E_BEGIN_TRY { + ret = H5Dread(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + } H5E_END_TRY; - /* Try to open objects */ - dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); - CHECK(dset2, FAIL, "H5Rdereference2"); + if(libver_high < H5F_LIBVER_V110) + VERIFY(ret, FAIL, "H5Dread"); + else { + CHECK(ret, FAIL, "H5Dread"); - /* Check what H5Rget_obj_type2 function returns */ - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + /* Try to open objects */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); - /* Check information in referenced dataset */ - sid1 = H5Dget_space(dset2); - CHECK(sid1, FAIL, "H5Dget_space"); + /* Check what H5Rget_obj_type3 function returns */ + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); - /* Read from disk */ - ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); - CHECK(ret, FAIL, "H5Dread"); + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, (SPACE2_DIM1 * SPACE2_DIM2), "H5Sget_simple_extent_npoints"); - for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) - VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + /* Read from disk */ + ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); - /* Get the hyperslab selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); - CHECK(sid2, FAIL, "H5Rget_region"); + for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); - /* Verify correct hyperslab selected */ - ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 36, "H5Sget_select_npoints"); - ret = (int)H5Sget_select_hyper_nblocks(sid2); - VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); - coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ - ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); - CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); - VERIFY(coords[0], 2, "Hyperslab Coordinates"); - VERIFY(coords[1], 2, "Hyperslab Coordinates"); - VERIFY(coords[2], 7, "Hyperslab Coordinates"); - VERIFY(coords[3], 7, "Hyperslab Coordinates"); - HDfree(coords); - ret = H5Sget_select_bounds(sid2, low, high); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low[0], 2, "Selection Bounds"); - VERIFY(low[1], 2, "Selection Bounds"); - VERIFY(high[0], 7, "Selection Bounds"); - VERIFY(high[1], 7, "Selection Bounds"); + /* Get the hyperslab selection */ + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); - /* Close region space */ - ret = H5Sclose(sid2); - CHECK(ret, FAIL, "H5Sclose"); + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid2); + VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 2, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 7, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(low[1], 2, "Selection Bounds"); + VERIFY(high[0], 7, "Selection Bounds"); + VERIFY(high[1], 7, "Selection Bounds"); - /* Get the element selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); - CHECK(sid2, FAIL, "H5Rget_region"); + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); - /* Verify correct elements selected */ - ret = (int)H5Sget_select_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_npoints"); - ret = (int)H5Sget_select_elem_npoints(sid2); - VERIFY(ret, 10, "H5Sget_select_elem_npoints"); - coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ - ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); - CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); - VERIFY(coords[0], coord1[0][0], "Element Coordinates"); - VERIFY(coords[1], coord1[0][1], "Element Coordinates"); - VERIFY(coords[2], coord1[1][0], "Element Coordinates"); - VERIFY(coords[3], coord1[1][1], "Element Coordinates"); - VERIFY(coords[4], coord1[2][0], "Element Coordinates"); - VERIFY(coords[5], coord1[2][1], "Element Coordinates"); - VERIFY(coords[6], coord1[3][0], "Element Coordinates"); - VERIFY(coords[7], coord1[3][1], "Element Coordinates"); - VERIFY(coords[8], coord1[4][0], "Element Coordinates"); - VERIFY(coords[9], coord1[4][1], "Element Coordinates"); - VERIFY(coords[10], coord1[5][0], "Element Coordinates"); - VERIFY(coords[11], coord1[5][1], "Element Coordinates"); - VERIFY(coords[12], coord1[6][0], "Element Coordinates"); - VERIFY(coords[13], coord1[6][1], "Element Coordinates"); - VERIFY(coords[14], coord1[7][0], "Element Coordinates"); - VERIFY(coords[15], coord1[7][1], "Element Coordinates"); - VERIFY(coords[16], coord1[8][0], "Element Coordinates"); - VERIFY(coords[17], coord1[8][1], "Element Coordinates"); - VERIFY(coords[18], coord1[9][0], "Element Coordinates"); - VERIFY(coords[19], coord1[9][1], "Element Coordinates"); - HDfree(coords); - ret = H5Sget_select_bounds(sid2, low, high); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low[0], 0, "Selection Bounds"); - VERIFY(low[1], 0, "Selection Bounds"); - VERIFY(high[0], 9, "Selection Bounds"); - VERIFY(high[1], 9, "Selection Bounds"); + /* Get the element selection */ + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid2); + VERIFY(ret, SPACE2_DIM2, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[0][1], "Element Coordinates"); + VERIFY(coords[2], coord1[1][0], "Element Coordinates"); + VERIFY(coords[3], coord1[1][1], "Element Coordinates"); + VERIFY(coords[4], coord1[2][0], "Element Coordinates"); + VERIFY(coords[5], coord1[2][1], "Element Coordinates"); + VERIFY(coords[6], coord1[3][0], "Element Coordinates"); + VERIFY(coords[7], coord1[3][1], "Element Coordinates"); + VERIFY(coords[8], coord1[4][0], "Element Coordinates"); + VERIFY(coords[9], coord1[4][1], "Element Coordinates"); + VERIFY(coords[10], coord1[5][0], "Element Coordinates"); + VERIFY(coords[11], coord1[5][1], "Element Coordinates"); + VERIFY(coords[12], coord1[6][0], "Element Coordinates"); + VERIFY(coords[13], coord1[6][1], "Element Coordinates"); + VERIFY(coords[14], coord1[7][0], "Element Coordinates"); + VERIFY(coords[15], coord1[7][1], "Element Coordinates"); + VERIFY(coords[16], coord1[8][0], "Element Coordinates"); + VERIFY(coords[17], coord1[8][1], "Element Coordinates"); + VERIFY(coords[18], coord1[9][0], "Element Coordinates"); + VERIFY(coords[19], coord1[9][1], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 0, "Selection Bounds"); + VERIFY(low[1], 0, "Selection Bounds"); + VERIFY(high[0], 9, "Selection Bounds"); + VERIFY(high[1], 9, "Selection Bounds"); - /* Close region space */ - ret = H5Sclose(sid2); - CHECK(ret, FAIL, "H5Sclose"); + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); - if(libver_high >= H5F_LIBVER_V110) { /* Get the unlimited selection */ - sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[2]); - CHECK(sid2, FAIL, "H5Rget_region"); + sid2 = H5Ropen_region((const H5R_ref_t *)&rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid2, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct hyperslab selected */ hssize_ret = H5Sget_select_npoints(sid2); @@ -867,23 +916,23 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Close region space */ ret = H5Sclose(sid2); CHECK(ret, FAIL, "H5Sclose"); - } - /* Close first space */ - ret = H5Sclose(sid1); - CHECK(ret, FAIL, "H5Sclose"); - - /* Close dereferenced Dataset */ - ret = H5Dclose(dset2); - CHECK(ret, FAIL, "H5Dclose"); + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); - /* Attempting to retrieve type of object using non-valid refs */ - for(j = 0; j < 3; j++) { - H5E_BEGIN_TRY { - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &nvrbuf[j], &obj_type); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Rget_obj_type2"); - } /* end for */ + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type3((const H5R_ref_t *)&nvrbuf[j], H5P_DEFAULT, &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type3"); + } /* end for */ + } /* Close Dataset */ ret = H5Dclose(dset1); @@ -897,6 +946,16 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(j = 0; j < SPACE1_DIM1; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + if(libver_high >= H5F_LIBVER_V110) { + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -917,14 +976,14 @@ test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) static void test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) { - hid_t fid1; /* HDF5 File IDs */ - hid_t fapl = -1; /* File access property list */ - hid_t dset1, /* Dataset ID */ - dset3; /* Dereferenced dataset ID */ - hid_t sid1, /* Dataspace ID #1 */ - sid3; /* Dataspace ID #3 */ - hid_t dapl_id; /* Dataset access property list */ - hsize_t dims1[] = {SPACE1_DIM1}, + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset3; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid3; /* Dataspace ID #3 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {2}, /* Must be 2 */ dims3[] = {SPACE3_DIM1}; hsize_t start[SPACE3_RANK]; /* Starting location of hyperslab */ hsize_t stride[SPACE3_RANK]; /* Stride of hyperslab */ @@ -934,50 +993,50 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) hsize_t *coords; /* Coordinate buffer */ hsize_t low[SPACE3_RANK]; /* Selection bounds */ hsize_t high[SPACE3_RANK]; /* Selection bounds */ - hdset_reg_ref_t *wbuf, /* buffer to write to disk */ - *rbuf; /* buffer read from disk */ - uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ - *drbuf; /* Buffer for reading numeric data from disk */ - uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ H5O_type_t obj_type; /* Object type */ - int i; /* counting variables */ - herr_t ret; /* Generic return value */ + int i; /* Counter */ + herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing 1-D Dataset Region Reference Functions\n")); /* Allocate write & read buffers */ - wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); - rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); - dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE3_DIM1); + wbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), (size_t)SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), (size_t)SPACE1_DIM1); + dwbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); + for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) + *tu8++ = (uint8_t)(i * 3); + /* Create the file access property list */ fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(fapl, FAIL, "H5Pcreate"); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); /* Set the low/high version bounds in fapl */ ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create file with the fapl */ - fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_REG_1D, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid3 = H5Screate_simple(SPACE3_RANK, dims3, NULL); - CHECK(sid3, FAIL, "H5Screate_simple"); + CHECK(sid3, H5I_INVALID_HID, "H5Screate_simple"); /* Create dataset access property list */ dapl_id = H5Pcreate(H5P_DATASET_ACCESS); - CHECK(dapl_id, FAIL, "H5Pcreate"); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); /* Create a dataset */ dset3 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset3, FAIL, "H5Dcreate2"); - - for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) - *tu8++ = (uint8_t)(i * 3); + CHECK(dset3, H5I_INVALID_HID, "H5Dcreate2"); /* Write selection to disk */ ret = H5Dwrite(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); @@ -989,31 +1048,31 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) /* Create dataspace for the reference dataset */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset */ - dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dcreate2"); /* Create references */ /* Select 15 2x1 hyperslabs for first reference */ - start[0] = 2; + start[0] = 2; stride[0] = 5; - count[0] = 15; - block[0] = 2; + count[0] = 15; + block[0] = 2; ret = H5Sselect_hyperslab(sid3, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); ret = (int)H5Sget_select_npoints(sid3); - VERIFY(ret, 30, "H5Sget_select_npoints"); + VERIFY(ret, (block[0] * count[0]), "H5Sget_select_npoints"); /* Store first dataset region */ - ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid3, &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Select sequence of ten points for second reference */ coord1[0][0] = 16; @@ -1030,14 +1089,14 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sselect_elements"); ret = (int)H5Sget_select_npoints(sid3); - VERIFY(ret, 10, "H5Sget_select_npoints"); + VERIFY(ret, POINT1_NPOINTS, "H5Sget_select_npoints"); /* Store second dataset region */ - ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_region(fid1, "/Dataset2", sid3, &wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_region"); /* Write selection to disk */ - ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + ret = H5Dwrite(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); CHECK(ret, FAIL, "H5Dwrite"); /* Close disk dataspace */ @@ -1057,32 +1116,32 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Fclose"); /* Re-open the file */ - fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_REG_1D, H5F_ACC_RDWR, fapl); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dopen2"); + CHECK(dset1, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + ret = H5Dread(dset1, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); CHECK(ret, FAIL, "H5Dread"); /* Try to open objects */ - dset3 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); - CHECK(dset3, FAIL, "H5Rdereference2"); + dset3 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset3, H5I_INVALID_HID, "H5Ropen_object"); - /* Check what H5Rget_obj_type2 function returns */ - ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + /* Check what H5Rget_obj_type3 function returns */ + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset3); - CHECK(sid1, FAIL, "H5Dget_space"); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); ret = (int)H5Sget_simple_extent_npoints(sid1); - VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + VERIFY(ret, SPACE3_DIM1, "H5Sget_simple_extent_npoints"); /* Read from disk */ ret = H5Dread(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); @@ -1092,8 +1151,8 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) VERIFY(*tu8, (uint8_t)(i * 3), "Data"); /* Get the hyperslab selection */ - sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); - CHECK(sid3, FAIL, "H5Rget_region"); + sid3 = H5Ropen_region((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid3, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct hyperslab selected */ ret = (int)H5Sget_select_npoints(sid3); @@ -1144,8 +1203,8 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) CHECK(ret, FAIL, "H5Sclose"); /* Get the element selection */ - sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); - CHECK(sid3, FAIL, "H5Rget_region"); + sid3 = H5Ropen_region((const H5R_ref_t *)&rbuf[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(sid3, H5I_INVALID_HID, "H5Ropen_region"); /* Verify correct elements selected */ ret = (int)H5Sget_select_npoints(sid3); @@ -1199,6 +1258,14 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(i = 0; i < 2; i++) { + ret = H5Rdestroy(&wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf); HDfree(rbuf); @@ -1215,44 +1282,43 @@ test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) static void test_reference_obj_deleted(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, /* Dataset ID */ - dset2; /* Dereferenced dataset ID */ - hid_t sid1; /* Dataspace ID */ - hobj_ref_t oref; /* Object Reference to test */ - H5O_type_t obj_type; /* Object type */ - haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ - herr_t ret; /* Generic return value */ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID */ + H5R_ref_t oref; /* Object Reference to test */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ /* Create file */ - fid1 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_OBJ_DEL, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create scalar dataspace for datasets */ sid1 = H5Screate_simple(0, NULL, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create a dataset to reference (deleted later) */ dataset = H5Dcreate2(fid1, "Dataset1", H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Create a dataset */ - dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to dataset */ - ret = H5Rcreate(&oref, fid1, "/Dataset1", H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); - ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &oref, &obj_type); - CHECK(ret, FAIL, "H5Rget_obj_type2"); - VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + ret = H5Rcreate_object(fid1, "/Dataset1", &oref); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&oref, H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Write selection to disk */ - ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); CHECK(ret, FAIL, "H5Dwrite"); /* Close Dataset */ @@ -1271,31 +1337,25 @@ test_reference_obj_deleted(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy reference */ + ret = H5Rdestroy(&oref); + CHECK(ret, FAIL, "H5Rdestroy"); + /* Re-open the file */ - fid1 = H5Fopen(FILE3, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fopen"); + fid1 = H5Fopen(FILE_REF_OBJ_DEL, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); /* Open the dataset */ dataset = H5Dopen2(fid1, "/Dataset2", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); - - /* Open undefined reference */ - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &addr); - VERIFY(dset2, FAIL, "H5Rdereference2"); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - HDmemset(&oref, 0, sizeof(hobj_ref_t)); - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); CHECK(ret, FAIL, "H5Dread"); /* Open deleted dataset object */ - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); - VERIFY(dset2, FAIL, "H5Rdereference2"); - - /* Open nonsense reference */ - HDmemset(&oref, 0, sizeof(hobj_ref_t)); - dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); - VERIFY(dset2, FAIL, "H5Rdereference2"); + dset2 = H5Ropen_object((const H5R_ref_t *)&oref, H5P_DEFAULT, H5P_DEFAULT); + VERIFY(dset2, H5I_INVALID_HID, "H5Ropen_object"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1304,6 +1364,10 @@ test_reference_obj_deleted(void) /* Close file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy reference */ + ret = H5Rdestroy(&oref); + CHECK(ret, FAIL, "H5Rdestroy"); } /* test_reference_obj_deleted() */ /**************************************************************** @@ -1359,8 +1423,8 @@ test_reference_group(void) hid_t gid = -1, gid2 = -1; /* Group IDs */ hid_t did; /* Dataset ID */ hid_t sid; /* Dataspace ID */ - hobj_ref_t wref; /* Reference to write */ - hobj_ref_t rref; /* Reference to read */ + H5R_ref_t wref; /* Reference to write */ + H5R_ref_t rref; /* Reference to read */ H5G_info_t ginfo; /* Group info struct */ char objname[NAME_SIZE]; /* Buffer to store name */ H5O_info_t oinfo; /* Object info struct */ @@ -1369,47 +1433,47 @@ test_reference_group(void) herr_t ret; /* Create file with a group and a dataset containing an object reference to the group */ - fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fcreate"); + fid = H5Fcreate(FILE_REF_GRP, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace to use for dataset */ sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); + CHECK(sid, H5I_INVALID_HID, "H5Screate"); /* Create group to refer to */ gid = H5Gcreate2(fid, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid, FAIL, "H5Gcreate2"); + CHECK(gid, H5I_INVALID_HID, "H5Gcreate2"); /* Create nested groups */ gid2 = H5Gcreate2(gid, GROUPNAME2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid2, FAIL, "H5Gcreate2"); + CHECK(gid2, H5I_INVALID_HID, "H5Gcreate2"); ret = H5Gclose(gid2); CHECK(ret, FAIL, "H5Gclose"); gid2 = H5Gcreate2(gid, GROUPNAME3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid2, FAIL, "H5Gcreate2"); + CHECK(gid2, H5I_INVALID_HID, "H5Gcreate2"); ret = H5Gclose(gid2); CHECK(ret, FAIL, "H5Gclose"); /* Create bottom dataset */ did = H5Dcreate2(gid, DSETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - assert(did > 0); + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); ret = H5Dclose(did); - assert(ret >= 0); + CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(gid); CHECK(ret, FAIL, "H5Gclose"); /* Create dataset */ - did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF_OBJ, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dcreate2"); + did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to group */ - ret = H5Rcreate(&wref, fid, GROUPNAME, H5R_OBJECT, (hid_t)-1); - CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rcreate_object(fid, GROUPNAME, &wref); + CHECK(ret, FAIL, "H5Rcreate_object"); /* Write reference to disk */ - ret = H5Dwrite(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); + ret = H5Dwrite(did, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); CHECK(ret, FAIL, "H5Dwrite"); /* Close objects */ @@ -1420,22 +1484,25 @@ test_reference_group(void) ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy reference */ + ret = H5Rdestroy(&wref); + CHECK(ret, FAIL, "H5Rdestroy"); /* Re-open file */ - fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(fid, FAIL, "H5Fopen"); + fid = H5Fopen(FILE_REF_GRP, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fopen"); /* Re-open dataset */ did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dopen2"); + CHECK(did, H5I_INVALID_HID, "H5Dopen2"); /* Read in the reference */ - ret = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); + ret = H5Dread(did, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); CHECK(ret, FAIL, "H5Dread"); /* Dereference to get the group */ - gid = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &rref); - CHECK(gid, FAIL, "H5Rdereference2"); + gid = H5Ropen_object((const H5R_ref_t *)&rref, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, H5I_INVALID_HID, "H5Ropen_object"); /* Iterate through objects in dereferenced group */ ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); @@ -1447,7 +1514,7 @@ test_reference_group(void) VERIFY(ginfo.nlinks, 3, "H5Gget_info"); size = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, objname, (size_t)NAME_SIZE, H5P_DEFAULT); - CHECK(size, FAIL, "H5Lget_name_by_idx"); + CHECK(size, (-1), "H5Lget_name_by_idx"); VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); @@ -1469,66 +1536,618 @@ test_reference_group(void) CHECK(ret, FAIL, "H5Gclose"); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy reference */ + ret = H5Rdestroy(&rref); + CHECK(ret, FAIL, "H5Rdestroy"); } /* test_reference_group() */ -#ifndef H5_NO_DEPRECATED_SYMBOLS /**************************************************************** ** -** test_reference_compat(): Test basic H5R (reference) object reference code. -** Tests deprecated API routines +** test_reference_attr(): Test basic H5R (reference) attribute reference code. +** Tests references to attributes on various kinds of objects ** ****************************************************************/ static void -test_reference_compat(void) +test_reference_attr(void) { - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset, dset2; /* Dataset ID */ - hid_t group, group2; /* Group ID */ - hid_t sid1, /* Dataspace IDs */ - sid2; - hid_t tid1, tid2; /* Datatype ID */ - hsize_t dims1[] = {SPACE1_DIM1}, - dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; - hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ - hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ - hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ - hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ - hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ - hobj_ref_t *wbuf_obj, /* Buffer to write to disk */ - *rbuf_obj; /* Buffer read from disk */ - hdset_reg_ref_t *wbuf_reg, /* Buffer to write to disk */ - *rbuf_reg; /* Buffer read from disk */ - H5G_obj_t obj_type; /* Object type */ - herr_t ret; /* Generic return value */ + hid_t fid; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t ref_wbuf[SPACE1_DIM1], /* Buffer to write to disk */ + ref_rbuf[SPACE1_DIM1]; /* Buffer read from disk */ + unsigned wbuf[SPACE1_DIM1], rbuf[SPACE1_DIM1]; + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* Local index variables */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Attribute Reference Functions\n")); + + /* Create file */ + fid = H5Fcreate(FILE_REF_ATTR, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(group, "Attr2", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 1); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)(i * 3); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Create an attribute for the datatype */ + attr = H5Acreate2(tid, "Attr3", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 2); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid, "Dataset3", H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create reference to dataset1 attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Dataset1", "Attr1", &ref_wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to dataset2 attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Dataset2", "Attr1", &ref_wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to group attribute */ + ret = H5Rcreate_attr(fid, "/Group1", "Attr2", &ref_wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); + + /* Create reference to named datatype attribute */ + ret = H5Rcreate_attr(fid, "/Group1/Datatype1", "Attr3", &ref_wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid = H5Fopen(FILE_REF_ATTR, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid, "/Dataset3", H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open attribute on dataset object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Check information in referenced dataset */ + sid = H5Aget_space(attr); + CHECK(sid, H5I_INVALID_HID, "H5Aget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i * 3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on group object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 1), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on named datatype object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 2), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + for (i = 0; i < SPACE1_DIM1; i++) { + ret = H5Rdestroy(&ref_wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&ref_rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } +} /* test_reference_attr() */ + +/**************************************************************** +** +** test_reference_external(): +** Tests external references on various kinds of objects +** +****************************************************************/ +static void +test_reference_external(void) +{ + hid_t fid1, fid2; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t group; /* Group ID */ + hid_t attr; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t ref_wbuf[SPACE1_DIM1], /* Buffer to write to disk */ + ref_rbuf[SPACE1_DIM1]; /* Buffer read from disk */ + unsigned wbuf[SPACE1_DIM1], rbuf[SPACE1_DIM1]; + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* Local index variables */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing External References Functions\n")); + + /* Create file */ + fid1 = H5Fcreate(FILE_REF_EXT1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(group, "Attr2", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 1); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Create an attribute for the dataset */ + attr = H5Acreate2(dataset, "Attr1", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)(i * 3); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Create an attribute for the datatype */ + attr = H5Acreate2(tid, "Attr3", H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Acreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)((i * 3) + 2); + + /* Write attribute to disk */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, wbuf); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create reference to dataset1 attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset1", "Attr1", &ref_wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to dataset2 attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Dataset2", "Attr1", &ref_wbuf[1]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + /* Create reference to group attribute */ + ret = H5Rcreate_attr(fid1, "/Group1", "Attr2", &ref_wbuf[2]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); + + /* Create reference to named datatype attribute */ + ret = H5Rcreate_attr(fid1, "/Group1/Datatype1", "Attr3", &ref_wbuf[3]); + CHECK(ret, FAIL, "H5Rcreate_attr"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&ref_wbuf[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create file */ + fid2 = H5Fcreate(FILE_REF_EXT2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid2, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid = H5Screate_simple(SPACE1_RANK, dims, NULL); + CHECK(sid, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid2, "Dataset3", H5T_STD_REF, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid2 = H5Fopen(FILE_REF_EXT2, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid2, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid2, "/Dataset3", H5P_DEFAULT); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open attribute on dataset object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Check information in referenced dataset */ + sid = H5Aget_space(attr); + CHECK(sid, H5I_INVALID_HID, "H5Aget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid); + VERIFY(ret, SPACE1_DIM1, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i * 3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on group object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 1), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Open attribute on named datatype object */ + attr = H5Ropen_attr((const H5R_ref_t *)&ref_rbuf[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, H5I_INVALID_HID, "H5Ropen_attr"); + + /* Read from disk */ + ret = H5Aread(attr, H5T_NATIVE_UINT, rbuf); + CHECK(ret, FAIL, "H5Aread"); + + for(tu32 = (unsigned *)rbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)((i * 3) + 2), "Data"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid2); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + for (i = 0; i < SPACE1_DIM1; i++) { + ret = H5Rdestroy(&ref_wbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&ref_rbuf[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } +} /* test_reference_external() */ + +/**************************************************************** +** +** test_reference_compat_conv(): Test basic H5R (reference) object reference code. +** Tests deprecated API routines and type conversion. +** +****************************************************************/ +static void +test_reference_compat_conv(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, dset2; /* Dataset ID */ + hid_t group, group2; /* Group ID */ + hid_t sid1, sid2, sid3; /* Dataspace IDs */ + hid_t tid1, tid2; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}, + dims3[] = {2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK];/* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hobj_ref_t *wbuf_obj; /* Buffer to write to disk */ + H5R_ref_t *rbuf_obj; /* Buffer read from disk */ + hdset_reg_ref_t *wbuf_reg; /* Buffer to write to disk */ + H5R_ref_t *rbuf_reg; /* Buffer read from disk */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + unsigned int i; /* Counter */ /* Output message about test being performed */ MESSAGE(5, ("Testing Deprecated Object Reference Functions\n")); /* Allocate write & read buffers */ wbuf_obj = (hobj_ref_t *)HDcalloc(sizeof(hobj_ref_t), SPACE1_DIM1); - rbuf_obj = (hobj_ref_t *)HDmalloc(sizeof(hobj_ref_t) * SPACE1_DIM1); - wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), SPACE1_DIM1); - rbuf_reg = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + rbuf_obj = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), SPACE1_DIM1); + wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), 2); + rbuf_reg = (H5R_ref_t *)HDcalloc(sizeof(H5R_ref_t), 2); /* Create file */ - fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); + fid1 = H5Fcreate(FILE_REF_COMPAT, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); /* Create dataspace for datasets */ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); /* Create another dataspace for datasets */ sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); - CHECK(sid2, FAIL, "H5Screate_simple"); + CHECK(sid2, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create another dataspace for datasets */ + sid3 = H5Screate_simple(SPACE1_RANK, dims3, NULL); + CHECK(sid3, H5I_INVALID_HID, "H5Screate_simple"); /* Create a group */ group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(group, FAIL, "H5Gcreate2"); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); /* Create a dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1536,7 +2155,7 @@ test_reference_compat(void) /* Create another dataset (inside Group1) */ dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1544,7 +2163,7 @@ test_reference_compat(void) /* Create a datatype to refer to */ tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); - CHECK(tid1, FAIL, "H5Tcreate"); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); /* Insert fields */ ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); @@ -1568,25 +2187,24 @@ test_reference_compat(void) ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); - /* Create a dataset with object reference datatype */ dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, H5I_INVALID_HID); CHECK(ret, FAIL, "H5Rcreate"); /* Create reference to dataset */ - ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); + ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, H5I_INVALID_HID); CHECK(ret, FAIL, "H5Rcreate"); /* Create reference to group */ - ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); + ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, H5I_INVALID_HID); CHECK(ret, FAIL, "H5Rcreate"); /* Create reference to named datatype */ - ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); + ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, H5I_INVALID_HID); CHECK(ret, FAIL, "H5Rcreate"); /* Write references to disk */ @@ -1597,16 +2215,19 @@ test_reference_compat(void) ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); - /* Create a dataset with region reference datatype */ - dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dcreate2"); + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); /* Select 6x6 hyperslab for first reference */ - start[0] = 2; start[1] = 2; - stride[0] = 1; stride[1] = 1; - count[0] = 1; count[1] = 1; - block[0] = 6; block[1] = 6; + start[0] = 2; + start[1] = 2; + stride[0] = 1; + stride[1] = 1; + count[0] = 1; + count[1] = 1; + block[0] = 6; + block[1] = 6; ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); @@ -1640,69 +2261,69 @@ test_reference_compat(void) ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); - /* Close disk dataspaces */ ret = H5Sclose(sid1); CHECK(ret, FAIL, "H5Sclose"); ret = H5Sclose(sid2); CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); /* Close file */ ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); - /* Re-open the file */ - fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + fid1 = H5Fopen(FILE_REF_COMPAT, H5F_ACC_RDWR, H5P_DEFAULT); CHECK(fid1, FAIL, "H5Fopen"); /* Open the object reference dataset */ dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(dataset, FAIL, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); CHECK(ret, FAIL, "H5Dread"); /* Verify type of objects pointed at */ - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[0]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[1]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[2]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_GROUP, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[2], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[3]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_TYPE, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_obj[3], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type3"); /* Make sure the referenced objects can be opened */ - dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[0]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[1]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - group2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[2]); - CHECK(group2, FAIL, "H5Rdereference1"); + group2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[2], H5P_DEFAULT, H5P_DEFAULT); + CHECK(group2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Gclose(group2); CHECK(ret, FAIL, "H5Gclose"); - tid2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[3]); - CHECK(tid2, FAIL, "H5Rdereference1"); + tid2 = H5Ropen_object((const H5R_ref_t *)&rbuf_obj[3], H5P_DEFAULT, H5P_DEFAULT); + CHECK(tid2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Tclose(tid2); CHECK(ret, FAIL, "H5Tclose"); @@ -1714,36 +2335,30 @@ test_reference_compat(void) /* Open the dataset region reference dataset */ dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); - CHECK(ret, FAIL, "H5Dopen2"); + CHECK(ret, H5I_INVALID_HID, "H5Dopen2"); /* Read selection from disk */ - ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); CHECK(ret, FAIL, "H5Dread"); /* Verify type of objects pointed at */ - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_reg[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); - CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); - - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[2]); - VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); - - obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[3]); - VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&rbuf_reg[1], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); /* Make sure the referenced objects can be opened */ - dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_reg[0], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); - dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); - CHECK(dset2, FAIL, "H5Rdereference1"); + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf_reg[1], H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); @@ -1756,13 +2371,424 @@ test_reference_compat(void) ret = H5Fclose(fid1); CHECK(ret, FAIL, "H5Fclose"); + /* Destroy references */ + for(i = 0; i < dims1[0]; i++) { + ret = H5Rdestroy(&rbuf_obj[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + for(i = 0; i < dims3[0]; i++) { + ret = H5Rdestroy(&rbuf_reg[i]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + /* Free memory buffers */ HDfree(wbuf_obj); HDfree(rbuf_obj); HDfree(wbuf_reg); HDfree(rbuf_reg); } /* test_reference_compat() */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/**************************************************************** +** +** test_reference_perf(): Test basic H5R (reference) object reference +** performance. +** +****************************************************************/ +static void +test_reference_perf(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {1}; + hid_t dapl_id; /* Dataset access property list */ + H5R_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + H5R_ref_t *wbuf_reg, /* buffer to write to disk */ + *rbuf_reg; /* buffer read from disk */ + hobj_ref_t *wbuf_deprec,/* deprecated references */ + *rbuf_deprec;/* deprecated references */ + hdset_reg_ref_t *wbuf_reg_deprec, /* deprecated references*/ + *rbuf_reg_deprec; /* deprecated references*/ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* Counters */ + H5O_type_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + double t1, t2, t; /* Timers */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Object Reference Performance\n")); + + /* Allocate write & read buffers */ + wbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_deprec = (hobj_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)), SPACE1_DIM1); + rbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf_deprec = (hobj_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)), SPACE1_DIM1); + tbuf = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_reg = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + rbuf_reg = (H5R_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), SPACE1_DIM1); + wbuf_reg_deprec = (hdset_reg_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hdset_reg_ref_t)), SPACE1_DIM1); + rbuf_reg_deprec = (hdset_reg_ref_t *)HDcalloc(MAX(sizeof(unsigned), sizeof(hdset_reg_ref_t)), SPACE1_DIM1); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Create file */ + fid1 = H5Fcreate(FILE_REF_OBJ, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, H5I_INVALID_HID, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, H5I_INVALID_HID, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, H5I_INVALID_HID, "H5Gcreate2"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, H5I_INVALID_HID, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&wbuf[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Object reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Create reference to dataset */ + ret = H5Rcreate_object(fid1, "/Group1/Dataset1", &wbuf[0]); + CHECK(ret, FAIL, "H5Rcreate_object"); + ret = H5Rget_obj_type3((const H5R_ref_t *)&wbuf[0], H5P_DEFAULT, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type3"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type3"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Object reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + ret = H5Rcreate(&wbuf_deprec[0], fid1, "/Group1/Dataset1", H5R_OBJECT1, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_deprec[0], fid1, "/Group1/Dataset1", H5R_OBJECT1, H5I_INVALID_HID); + CHECK(ret, FAIL, "H5Rcreate"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_deprec); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset5", H5T_STD_REF, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + /* Store first dataset region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, &wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Region reference create time: %lfs\n", t / MAX_ITER_CREATE); + + /* Store first dataset region */ + ret = H5Rcreate_region(fid1, "/Group1/Dataset1", sid1, &wbuf_reg[0]); + CHECK(ret, FAIL, "H5Rcreate_region"); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Region reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset6", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dcreate2"); + + t = 0; + for(i = 0; i < MAX_ITER_CREATE; i++) { + t1 = H5_get_time(); + /* Store first dataset region */ + ret = H5Rcreate(&wbuf_reg_deprec[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION1, sid1); + CHECK(ret, FAIL, "H5Rcreate"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference create time: %lfs\n", t / MAX_ITER_CREATE); + + t = 0; + for(i = 0; i < MAX_ITER_WRITE; i++) { + t1 = H5_get_time(); + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg_deprec); + CHECK(ret, FAIL, "H5Dwrite"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference write time: %lfs\n", t / MAX_ITER_WRITE); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE_REF_OBJ, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, H5I_INVALID_HID, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&rbuf[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Object reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open dataset object */ + dset2 = H5Ropen_object((const H5R_ref_t *)&rbuf[0], H5P_DEFAULT, dapl_id); + CHECK(dset2, H5I_INVALID_HID, "H5Ropen_object"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, H5I_INVALID_HID, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, dims1[0], "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu32 = (unsigned *)tbuf, i = 0; i < (int)dims1[0]; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i*3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_deprec); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated object reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset5", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + ret = H5Rdestroy(&rbuf_reg[0]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + HDprintf("--- Region reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset6", H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + + t = 0; + for(i = 0; i < MAX_ITER_READ; i++) { + t1 = H5_get_time(); + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg_deprec); + CHECK(ret, FAIL, "H5Dread"); + t2 = H5_get_time(); + t += t2 - t1; + } + HDprintf("--- Deprecated region reference read time: %lfs\n", t / MAX_ITER_READ); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Destroy references */ + for(j = 0; j < (int)dims1[0]; j++) { + ret = H5Rdestroy(&wbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&wbuf_reg[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + ret = H5Rdestroy(&rbuf_reg[j]); + CHECK(ret, FAIL, "H5Rdestroy"); + } + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(wbuf_reg); + HDfree(rbuf_reg); + HDfree(wbuf_deprec); + HDfree(rbuf_deprec); + HDfree(wbuf_reg_deprec); + HDfree(rbuf_reg_deprec); + HDfree(tbuf); +} /* test_reference_perf() */ /**************************************************************** ** @@ -1794,11 +2820,13 @@ test_reference(void) } /* end high bound */ } /* end low bound */ - test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ - test_reference_group(); /* Test operations on dereferenced groups */ -#ifndef H5_NO_DEPRECATED_SYMBOLS - test_reference_compat(); /* Test operations with old API routines */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ + test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ + test_reference_group(); /* Test operations on dereferenced groups */ + test_reference_attr(); /* Test attribute references */ + test_reference_external(); /* Test external references */ + test_reference_compat_conv(); /* Test operations with old types */ + + test_reference_perf(); } /* test_reference() */ @@ -1820,8 +2848,14 @@ test_reference(void) void cleanup_reference(void) { - remove(FILE1); - remove(FILE2); - remove(FILE3); + HDremove(FILE_REF_PARAM); + HDremove(FILE_REF_OBJ); + HDremove(FILE_REF_REG); + HDremove(FILE_REF_REG_1D); + HDremove(FILE_REF_OBJ_DEL); + HDremove(FILE_REF_GRP); + HDremove(FILE_REF_ATTR); + HDremove(FILE_REF_EXT1); + HDremove(FILE_REF_EXT2); + HDremove(FILE_REF_COMPAT); } - diff --git a/test/trefer_deprec.c b/test/trefer_deprec.c new file mode 100644 index 0000000..949f41b --- /dev/null +++ b/test/trefer_deprec.c @@ -0,0 +1,1827 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*********************************************************** +* +* Test program: trefer_deprec +* +* Test the Reference functionality +* +*************************************************************/ + +#include "testhdf5.h" + +#define FILE1 "trefer1.h5" +#define FILE2 "trefer2.h5" +#define FILE3 "trefer3.h5" + +/* 1-D dataset with fixed dimensions */ +#define SPACE1_RANK 1 +#define SPACE1_DIM1 4 + +/* 2-D dataset with fixed dimensions */ +#define SPACE2_RANK 2 +#define SPACE2_DIM1 10 +#define SPACE2_DIM2 10 + +/* Larger 1-D dataset with fixed dimensions */ +#define SPACE3_RANK 1 +#define SPACE3_DIM1 100 + +/* Element selection information */ +#define POINT1_NPOINTS 10 + +/* Compound datatype */ +typedef struct s1_t { + unsigned int a; + unsigned int b; + float c; +} s1_t; + +#define GROUPNAME "/group" +#define GROUPNAME2 "group2" +#define GROUPNAME3 "group3" +#define DSETNAME "/dset" +#define DSETNAME2 "dset2" +#define NAME_SIZE 16 + + +/**************************************************************** +** +** test_reference_params(): Test basic H5R (reference) parameters +** for correct processing +** +****************************************************************/ +static void +test_reference_params(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}; + hobj_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i; /* counting variables */ + const char *write_comment = "Foo!"; /* Comments for group */ + hid_t ret_id; /* Generic hid_t return value */ + ssize_t name_size; /* Size of reference name */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Reference Parameters\n")); + + /* Allocate write & read buffers */ + wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Set group's comment */ + ret = H5Oset_comment(group, write_comment); + CHECK(ret, FAIL, "H5Oset_comment"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dcreate2"); + + /* Test parameters to H5Rcreate */ + ret = H5Rcreate(NULL, fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate ref"); + ret = H5Rcreate(&wbuf[0], (hid_t)-1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate loc_id"); + ret = H5Rcreate(&wbuf[0], fid1, NULL, H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate name"); + ret = H5Rcreate(&wbuf[0], fid1, "", H5R_OBJECT, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate null name"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate type"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, (hid_t)-1); + VERIFY(ret, FAIL, "H5Rcreate region space"); + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_MAXTYPE, (hid_t)0); + VERIFY(ret, FAIL, "H5Rcreate space"); + + /* Test parameters to H5Rdereference */ + dset2 = H5Rdereference2((hid_t)-1, H5P_DEFAULT, H5R_OBJECT, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 loc_id"); + dset2 = H5Rdereference2(dataset, (hid_t)-1, H5R_OBJECT, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 oapl_id"); + dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, NULL); + VERIFY(dset2, FAIL, "H5Rdereference2 ref"); + dset2 = H5Rdereference2(dataset, dapl_id, H5R_MAXTYPE, &rbuf[0]); + VERIFY(dset2, FAIL, "H5Rdereference2 type"); + + /* Test parameters to H5Rget_obj_type2 */ + ret = H5Rget_obj_type2((hid_t)-1, H5R_OBJECT, &rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 loc_id"); + ret = H5Rget_obj_type2(fid1, H5R_OBJECT, NULL, NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 ref"); + ret = H5Rget_obj_type2(fid1, H5R_MAXTYPE, &rbuf[0], NULL); + VERIFY(ret, FAIL, "H5Rget_obj_type2 type"); + + /* Test parameters to H5Rget_name */ + name_size = H5Rget_name((hid_t)-1, H5R_DATASET_REGION, &rbuf[0], NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name loc_id"); + name_size = H5Rget_name(fid1, H5R_DATASET_REGION, NULL, NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name ref"); + name_size = H5Rget_name(fid1, H5R_MAXTYPE, &rbuf[0], NULL, 0); + VERIFY(name_size, FAIL, "H5Rget_name type"); + + /* Test parameters to H5Rget_region */ + ret_id = H5Rget_region((hid_t)-1, H5R_OBJECT, &rbuf[0]); + VERIFY(ret_id, FAIL, "H5Rget_region loc_id"); + ret_id = H5Rget_region(fid1, H5R_OBJECT, NULL); + VERIFY(ret_id, FAIL, "H5Rget_region ref"); + ret_id = H5Rget_region(fid1, H5R_OBJECT, &rbuf[0]); + VERIFY(ret_id, FAIL, "H5Rget_region type"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(tbuf); +} /* test_reference_obj() */ + +/**************************************************************** +** +** test_reference_obj(): Test basic H5R (reference) object reference code. +** Tests references to various kinds of objects +** +****************************************************************/ +static void +test_reference_obj(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t group; /* Group ID */ + hid_t sid1; /* Dataspace ID */ + hid_t tid1; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}; + hid_t dapl_id; /* Dataset access property list */ + hobj_ref_t *wbuf, /* buffer to write to disk */ + *rbuf, /* buffer read from disk */ + *tbuf; /* temp. buffer read from disk */ + hobj_ref_t nvrbuf[3]={0,101,1000000000}; /* buffer with non-valid refs */ + unsigned *tu32; /* Temporary pointer to uint32 data */ + int i, j; /* counting variables */ + const char *write_comment="Foo!"; /* Comments for group */ + char read_comment[10]; + H5O_type_t obj_type; /* Object type */ + ssize_t size; /* Comment length */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Object Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + rbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + tbuf = (hobj_ref_t *)HDmalloc(MAX(sizeof(unsigned), sizeof(hobj_ref_t)) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Set group's comment */ + ret = H5Oset_comment(group, write_comment); + CHECK(ret, FAIL, "H5Oset_comment"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + for(tu32 = (unsigned *)wbuf, i = 0; i < SPACE1_DIM1; i++) + *tu32++ = (unsigned)i * 3; + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[1], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Create reference to group */ + ret = H5Rcreate(&wbuf[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[2], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_GROUP, "H5Rget_obj_type2"); + + /* Create reference to named datatype */ + ret = H5Rcreate(&wbuf[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &wbuf[3], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_NAMED_DATATYPE, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Open dataset object */ + dset2 = H5Rdereference2(dataset, dapl_id, H5R_OBJECT, &rbuf[0]); + CHECK(dset2, FAIL, "H5Rdereference2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 4, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, tbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu32 = (unsigned *)tbuf, i = 0; i < SPACE1_DIM1; i++, tu32++) + VERIFY(*tu32, (uint32_t)(i*3), "Data"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Open group object. GAPL isn't supported yet. But it's harmless to pass in */ + group = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[2]); + CHECK(group, FAIL, "H5Rdereference2"); + + /* Get group's comment */ + size = H5Oget_comment(group, read_comment, (size_t)10); + CHECK(size, FAIL, "H5Oget_comment"); + + /* Check for correct comment value */ + if(HDstrcmp(write_comment, read_comment) != 0) + TestErrPrintf("Error! Incorrect group comment, wanted: %s, got: %s\n",write_comment,read_comment); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + /* Open datatype object. TAPL isn't supported yet. But it's harmless to pass in */ + tid1 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &rbuf[3]); + CHECK(tid1, FAIL, "H5Rdereference2"); + + /* Verify correct datatype */ + { + H5T_class_t tclass; + + tclass = H5Tget_class(tid1); + VERIFY(tclass, H5T_COMPOUND, "H5Tget_class"); + + ret= H5Tget_nmembers(tid1); + VERIFY(ret, 3, "H5Tget_nmembers"); + } + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &nvrbuf[j], &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type2"); + } /* end for */ + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(tbuf); +} /* test_reference_obj() */ + +/**************************************************************** +** +** test_reference_region(): Test basic H5R (reference) object reference code. +** Tests references to various kinds of objects +** +** Note: The libver_low/libver_high parameters are added to create the file +** with the low and high bounds setting in fapl. +** Please see the RFC for "H5Sencode/H5Sdecode Format Change". +** +****************************************************************/ +static void +test_reference_region(H5F_libver_t libver_low, H5F_libver_t libver_high) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl = -1; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid2; /* Dataspace ID #2 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE2_RANK]; /* Selection bounds */ + hsize_t high[SPACE2_RANK]; /* Selection bounds */ + hdset_reg_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + hdset_reg_ref_t nvrbuf[3]={{0},{101},{255}}; /* buffer with non-valid refs */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Type of object */ + int i, j; /* counting variables */ + hssize_t hssize_ret; /* hssize_t return value */ + htri_t tri_ret; /* htri_t return value */ + herr_t ret; /* Generic return value */ + hdset_reg_ref_t undef_reg[1]; /* test for undefined reference */ + hid_t dset_NA; /* Dataset id for undefined reference */ + hid_t space_NA; /* Dataspace id for undefined reference */ + hsize_t dims_NA[1] = {1}; /* Dims array for undefined reference */ + hdset_reg_ref_t wdata_NA[1], /* Write buffer */ + rdata_NA[1]; /* Read buffer */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Dataset Region Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); + rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE2_DIM1 * SPACE2_DIM2); + drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)(SPACE2_DIM1 * SPACE2_DIM2)); + + /* Create file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Set the low/high version bounds in fapl */ + ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + + /* Create file with the fapl */ + fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + CHECK(sid2, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a dataset */ + dset2 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset2, FAIL, "H5Dcreate2"); + + for(tu8 = dwbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++) + *tu8++ = (uint8_t)(i * 3); + + /* Write selection to disk */ + ret = H5Dwrite(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create dataspace for the reference dataset */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset */ + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); + + /* Create references */ + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; start[1] = 2; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = 6; block[1] = 6; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + + /* Store first dataset region */ + ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 6; coord1[0][1] = 9; + coord1[1][0] = 2; coord1[1][1] = 2; + coord1[2][0] = 8; coord1[2][1] = 4; + coord1[3][0] = 1; coord1[3][1] = 6; + coord1[4][0] = 2; coord1[4][1] = 8; + coord1[5][0] = 3; coord1[5][1] = 2; + coord1[6][0] = 0; coord1[6][1] = 4; + coord1[7][0] = 9; coord1[7][1] = 0; + coord1[8][0] = 7; coord1[8][1] = 1; + coord1[9][0] = 3; coord1[9][1] = 3; + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_npoints"); + + /* Store second dataset region */ + ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Select unlimited hyperslab for third reference */ + start[0] = 1; start[1] = 8; + stride[0] = 4; stride[1] = 1; + count[0] = H5S_UNLIMITED; count[1] = 1; + block[0] = 2; block[1] = 2; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + + /* Store third dataset region */ + H5E_BEGIN_TRY { + ret = H5Rcreate(&wbuf[2], fid1, "/Dataset2", H5R_DATASET_REGION, sid2); + } H5E_END_TRY; + + if(libver_high < H5F_LIBVER_V110) + VERIFY(ret, FAIL, "H5Rcreate"); + else + CHECK(ret, FAIL, "H5Rcreate"); + + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* + * Store a dataset region reference which will not get written to disk + */ + + /* Create reference to an element in dset1 */ + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + ret = H5Rcreate(&wdata_NA[0], fid1, "/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create the dataspace of the region references */ + space_NA = H5Screate_simple(1, dims_NA, NULL); + CHECK(space_NA, FAIL, "H5Screate_simple"); + + /* Create the dataset and write the region references to it */ + dset_NA = H5Dcreate2(fid1, "DS_NA", H5T_STD_REF_DSETREG, space_NA, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dcreate"); + + /* Close and release resources for undefined region reference tests */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(space_NA); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close uint8 dataset dataspace */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); + CHECK(fid1, FAIL, "H5Fopen"); + + /* + * Start the test of an undefined reference + */ + + /* Open the dataset of the undefined references */ + dset_NA = H5Dopen2(fid1, "DS_NA", H5P_DEFAULT); + CHECK(dset_NA, FAIL, "H5Dopen2"); + + /* Read the data */ + ret = H5Dread(dset_NA, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_NA); + CHECK(ret, FAIL, "H5Dread"); + + /* + * Dereference an undefined reference (should fail) + */ + H5E_BEGIN_TRY { + dset2 = H5Rdereference2(dset_NA, H5P_DEFAULT, H5R_DATASET_REGION, &rdata_NA[0]); + } H5E_END_TRY; + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Close and release resources. */ + ret = H5Dclose(dset_NA); + CHECK(ret, FAIL, "H5Dclose"); + + /* This close should fail since H5Rdereference2 never created + * the id of the referenced object. */ + H5E_BEGIN_TRY { + ret = H5Dclose(dset2); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dclose"); + + /* + * End the test of an undefined reference + */ + + /* Open the dataset */ + dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Try to read an unaddressed dataset */ + dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, undef_reg); + VERIFY(dset2, FAIL, "H5Rdereference2 haddr_undef"); + + /* Try to open objects */ + dset2 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); + CHECK(dset2, FAIL, "H5Rdereference2"); + + /* Check what H5Rget_obj_type2 function returns */ + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset2); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset2, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu8 = (uint8_t *)drbuf, i = 0; i < (SPACE2_DIM1 * SPACE2_DIM2); i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + + /* Get the hyperslab selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 36, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid2); + VERIFY(ret, 1, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 2, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 7, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(low[1], 2, "Selection Bounds"); + VERIFY(high[0], 7, "Selection Bounds"); + VERIFY(high[1], 7, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get the element selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid2); + VERIFY(ret, 10, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE2_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid2, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[0][1], "Element Coordinates"); + VERIFY(coords[2], coord1[1][0], "Element Coordinates"); + VERIFY(coords[3], coord1[1][1], "Element Coordinates"); + VERIFY(coords[4], coord1[2][0], "Element Coordinates"); + VERIFY(coords[5], coord1[2][1], "Element Coordinates"); + VERIFY(coords[6], coord1[3][0], "Element Coordinates"); + VERIFY(coords[7], coord1[3][1], "Element Coordinates"); + VERIFY(coords[8], coord1[4][0], "Element Coordinates"); + VERIFY(coords[9], coord1[4][1], "Element Coordinates"); + VERIFY(coords[10], coord1[5][0], "Element Coordinates"); + VERIFY(coords[11], coord1[5][1], "Element Coordinates"); + VERIFY(coords[12], coord1[6][0], "Element Coordinates"); + VERIFY(coords[13], coord1[6][1], "Element Coordinates"); + VERIFY(coords[14], coord1[7][0], "Element Coordinates"); + VERIFY(coords[15], coord1[7][1], "Element Coordinates"); + VERIFY(coords[16], coord1[8][0], "Element Coordinates"); + VERIFY(coords[17], coord1[8][1], "Element Coordinates"); + VERIFY(coords[18], coord1[9][0], "Element Coordinates"); + VERIFY(coords[19], coord1[9][1], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid2, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 0, "Selection Bounds"); + VERIFY(low[1], 0, "Selection Bounds"); + VERIFY(high[0], 9, "Selection Bounds"); + VERIFY(high[1], 9, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + if(libver_high >= H5F_LIBVER_V110) { + /* Get the unlimited selection */ + sid2 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[2]); + CHECK(sid2, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + hssize_ret = H5Sget_select_npoints(sid2); + VERIFY(hssize_ret, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + tri_ret = H5Sis_regular_hyperslab(sid2); + CHECK(tri_ret, FAIL, "H5Sis_regular_hyperslab"); + VERIFY(tri_ret, TRUE, "H5Sis_regular_hyperslab Result"); + ret = H5Sget_regular_hyperslab(sid2, start, stride, count, block); + CHECK(ret, FAIL, "H5Sget_regular_hyperslab"); + VERIFY(start[0], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(start[1], (hsize_t)8, "Hyperslab Coordinates"); + VERIFY(stride[0], (hsize_t)4, "Hyperslab Coordinates"); + VERIFY(stride[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(count[0], H5S_UNLIMITED, "Hyperslab Coordinates"); + VERIFY(count[1], (hsize_t)1, "Hyperslab Coordinates"); + VERIFY(block[0], (hsize_t)2, "Hyperslab Coordinates"); + VERIFY(block[1], (hsize_t)2, "Hyperslab Coordinates"); + + /* Close region space */ + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + } + + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Attempting to retrieve type of object using non-valid refs */ + for(j = 0; j < 3; j++) { + H5E_BEGIN_TRY { + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &nvrbuf[j], &obj_type); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Rget_obj_type2"); + } /* end for */ + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(dwbuf); + HDfree(drbuf); +} /* test_reference_region() */ + +/**************************************************************** +** +** test_reference_region_1D(): Test H5R (reference) object reference code. +** Tests 1-D references to various kinds of objects +** +** Note: The libver_low/libver_high parameters are added to create the file +** with the low and high bounds setting in fapl. +** Please see the RFC for "H5Sencode/H5Sdecode Format Change". +** +****************************************************************/ +static void +test_reference_region_1D(H5F_libver_t libver_low, H5F_libver_t libver_high) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t fapl = -1; /* File access property list */ + hid_t dset1, /* Dataset ID */ + dset3; /* Dereferenced dataset ID */ + hid_t sid1, /* Dataspace ID #1 */ + sid3; /* Dataspace ID #3 */ + hid_t dapl_id; /* Dataset access property list */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims3[] = {SPACE3_DIM1}; + hsize_t start[SPACE3_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE3_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE3_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE3_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE3_RANK]; /* Coordinates for point selection */ + hsize_t *coords; /* Coordinate buffer */ + hsize_t low[SPACE3_RANK]; /* Selection bounds */ + hsize_t high[SPACE3_RANK]; /* Selection bounds */ + hdset_reg_ref_t *wbuf, /* buffer to write to disk */ + *rbuf; /* buffer read from disk */ + uint8_t *dwbuf, /* Buffer for writing numeric data to disk */ + *drbuf; /* Buffer for reading numeric data from disk */ + uint8_t *tu8; /* Temporary pointer to uint8 data */ + H5O_type_t obj_type; /* Object type */ + int i; /* counting variables */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing 1-D Dataset Region Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); + rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE3_DIM1); + drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); + + /* Create the file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Set the low/high version bounds in fapl */ + ret = H5Pset_libver_bounds(fapl, libver_low, libver_high); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + + /* Create file with the fapl */ + fid1 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid3 = H5Screate_simple(SPACE3_RANK, dims3, NULL); + CHECK(sid3, FAIL, "H5Screate_simple"); + + /* Create dataset access property list */ + dapl_id = H5Pcreate(H5P_DATASET_ACCESS); + CHECK(dapl_id, FAIL, "H5Pcreate"); + + /* Create a dataset */ + dset3 = H5Dcreate2(fid1, "Dataset2", H5T_STD_U8LE, sid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dset3, FAIL, "H5Dcreate2"); + + for(tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) + *tu8++ = (uint8_t)(i * 3); + + /* Write selection to disk */ + ret = H5Dwrite(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dwbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create dataspace for the reference dataset */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset */ + dset1 = H5Dcreate2(fid1, "Dataset1", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dcreate2"); + + /* Create references */ + + /* Select 15 2x1 hyperslabs for first reference */ + start[0] = 2; + stride[0] = 5; + count[0] = 15; + block[0] = 2; + ret = H5Sselect_hyperslab(sid3, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 30, "H5Sget_select_npoints"); + + /* Store first dataset region */ + ret = H5Rcreate(&wbuf[0], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &wbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 16; + coord1[1][0] = 22; + coord1[2][0] = 38; + coord1[3][0] = 41; + coord1[4][0] = 52; + coord1[5][0] = 63; + coord1[6][0] = 70; + coord1[7][0] = 89; + coord1[8][0] = 97; + coord1[9][0] = 03; + ret = H5Sselect_elements(sid3, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_npoints"); + + /* Store second dataset region */ + ret = H5Rcreate(&wbuf[1], fid1, "/Dataset2", H5R_DATASET_REGION, sid3); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write selection to disk */ + ret = H5Dwrite(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close uint8 dataset dataspace */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dset1 = H5Dopen2(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dset1, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); + + /* Try to open objects */ + dset3 = H5Rdereference2(dset1, dapl_id, H5R_DATASET_REGION, &rbuf[0]); + CHECK(dset3, FAIL, "H5Rdereference2"); + + /* Check what H5Rget_obj_type2 function returns */ + ret = H5Rget_obj_type2(dset1, H5R_DATASET_REGION, &rbuf[0], &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Check information in referenced dataset */ + sid1 = H5Dget_space(dset3); + CHECK(sid1, FAIL, "H5Dget_space"); + + ret = (int)H5Sget_simple_extent_npoints(sid1); + VERIFY(ret, 100, "H5Sget_simple_extent_npoints"); + + /* Read from disk */ + ret = H5Dread(dset3, H5T_STD_U8LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, drbuf); + CHECK(ret, FAIL, "H5Dread"); + + for(tu8 = (uint8_t *)drbuf, i = 0; i < SPACE3_DIM1; i++, tu8++) + VERIFY(*tu8, (uint8_t)(i * 3), "Data"); + + /* Get the hyperslab selection */ + sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[0]); + CHECK(sid3, FAIL, "H5Rget_region"); + + /* Verify correct hyperslab selected */ + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 30, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_hyper_nblocks(sid3); + VERIFY(ret, 15, "H5Sget_select_hyper_nblocks"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE3_RANK * sizeof(hsize_t) * 2); /* allocate space for the hyperslab blocks */ + ret = H5Sget_select_hyper_blocklist(sid3, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + VERIFY(coords[0], 2, "Hyperslab Coordinates"); + VERIFY(coords[1], 3, "Hyperslab Coordinates"); + VERIFY(coords[2], 7, "Hyperslab Coordinates"); + VERIFY(coords[3], 8, "Hyperslab Coordinates"); + VERIFY(coords[4], 12, "Hyperslab Coordinates"); + VERIFY(coords[5], 13, "Hyperslab Coordinates"); + VERIFY(coords[6], 17, "Hyperslab Coordinates"); + VERIFY(coords[7], 18, "Hyperslab Coordinates"); + VERIFY(coords[8], 22, "Hyperslab Coordinates"); + VERIFY(coords[9], 23, "Hyperslab Coordinates"); + VERIFY(coords[10], 27, "Hyperslab Coordinates"); + VERIFY(coords[11], 28, "Hyperslab Coordinates"); + VERIFY(coords[12], 32, "Hyperslab Coordinates"); + VERIFY(coords[13], 33, "Hyperslab Coordinates"); + VERIFY(coords[14], 37, "Hyperslab Coordinates"); + VERIFY(coords[15], 38, "Hyperslab Coordinates"); + VERIFY(coords[16], 42, "Hyperslab Coordinates"); + VERIFY(coords[17], 43, "Hyperslab Coordinates"); + VERIFY(coords[18], 47, "Hyperslab Coordinates"); + VERIFY(coords[19], 48, "Hyperslab Coordinates"); + VERIFY(coords[20], 52, "Hyperslab Coordinates"); + VERIFY(coords[21], 53, "Hyperslab Coordinates"); + VERIFY(coords[22], 57, "Hyperslab Coordinates"); + VERIFY(coords[23], 58, "Hyperslab Coordinates"); + VERIFY(coords[24], 62, "Hyperslab Coordinates"); + VERIFY(coords[25], 63, "Hyperslab Coordinates"); + VERIFY(coords[26], 67, "Hyperslab Coordinates"); + VERIFY(coords[27], 68, "Hyperslab Coordinates"); + VERIFY(coords[28], 72, "Hyperslab Coordinates"); + VERIFY(coords[29], 73, "Hyperslab Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid3, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 2, "Selection Bounds"); + VERIFY(high[0], 73, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get the element selection */ + sid3 = H5Rget_region(dset1, H5R_DATASET_REGION, &rbuf[1]); + CHECK(sid3, FAIL, "H5Rget_region"); + + /* Verify correct elements selected */ + ret = (int)H5Sget_select_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_npoints"); + ret = (int)H5Sget_select_elem_npoints(sid3); + VERIFY(ret, 10, "H5Sget_select_elem_npoints"); + coords = (hsize_t *)HDmalloc((size_t)ret * SPACE3_RANK * sizeof(hsize_t)); /* allocate space for the element points */ + ret = H5Sget_select_elem_pointlist(sid3, (hsize_t)0, (hsize_t)ret, coords); + CHECK(ret, FAIL, "H5Sget_select_elem_pointlist"); + VERIFY(coords[0], coord1[0][0], "Element Coordinates"); + VERIFY(coords[1], coord1[1][0], "Element Coordinates"); + VERIFY(coords[2], coord1[2][0], "Element Coordinates"); + VERIFY(coords[3], coord1[3][0], "Element Coordinates"); + VERIFY(coords[4], coord1[4][0], "Element Coordinates"); + VERIFY(coords[5], coord1[5][0], "Element Coordinates"); + VERIFY(coords[6], coord1[6][0], "Element Coordinates"); + VERIFY(coords[7], coord1[7][0], "Element Coordinates"); + VERIFY(coords[8], coord1[8][0], "Element Coordinates"); + VERIFY(coords[9], coord1[9][0], "Element Coordinates"); + HDfree(coords); + ret = H5Sget_select_bounds(sid3, low, high); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low[0], 3, "Selection Bounds"); + VERIFY(high[0], 97, "Selection Bounds"); + + /* Close region space */ + ret = H5Sclose(sid3); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close first space */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close dereferenced Dataset */ + ret = H5Dclose(dset3); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close dataset access property list */ + ret = H5Pclose(dapl_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf); + HDfree(rbuf); + HDfree(dwbuf); + HDfree(drbuf); +} /* test_reference_region_1D() */ + +/**************************************************************** +** +** test_reference_obj_deleted(): Test H5R (reference) object reference code. +** Tests for correct failures for deleted and non-existent objects +** +****************************************************************/ +static void +test_reference_obj_deleted(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, /* Dataset ID */ + dset2; /* Dereferenced dataset ID */ + hid_t sid1; /* Dataspace ID */ + hobj_ref_t oref; /* Object Reference to test */ + H5O_type_t obj_type; /* Object type */ + haddr_t addr = HADDR_UNDEF; /* test for undefined reference */ + herr_t ret; /* Generic return value */ + + /* Create file */ + fid1 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create scalar dataspace for datasets */ + sid1 = H5Screate_simple(0, NULL, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create a dataset to reference (deleted later) */ + dataset = H5Dcreate2(fid1, "Dataset1", H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a dataset */ + dataset = H5Dcreate2(fid1, "Dataset2", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&oref, fid1, "/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type2(dataset, H5R_OBJECT, &oref, &obj_type); + CHECK(ret, FAIL, "H5Rget_obj_type2"); + VERIFY(obj_type, H5O_TYPE_DATASET, "H5Rget_obj_type2"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Delete referenced dataset */ + ret = H5Ldelete(fid1, "/Dataset1", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close disk dataspace */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file */ + fid1 = H5Fopen(FILE3, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the dataset */ + dataset = H5Dopen2(fid1, "/Dataset2", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dopen2"); + + /* Open undefined reference */ + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &addr); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Read selection from disk */ + HDmemset(&oref, 0, sizeof(hobj_ref_t)); + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &oref); + CHECK(ret, FAIL, "H5Dread"); + + /* Open deleted dataset object */ + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Open nonsense reference */ + HDmemset(&oref, 0, sizeof(hobj_ref_t)); + dset2 = H5Rdereference2(dataset, H5P_DEFAULT, H5R_OBJECT, &oref); + VERIFY(dset2, FAIL, "H5Rdereference2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_reference_obj_deleted() */ + +/**************************************************************** +** +** test_deref_iter_op(): Iterator callback for test_reference_group_iterate() +** test. +** +****************************************************************/ +static herr_t +test_deref_iter_op(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *info, + void *op_data) +{ + int *count = (int *)op_data; /* Pointer to name counter */ + herr_t ret_value; + + /* Simple check for correct names */ + if(*count == 0) { + if(HDstrcmp(name, DSETNAME2) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else if(*count == 1) { + if(HDstrcmp(name, GROUPNAME2) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else if(*count == 2) { + if(HDstrcmp(name, GROUPNAME3) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else + ret_value = -1; + + (*count)++; + + return(ret_value); +} /* end test_deref_iter_op() */ + +/**************************************************************** +** +** test_reference_group(): Test H5R (reference) object reference code. +** Tests for correct behavior of various routines on dereferenced group +** +****************************************************************/ +static void +test_reference_group(void) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + hid_t did; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hobj_ref_t wref; /* Reference to write */ + hobj_ref_t rref; /* Reference to read */ + H5G_info_t ginfo; /* Group info struct */ + char objname[NAME_SIZE]; /* Buffer to store name */ + H5O_info_t oinfo; /* Object info struct */ + int count = 0; /* Count within iterated group */ + ssize_t size; /* Name length */ + herr_t ret; + + /* Create file with a group and a dataset containing an object reference to the group */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataspace to use for dataset */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create group to refer to */ + gid = H5Gcreate2(fid, GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Create nested groups */ + gid2 = H5Gcreate2(gid, GROUPNAME2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid2, FAIL, "H5Gcreate2"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + gid2 = H5Gcreate2(gid, GROUPNAME3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid2, FAIL, "H5Gcreate2"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create bottom dataset */ + did = H5Dcreate2(gid, DSETNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + assert(did > 0); + ret = H5Dclose(did); + assert(ret >= 0); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create dataset */ + did = H5Dcreate2(fid, DSETNAME, H5T_STD_REF_OBJ, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Create reference to group */ + ret = H5Rcreate(&wref, fid, GROUPNAME, H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write reference to disk */ + ret = H5Dwrite(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Re-open dataset */ + did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dopen2"); + + /* Read in the reference */ + ret = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); + CHECK(ret, FAIL, "H5Dread"); + + /* Dereference to get the group */ + gid = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &rref); + CHECK(gid, FAIL, "H5Rdereference2"); + + /* Iterate through objects in dereferenced group */ + ret = H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_deref_iter_op, &count); + CHECK(ret, FAIL, "H5Literate"); + + /* Various queries on the group opened */ + ret = H5Gget_info(gid, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + VERIFY(ginfo.nlinks, 3, "H5Gget_info"); + + size = H5Lget_name_by_idx(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, objname, (size_t)NAME_SIZE, H5P_DEFAULT); + CHECK(size, FAIL, "H5Lget_name_by_idx"); + VERIFY_STR(objname, DSETNAME2, "H5Lget_name_by_idx"); + + ret = H5Oget_info_by_idx2(gid, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)0, &oinfo, H5O_INFO_BASIC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_idx"); + VERIFY(oinfo.type, H5O_TYPE_DATASET, "H5Oget_info_by_idx"); + + /* Unlink one of the objects in the dereferenced group */ + ret = H5Ldelete(gid, GROUPNAME2, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Delete dataset object in dereferenced group (with other dataset still open) */ + ret = H5Ldelete(gid, DSETNAME2, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_reference_group() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS +/**************************************************************** +** +** test_reference_compat(): Test basic H5R (reference) object reference code. +** Tests deprecated API routines +** +****************************************************************/ +static void +test_reference_compat(void) +{ + hid_t fid1; /* HDF5 File IDs */ + hid_t dataset, dset2; /* Dataset ID */ + hid_t group, group2; /* Group ID */ + hid_t sid1, /* Dataspace IDs */ + sid2; + hid_t tid1, tid2; /* Datatype ID */ + hsize_t dims1[] = {SPACE1_DIM1}, + dims2[] = {SPACE2_DIM1, SPACE2_DIM2}; + hsize_t start[SPACE2_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE2_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE2_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE2_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE2_RANK]; /* Coordinates for point selection */ + hobj_ref_t *wbuf_obj, /* Buffer to write to disk */ + *rbuf_obj; /* Buffer read from disk */ + hdset_reg_ref_t *wbuf_reg, /* Buffer to write to disk */ + *rbuf_reg; /* Buffer read from disk */ + H5G_obj_t obj_type; /* Object type */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated Object Reference Functions\n")); + + /* Allocate write & read buffers */ + wbuf_obj = (hobj_ref_t *)HDcalloc(sizeof(hobj_ref_t), SPACE1_DIM1); + rbuf_obj = (hobj_ref_t *)HDmalloc(sizeof(hobj_ref_t) * SPACE1_DIM1); + wbuf_reg = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), SPACE1_DIM1); + rbuf_reg = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + + /* Create file */ + fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /* Create dataspace for datasets */ + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + /* Create another dataspace for datasets */ + sid2 = H5Screate_simple(SPACE2_RANK, dims2, NULL); + CHECK(sid2, FAIL, "H5Screate_simple"); + + /* Create a group */ + group = H5Gcreate2(fid1, "Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group, FAIL, "H5Gcreate2"); + + /* Create a dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset1", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create another dataset (inside Group1) */ + dataset = H5Dcreate2(group, "Dataset2", H5T_NATIVE_UCHAR, sid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Create a datatype to refer to */ + tid1 = H5Tcreate(H5T_COMPOUND, sizeof(s1_t)); + CHECK(tid1, FAIL, "H5Tcreate"); + + /* Insert fields */ + ret = H5Tinsert(tid1, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "b", HOFFSET(s1_t,b), H5T_NATIVE_INT); + CHECK(ret, FAIL, "H5Tinsert"); + + ret = H5Tinsert(tid1, "c", HOFFSET(s1_t,c), H5T_NATIVE_FLOAT); + CHECK(ret, FAIL, "H5Tinsert"); + + /* Save datatype for later */ + ret = H5Tcommit2(group, "Datatype1", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Close datatype */ + ret = H5Tclose(tid1); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close group */ + ret = H5Gclose(group); + CHECK(ret, FAIL, "H5Gclose"); + + + /* Create a dataset with object reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset3", H5T_STD_REF_OBJ, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[0], fid1, "/Group1/Dataset1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to dataset */ + ret = H5Rcreate(&wbuf_obj[1], fid1, "/Group1/Dataset2", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to group */ + ret = H5Rcreate(&wbuf_obj[2], fid1, "/Group1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Create reference to named datatype */ + ret = H5Rcreate(&wbuf_obj[3], fid1, "/Group1/Datatype1", H5R_OBJECT, (hid_t)-1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write references to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_obj); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Create a dataset with region reference datatype */ + dataset = H5Dcreate2(fid1, "Dataset4", H5T_STD_REF_DSETREG, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Select 6x6 hyperslab for first reference */ + start[0] = 2; start[1] = 2; + stride[0] = 1; stride[1] = 1; + count[0] = 1; count[1] = 1; + block[0] = 6; block[1] = 6; + ret = H5Sselect_hyperslab(sid2, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Create first dataset region */ + ret = H5Rcreate(&wbuf_reg[0], fid1, "/Group1/Dataset1", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 6; coord1[0][1] = 9; + coord1[1][0] = 2; coord1[1][1] = 2; + coord1[2][0] = 8; coord1[2][1] = 4; + coord1[3][0] = 1; coord1[3][1] = 6; + coord1[4][0] = 2; coord1[4][1] = 8; + coord1[5][0] = 3; coord1[5][1] = 2; + coord1[6][0] = 0; coord1[6][1] = 4; + coord1[7][0] = 9; coord1[7][1] = 0; + coord1[8][0] = 7; coord1[8][1] = 1; + coord1[9][0] = 3; coord1[9][1] = 3; + ret = H5Sselect_elements(sid2, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Create second dataset region */ + ret = H5Rcreate(&wbuf_reg[1], fid1, "/Group1/Dataset2", H5R_DATASET_REGION, sid2); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write selection to disk */ + ret = H5Dwrite(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf_reg); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Close disk dataspaces */ + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open the file */ + fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Open the object reference dataset */ + dataset = H5Dopen2(fid1, "/Dataset3", H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_obj); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify type of objects pointed at */ + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[0]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[1]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[2]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_GROUP, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_OBJECT, &rbuf_obj[3]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_TYPE, "H5Rget_obj_type1"); + + + /* Make sure the referenced objects can be opened */ + dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[0]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + dset2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[1]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + group2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[2]); + CHECK(group2, FAIL, "H5Rdereference1"); + + ret = H5Gclose(group2); + CHECK(ret, FAIL, "H5Gclose"); + + tid2 = H5Rdereference1(dataset, H5R_OBJECT, &rbuf_obj[3]); + CHECK(tid2, FAIL, "H5Rdereference1"); + + ret = H5Tclose(tid2); + CHECK(ret, FAIL, "H5Tclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + + /* Open the dataset region reference dataset */ + dataset = H5Dopen2(fid1, "/Dataset4", H5P_DEFAULT); + CHECK(ret, FAIL, "H5Dopen2"); + + /* Read selection from disk */ + ret = H5Dread(dataset, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf_reg); + CHECK(ret, FAIL, "H5Dread"); + + /* Verify type of objects pointed at */ + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); + CHECK(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + VERIFY(obj_type, H5G_DATASET, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[2]); + VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + + obj_type = H5Rget_obj_type1(dataset, H5R_DATASET_REGION, &rbuf_reg[3]); + VERIFY(obj_type, H5G_UNKNOWN, "H5Rget_obj_type1"); + + /* Make sure the referenced objects can be opened */ + dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[0]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + dset2 = H5Rdereference1(dataset, H5R_DATASET_REGION, &rbuf_reg[1]); + CHECK(dset2, FAIL, "H5Rdereference1"); + + ret = H5Dclose(dset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free memory buffers */ + HDfree(wbuf_obj); + HDfree(rbuf_obj); + HDfree(wbuf_reg); + HDfree(rbuf_reg); +} /* test_reference_compat() */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +/**************************************************************** +** +** test_reference_deprec(): Main H5R reference testing routine. +** +****************************************************************/ +void +test_reference_deprec(void) +{ + H5F_libver_t low, high; /* Low and high bounds */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated References\n")); + + test_reference_params(); /* Test for correct parameter checking */ + test_reference_obj(); /* Test basic H5R object reference code */ + + /* Loop through all the combinations of low/high version bounds */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; H5_INC_ENUM(H5F_libver_t, low)) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; H5_INC_ENUM(H5F_libver_t, high)) { + + /* Invalid combinations, just continue */ + if(high == H5F_LIBVER_EARLIEST || high < low) + continue; + + test_reference_region(low, high); /* Test basic H5R dataset region reference code */ + test_reference_region_1D(low, high); /* Test H5R dataset region reference code for 1-D datasets */ + + } /* end high bound */ + } /* end low bound */ + + test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ + test_reference_group(); /* Test operations on dereferenced groups */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_reference_compat(); /* Test operations with old API routines */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + +} /* test_reference() */ + + +/*------------------------------------------------------------------------- + * Function: cleanup_reference + * + * Purpose: Cleanup temporary test files + * + * Return: none + * + * Programmer: Quincey Koziol + * September 8, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +cleanup_reference_deprec(void) +{ + HDremove(FILE1); + HDremove(FILE2); + HDremove(FILE3); +} + diff --git a/test/tunicode.c b/test/tunicode.c index b3fa237..6f7431b 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -352,8 +352,8 @@ void test_vl_string(hid_t fid, const char *string) VERIFY(HDstrcmp(string, read_buf[0]), 0, "strcmp"); /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(type_id, space_id, H5P_DEFAULT, read_buf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type_id, space_id, H5P_DEFAULT, read_buf); + CHECK(ret, FAIL, "H5Treclaim"); /* Close all */ ret = H5Dclose(dset_id); diff --git a/test/tvlstr.c b/test/tvlstr.c index 5f715ce..731270c 100644 --- a/test/tvlstr.c +++ b/test/tvlstr.c @@ -208,11 +208,11 @@ test_vlstrings_basic(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -314,8 +314,8 @@ test_vlstrings_special(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -537,8 +537,8 @@ test_compact_vlstring(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -762,8 +762,8 @@ static void read_scalar_dset(hid_t file, hid_t type, hid_t space, char *name, ch if(HDstrcmp(data, data_read)) TestErrPrintf("Expected %s for dataset %s but read %s\n", data, name, data_read); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &data_read); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(type, space, H5P_DEFAULT, &data_read); + CHECK(ret, FAIL, "H5Treclaim"); } /**************************************************************** diff --git a/test/tvltypes.c b/test/tvltypes.c index ffa2aff..656bf92 100644 --- a/test/tvltypes.c +++ b/test/tvltypes.c @@ -415,11 +415,11 @@ test_vltypes_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, xfer_pid, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid1, sid1, xfer_pid, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used, 0, "H5Dvlen_reclaim"); + VERIFY(mem_used, 0, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -499,24 +499,24 @@ test_vltypes_vlen_atomic(void) /* Try to reclaim read data using "bad" dataspace with no extent * Should fail */ H5E_BEGIN_TRY { - ret=H5Dvlen_reclaim(tid1,sid2,xfer_pid,rdata); + ret=H5Treclaim(tid1,sid2,xfer_pid,rdata); } H5E_END_TRY - VERIFY(ret, FAIL, "H5Dvlen_reclaim"); + VERIFY(ret, FAIL, "H5Treclaim"); /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close datatype */ ret = H5Tclose(tid1); @@ -659,15 +659,15 @@ rewrite_vltypes_vlen_atomic(void) } /* end for */ /* Reclaim the read VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -803,15 +803,15 @@ test_vltypes_vlen_compound(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -948,15 +948,15 @@ rewrite_vltypes_vlen_compound(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid1,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1118,12 +1118,12 @@ test_vltypes_compound_vlen_vlen(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1360,12 +1360,12 @@ test_vltypes_compound_vlstr(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Use this part for new data */ HDstrcpy(str, "bbbbbbbb\0"); @@ -1418,12 +1418,12 @@ test_vltypes_compound_vlstr(void) } /* end for */ /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata2); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata2); + CHECK(ret, FAIL, "H5Treclaim"); /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata2); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata2); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset2); CHECK(ret, FAIL, "H5Dclose"); @@ -1568,11 +1568,11 @@ test_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, xfer_pid, rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(tid2, sid1, xfer_pid, rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used, 0, "H5Dvlen_reclaim"); + VERIFY(mem_used, 0, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1634,16 +1634,16 @@ test_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close datatype */ ret = H5Tclose(tid2); @@ -1786,15 +1786,15 @@ rewrite_vltypes_compound_vlen_atomic(void) } /* end for */ /* Reclaim the VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -1997,15 +1997,15 @@ test_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2177,15 +2177,15 @@ rewrite_longer_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2353,15 +2353,15 @@ rewrite_shorter_vltypes_vlen_vlen_atomic(void) } /* end for */ /* Reclaim all the (nested) VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,xfer_pid,rdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,xfer_pid,rdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Make certain the VL memory has been freed */ - VERIFY(mem_used,0,"H5Dvlen_reclaim"); + VERIFY(mem_used,0,"H5Treclaim"); /* Reclaim the write VL data */ - ret=H5Dvlen_reclaim(tid2,sid1,H5P_DEFAULT,wdata); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret=H5Treclaim(tid2,sid1,H5P_DEFAULT,wdata); + CHECK(ret, FAIL, "H5Treclaim"); /* Close Dataset */ ret = H5Dclose(dataset); @@ -2743,8 +2743,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -2778,8 +2778,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -2808,8 +2808,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -2843,8 +2843,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -2970,8 +2970,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -3019,8 +3019,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); @@ -3066,8 +3066,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); /* Clear the read buffer */ HDmemset(rbuf, 0, dset_elmts * sizeof(dtype1_struct)); @@ -3115,8 +3115,8 @@ test_vltypes_fill_value(void) } /* end for */ /* Release the space */ - ret = H5Dvlen_reclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); - CHECK(ret, FAIL, "H5Dvlen_reclaim"); + ret = H5Treclaim(dtype1_id, dset_select_dspace_id, xfer_pid, rbuf); + CHECK(ret, FAIL, "H5Treclaim"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index 8d131db..4d6b18c 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -58,6 +58,9 @@ macro (ADD_VFD_TEST vfdname resultcode) WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR}/${vfdname} ) endforeach () + set_tests_properties (MPI_TEST_VFD-${vfdname}-pflush1 PROPERTIES WILL_FAIL "true") + #set_property (TEST MPI_TEST_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") + set_tests_properties (MPI_TEST_VFD-${vfdname}-pflush2 PROPERTIES DEPENDS MPI_TEST_VFD-${vfdname}-pflush1) endif () endmacro () diff --git a/testpar/t_bigio.c b/testpar/t_bigio.c index 9ca077c..12c1023 100644 --- a/testpar/t_bigio.c +++ b/testpar/t_bigio.c @@ -4,7 +4,8 @@ #include "H5Dprivate.h" /* For Chunk tests */ /* FILENAME and filenames must have the same number of names */ -const char *FILENAME[2]={ "bigio_test.h5", +const char *FILENAME[3]={ "bigio_test.h5", + "single_rank_independent_io.h5", NULL }; @@ -29,7 +30,8 @@ const char *FILENAME[2]={ "bigio_test.h5", #define DATASET5 "DSET5" #define DXFER_COLLECTIVE_IO 0x1 /* Collective IO*/ #define DXFER_INDEPENDENT_IO 0x2 /* Independent IO collectively */ -#define DXFER_BIGCOUNT 536870916 +#define DXFER_BIGCOUNT (1 < 29) +#define LARGE_DIM 1610612736 #define HYPER 1 #define POINT 2 @@ -40,7 +42,7 @@ typedef hsize_t B_DATATYPE; int facc_type = FACC_MPIO; /*Test file access type */ int dxfer_coll_type = DXFER_COLLECTIVE_IO; -size_t bigcount = DXFER_BIGCOUNT; +size_t bigcount = (size_t)DXFER_BIGCOUNT; int nerrors = 0; int mpi_size, mpi_rank; @@ -478,22 +480,19 @@ static void dataset_big_write(void) { - hid_t xfer_plist; /* Dataset transfer properties list */ - hid_t sid; /* Dataspace ID */ - hid_t file_dataspace; /* File dataspace ID */ - hid_t mem_dataspace; /* memory dataspace ID */ + hid_t xfer_plist; /* Dataset transfer properties list */ + hid_t sid; /* Dataspace ID */ + hid_t file_dataspace; /* File dataspace ID */ + hid_t mem_dataspace; /* memory dataspace ID */ hid_t dataset; - hid_t datatype; /* Datatype ID */ - hsize_t dims[RANK]; /* dataset dim sizes */ - hsize_t start[RANK]; /* for hyperslab setting */ - hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */ - hsize_t block[RANK]; /* for hyperslab setting */ + hsize_t dims[RANK]; /* dataset dim sizes */ + hsize_t start[RANK]; /* for hyperslab setting */ + hsize_t count[RANK],stride[RANK]; /* for hyperslab setting */ + hsize_t block[RANK]; /* for hyperslab setting */ hsize_t *coords = NULL; - int i; - herr_t ret; /* Generic return value */ - hid_t fid; /* HDF5 file ID */ - hid_t acc_tpl; /* File access templates */ - hsize_t h; + herr_t ret; /* Generic return value */ + hid_t fid; /* HDF5 file ID */ + hid_t acc_tpl; /* File access templates */ size_t num_points; B_DATATYPE * wdata; @@ -806,8 +805,6 @@ dataset_big_read(void) hsize_t start[RANK]; /* for hyperslab setting */ hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */ hsize_t block[RANK]; /* for hyperslab setting */ - int i,j,k; - hsize_t h; size_t num_points; hsize_t *coords = NULL; herr_t ret; /* Generic return value */ @@ -1120,6 +1117,63 @@ dataset_big_read(void) } /* dataset_large_readAll */ +static void +single_rank_independent_io(void) +{ + if (mpi_rank == 0) + HDprintf("single_rank_independent_io\n"); + + if (MAINPROCESS) { + hsize_t dims[] = { LARGE_DIM }; + hid_t file_id = -1; + hid_t fapl_id = -1; + hid_t dset_id = -1; + hid_t fspace_id = -1; + hid_t mspace_id = -1; + void *data = NULL; + + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((fapl_id >= 0), "H5P_FILE_ACCESS"); + + H5Pset_fapl_mpio(fapl_id, MPI_COMM_SELF, MPI_INFO_NULL); + file_id = H5Fcreate(FILENAME[1], H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + VRFY((file_id >= 0), "H5Dcreate2 succeeded"); + + fspace_id = H5Screate_simple(1, dims, NULL); + VRFY((fspace_id >= 0), "H5Screate_simple fspace_id succeeded"); + + /* + * Create and write to a >2GB dataset from a single rank. + */ + dset_id = H5Dcreate2(file_id, "test_dset", H5T_NATIVE_INT, fspace_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + VRFY((dset_id >= 0), "H5Dcreate2 succeeded"); + + data = malloc(LARGE_DIM * sizeof(int)); + + if (mpi_rank == 0) + H5Sselect_all(fspace_id); + else + H5Sselect_none(fspace_id); + + dims[0] = LARGE_DIM; + mspace_id = H5Screate_simple(1, dims, NULL); + VRFY((mspace_id >= 0), "H5Screate_simple mspace_id succeeded"); + H5Dwrite(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, H5P_DEFAULT, data); + + free(data); + H5Sclose(mspace_id); + H5Sclose(fspace_id); + H5Pclose(fapl_id); + H5Dclose(dset_id); + H5Fclose(file_id); + + HDremove(FILENAME[1]); + + } + MPI_Barrier(MPI_COMM_WORLD); +} /* * Create the appropriate File access property list @@ -1395,7 +1449,6 @@ coll_chunktest(const char* filename, size_t num_points; /* for point selection */ hsize_t *coords = NULL; /* for point selection */ - int i; /* Create the data space */ @@ -1873,7 +1926,7 @@ int main(int argc, char **argv) int ExpressMode = 0; hsize_t newsize = 1048576; /* Set the bigio processing limit to be 'newsize' bytes */ - hsize_t oldsize = H5S_mpio_set_bigio_count(newsize); + hsize_t oldsize = H5_mpi_set_bigio_count(newsize); /* Having set the bigio handling to a size that is managable, * we'll set our 'bigcount' variable to be 2X that limit so @@ -1918,6 +1971,8 @@ int main(int argc, char **argv) coll_chunk2(); MPI_Barrier(MPI_COMM_WORLD); coll_chunk3(); + MPI_Barrier(MPI_COMM_WORLD); + single_rank_independent_io(); } /* turn off alarm */ diff --git a/testpar/t_file.c b/testpar/t_file.c index 204095b..99ac189 100644 --- a/testpar/t_file.c +++ b/testpar/t_file.c @@ -145,7 +145,7 @@ test_page_buffer_access(void) ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 1, (hsize_t)0); VRFY((ret == 0), ""); - ret = H5Pset_file_space_page_size(fcpl, sizeof(int)*100); + ret = H5Pset_file_space_page_size(fcpl, sizeof(int)*128); VRFY((ret == 0), ""); ret = H5Pset_page_buffer_size(fapl, sizeof(int)*100000, 0, 0); VRFY((ret == 0), ""); @@ -180,7 +180,6 @@ test_page_buffer_access(void) data[i] = -1; if(MAINPROCESS) { hid_t fapl_self = H5I_INVALID_HID; - fapl_self = create_faccess_plist(MPI_COMM_SELF, MPI_INFO_NULL, facc_type); ret = H5Pset_page_buffer_size(fapl_self, sizeof(int)*1000, 0, 0); @@ -433,7 +432,7 @@ create_file(const char *filename, hid_t fcpl, hid_t fapl, int metadata_write_str hsize_t dims[RANK], i; hsize_t num_elements; int k; - char dset_name[10]; + char dset_name[20]; H5F_t *f = NULL; H5C_t *cache_ptr = NULL; H5AC_cache_config_t config; @@ -590,7 +589,7 @@ open_file(const char *filename, hid_t fapl, int metadata_write_strategy, hsize_t block[RANK]; int i, k, ndims; hsize_t num_elements; - char dset_name[10]; + char dset_name[20]; H5F_t *f = NULL; H5C_t *cache_ptr = NULL; H5AC_cache_config_t config; @@ -665,8 +664,8 @@ open_file(const char *filename, hid_t fapl, int metadata_write_strategy, ndims = H5Sget_simple_extent_dims(sid, dims, NULL); VRFY((ndims == 2), "H5Sget_simple_extent_dims succeeded"); - VRFY(dims[0] == ROW_FACTOR*mpi_size, "Wrong dataset dimensions"); - VRFY(dims[1] == COL_FACTOR*mpi_size, "Wrong dataset dimensions"); + VRFY(dims[0] == (hsize_t)(ROW_FACTOR*mpi_size), "Wrong dataset dimensions"); + VRFY(dims[1] == (hsize_t)(COL_FACTOR*mpi_size), "Wrong dataset dimensions"); ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); VRFY((ret >= 0), "H5Sset_hyperslab succeeded"); @@ -679,7 +678,7 @@ open_file(const char *filename, hid_t fapl, int metadata_write_strategy, ret = H5Sclose(sid); VRFY((ret == 0), ""); - for (i=0; i < num_elements; i++) + for (i=0; i < (int)num_elements; i++) VRFY((data_array[i] == mpi_rank+1), "Dataset Verify failed"); } diff --git a/tools/lib/h5diff_attr.c b/tools/lib/h5diff_attr.c index 4ad4c90..351e6ab 100644 --- a/tools/lib/h5diff_attr.c +++ b/tools/lib/h5diff_attr.c @@ -515,12 +515,12 @@ hsize_t diff_attr(hid_t loc1_id, /* Free buf1 and buf2, check both VLEN-data VLEN-string to reclaim any * VLEN memory first */ if(TRUE == h5tools_detect_vlen(mtype1_id)) - H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); + H5Treclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; if(TRUE == h5tools_detect_vlen(mtype2_id)) - H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); + H5Treclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; @@ -551,12 +551,12 @@ done: H5E_BEGIN_TRY { if(buf1) { if(buf1hasdata && TRUE == h5tools_detect_vlen(mtype1_id)) - H5Dvlen_reclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); + H5Treclaim(mtype1_id, space1_id, H5P_DEFAULT, buf1); HDfree(buf1); } /* end if */ if(buf2) { if(buf2hasdata && TRUE == h5tools_detect_vlen(mtype2_id)) - H5Dvlen_reclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); + H5Treclaim(mtype2_id, space2_id, H5P_DEFAULT, buf2); HDfree(buf2); } /* end if */ diff --git a/tools/lib/h5diff_dset.c b/tools/lib/h5diff_dset.c index ff542db..96f1d1a 100644 --- a/tools/lib/h5diff_dset.c +++ b/tools/lib/h5diff_dset.c @@ -416,10 +416,10 @@ hsize_t diff_datasetid(hid_t did1, /* reclaim any VL memory, if necessary */ h5diffdebug2("check vl_data1:%d\n", vl_data1); if(vl_data1) - H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); + H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1); h5diffdebug2("check vl_data2:%d\n", vl_data2); if(vl_data2) - H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); + H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2); if(buf1 != NULL) { HDfree(buf1); buf1 = NULL; @@ -510,9 +510,9 @@ hsize_t diff_datasetid(hid_t did1, /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); + H5Treclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); if(vl_data2) - H5Dvlen_reclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); + H5Treclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); /* calculate the next hyperslab offset */ for(i = rank1, carry = 1; i > 0 && carry; --i) { @@ -550,28 +550,28 @@ done: if(buf1 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sid1, H5P_DEFAULT, buf1); + H5Treclaim(m_tid1, sid1, H5P_DEFAULT, buf1); HDfree(buf1); buf1 = NULL; } if(buf2 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data2) - H5Dvlen_reclaim(m_tid2, sid2, H5P_DEFAULT, buf2); + H5Treclaim(m_tid2, sid2, H5P_DEFAULT, buf2); HDfree(buf2); buf2 = NULL; } if(sm_buf1 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data1) - H5Dvlen_reclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); + H5Treclaim(m_tid1, sm_space, H5P_DEFAULT, sm_buf1); HDfree(sm_buf1); sm_buf1 = NULL; } if(sm_buf2 != NULL) { /* reclaim any VL memory, if necessary */ if(vl_data2) - H5Dvlen_reclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); + H5Treclaim(m_tid2, sm_space, H5P_DEFAULT, sm_buf2); HDfree(sm_buf2); sm_buf2 = NULL; } diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index eaac94a..ebe5c4a 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -1256,7 +1256,7 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); + H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); if(H5Sclose(sm_space) < 0) H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Sclose failed"); @@ -1645,7 +1645,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); + H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); /* Calculate the next hyperslab offset */ for (i = ctx->ndims, carry = 1; i > 0 && carry; --i) { @@ -2345,9 +2345,13 @@ h5tools_print_datatype(FILE *stream, h5tools_str_t *buffer, const h5tool_format_ if (H5Tequal(type, H5T_STD_REF_DSETREG) == TRUE) { h5tools_str_append(buffer, " { H5T_STD_REF_DSETREG }"); } - else { + else if (H5Tequal(type, H5T_STD_REF_OBJ) == TRUE) { h5tools_str_append(buffer, " { H5T_STD_REF_OBJECT }"); } + else if (H5Tequal(type, H5T_STD_REF) == TRUE) { + h5tools_str_append(buffer, " { H5T_STD_REF }"); + } else + h5tools_str_append(buffer, " { UNDEFINED }"); break; case H5T_ENUM: @@ -3979,7 +3983,7 @@ h5tools_dump_data(FILE *stream, const h5tool_format_t *info, /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index c4fd948..be9e727 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -1919,7 +1919,7 @@ xml_dump_data(hid_t obj_id, int obj_data, struct subset_t H5_ATTR_UNUSED * sset, } /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } @@ -3099,7 +3099,7 @@ xml_print_strs(hid_t did, int source) HDfree(onestring); if (buf) { if (is_vlstr) - H5Dvlen_reclaim(type, space, H5P_DEFAULT, buf); + H5Treclaim(type, space, H5P_DEFAULT, buf); HDfree(buf); } H5Tclose(type); diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index 3b0001d..5c9c693 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -1568,7 +1568,7 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ain /* Reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(p_type, space, H5P_DEFAULT, buf); + H5Treclaim(p_type, space, H5P_DEFAULT, buf); HDfree(buf); } diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c index 0183cbf..5f688d9 100644 --- a/tools/src/h5repack/h5repack.c +++ b/tools/src/h5repack/h5repack.c @@ -486,7 +486,7 @@ copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p, trav_table_ /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) - H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim(wtype_id, space_id, H5P_DEFAULT, buf); HDfree(buf); buf = NULL; } /*H5T_REFERENCE*/ @@ -519,7 +519,9 @@ done: * datatype that must be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) - H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim(wtype_id, space_id, H5P_DEFAULT, buf); + + /* Free buf */ HDfree(buf); } diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index f6409e3..24f67db 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -918,8 +918,8 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, /* Check if we have VL data in the dataset's * datatype that must be reclaimed */ if (TRUE == H5Tdetect_class(wtype_id, H5T_VLEN)) - if (H5Dvlen_reclaim(wtype_id, f_space_id, H5P_DEFAULT, buf) < 0) - HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dvlen_reclaim failed"); + if (H5Treclaim(wtype_id, f_space_id, H5P_DEFAULT, buf) < 0) + HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Treclaim failed"); if (buf != NULL) { /* TODO: is buf potentially released by H5Dvlen_reclaim()? */ HDfree(buf); @@ -1010,7 +1010,7 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, /* reclaim any VL memory, if necessary */ if (vl_data) - H5Dvlen_reclaim(wtype_id, hslab_space, H5P_DEFAULT, hslab_buf); + H5Treclaim(wtype_id, hslab_space, H5P_DEFAULT, hslab_buf); /* calculate the next hyperslab offset */ for (k = rank, carry = 1; k > 0 && carry; --k) { diff --git a/tools/src/h5repack/h5repack_refs.c b/tools/src/h5repack/h5repack_refs.c index 7e8951f..bfc376f 100644 --- a/tools/src/h5repack/h5repack_refs.c +++ b/tools/src/h5repack/h5repack_refs.c @@ -712,7 +712,7 @@ static int copy_refs_attr(hid_t loc_in, HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed"); if (is_ref_vlen && buf) - H5Dvlen_reclaim (mtype_id, space_id, H5P_DEFAULT, buf); + H5Treclaim (mtype_id, space_id, H5P_DEFAULT, buf); } /* if (nelmts) */ if (refbuf == buf) diff --git a/tools/test/h5copy/h5copygentest.c b/tools/test/h5copy/h5copygentest.c index f6aa72f..a3acdae 100644 --- a/tools/test/h5copy/h5copygentest.c +++ b/tools/test/h5copy/h5copygentest.c @@ -261,7 +261,7 @@ static void gent_named_vl(hid_t loc_id) H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* close */ - H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf); + H5Treclaim(tid,sid,H5P_DEFAULT,buf); H5Sclose(sid); H5Dclose(did); H5Tclose(tid); @@ -314,7 +314,7 @@ static void gent_nested_vl(hid_t loc_id) H5Dwrite(did, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); /* close */ - H5Dvlen_reclaim(tid2,sid,H5P_DEFAULT,buf); + H5Treclaim(tid2,sid,H5P_DEFAULT,buf); H5Sclose(sid); H5Dclose(did); H5Tclose(tid1); diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 93dfd72..57bcd12 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -426,7 +426,7 @@ if (last_test) set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () - set (last_test "PH5DIFF-${resultfile}") + set (last_test "MPI_TEST_H5DIFF-${resultfile}") endif () endmacro () diff --git a/tools/test/h5diff/h5diffgentest.c b/tools/test/h5diff/h5diffgentest.c index d60e393..c711013 100644 --- a/tools/test/h5diff/h5diffgentest.c +++ b/tools/test/h5diff/h5diffgentest.c @@ -4403,7 +4403,7 @@ static void test_comps_vlen(const char * fname, const char *dset, const char *at assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /* ---------------- @@ -4537,7 +4537,7 @@ static void test_comps_array_vlen(const char * fname, const char *dset, const ch assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /*------------------- @@ -4680,7 +4680,7 @@ static void test_comps_vlen_arry(const char * fname, const char *dset, const cha assert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid_cmpd1, sid_dset, H5P_DEFAULT, wdata); assert(ret >= 0); /* ---------------- @@ -5446,7 +5446,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -5712,7 +5712,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6108,7 +6108,7 @@ void write_attr_strings(hid_t loc_id, const char* dset_name, hid_t fid, int make aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6434,7 +6434,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -6702,7 +6702,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -7100,7 +7100,7 @@ void write_attr_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -7395,7 +7395,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -7580,7 +7580,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff did = H5Dcreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); assert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -7759,7 +7759,7 @@ void write_dset_in(hid_t loc_id, const char* dset_name, hid_t fid, int make_diff did = H5Dcreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53); assert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); assert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 35c3e3c..ad70770 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -2624,7 +2624,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset1.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, wdata); + ret = H5Treclaim(type, space, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2651,7 +2651,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset2.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, wdata); + ret = H5Treclaim(type, space, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2674,7 +2674,7 @@ static void gent_vldatatypes(void) dset = H5Dcreate2(file, "Dataset3.0", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, &adata); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(type, space, H5P_DEFAULT, &adata); + ret = H5Treclaim(type, space, H5P_DEFAULT, &adata); HDassert(ret >= 0); ret = H5Dclose(dset); @@ -2740,7 +2740,7 @@ gent_vldatatypes2(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2811,7 +2811,7 @@ static void gent_vldatatypes3(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid2, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2878,7 +2878,7 @@ static void gent_vldatatypes4(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -2942,7 +2942,7 @@ static void gent_vldatatypes5(void) ret = H5Dclose(dataset); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); ret = H5Tclose(tid1); @@ -3385,7 +3385,7 @@ static void gent_array6(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -3454,7 +3454,7 @@ static void gent_array7(void) HDassert(ret >= 0); /* Reclaim the write VL data */ - ret = H5Dvlen_reclaim(tid1, sid1, H5P_DEFAULT, wdata); + ret = H5Treclaim(tid1, sid1, H5P_DEFAULT, wdata); HDassert(ret >= 0); /* Close Dataset */ @@ -4054,7 +4054,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4165,7 +4165,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf52); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4298,7 +4298,7 @@ static void write_attr_in(hid_t loc_id, aid = H5Acreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite(aid, tid, buf53); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); HDassert(status >= 0); status = H5Aclose(aid); status = H5Tclose(tid); @@ -4496,7 +4496,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf5); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -4606,7 +4606,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen2D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf52); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -4745,7 +4745,7 @@ static void write_dset_in(hid_t loc_id, did = H5Dcreate2(loc_id, "vlen3D", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53); HDassert(status >= 0); - status = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53); + status = H5Treclaim(tid, sid, H5P_DEFAULT, buf53); HDassert(status >= 0); status = H5Dclose(did); status = H5Tclose(tid); @@ -5966,7 +5966,7 @@ static void gent_fvalues(void) did = H5Dcreate2(fid, "fill_vlen", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); ret = H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf3); HDassert(ret >= 0); - ret = H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf3); + ret = H5Treclaim(tid, sid, H5P_DEFAULT, buf3); HDassert(ret >= 0); ret = H5Dclose(did); ret = H5Tclose(tid); diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index e5680cf..141715c 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -906,12 +906,14 @@ TOOLTEST_HELP() { } # Call the h5dump tool and grep for a value -# +# txttype ERRTXT greps test error output, otherwise greps test output GREPTEST() { - expectdata=$1 - actual=$TESTDIR/$2 - actual_err="$TESTDIR/`basename $2 .ddl`.oerr" + txttype=$1 + expectdata=$2 + actual=$TESTDIR/$3 + actual_err="$TESTDIR/`basename $3 .ddl`.oerr" + shift shift shift @@ -921,7 +923,11 @@ GREPTEST() cd $TESTDIR $ENVCMD $RUNSERIAL $DUMPER_BIN -p "$@" ) >$actual 2>$actual_err - $GREP $expectdata $actual > /dev/null + if [[ "$txttype" = "ERRTXT" ]]; then + $GREP "$expectdata" $actual_err > /dev/null + else + $GREP "$expectdata" $actual > /dev/null + fi if [ $? -eq 0 ]; then echo " PASSED" else @@ -1137,7 +1143,7 @@ TOOLTEST tvlenstr_array.ddl --enable-error-stack tvlenstr_array.h5 # test for files with array data TOOLTEST tarray1.ddl --enable-error-stack tarray1.h5 # # added for bug# 2092 - tarray1_big.h -TOOLTEST4 tarray1_big.ddl --enable-error-stack -R tarray1_big.h5 +GREPTEST ERRTXT "Undefined reference pointer" tarray1_big.ddl --enable-error-stack -R tarray1_big.h5 TOOLTEST tarray2.ddl --enable-error-stack tarray2.h5 TOOLTEST tarray3.ddl --enable-error-stack tarray3.h5 TOOLTEST tarray4.ddl --enable-error-stack tarray4.h5 @@ -1345,9 +1351,9 @@ fi # test for dataset region references TOOLTEST tdatareg.ddl --enable-error-stack tdatareg.h5 -TOOLTEST4 tdataregR.ddl --enable-error-stack -R tdatareg.h5 +GREPTEST ERRTXT "Undefined reference pointer" tdataregR.ddl --enable-error-stack -R tdatareg.h5 TOOLTEST tattrreg.ddl --enable-error-stack tattrreg.h5 -TOOLTEST4 tattrregR.ddl --enable-error-stack -R tattrreg.h5 +GREPTEST ERRTXT "Undefined reference pointer" tattrregR.ddl --enable-error-stack -R tattrreg.h5 TOOLTEST2 tbinregR.exp --enable-error-stack -d /Dataset1 -s 0 -R -y -o tbinregR.txt tdatareg.h5 # Clean up text output files @@ -1396,7 +1402,7 @@ TOOLTEST3 non_existing.ddl --enable-error-stack tgroup.h5 non_existing.h5 TOOLTEST err_attr_dspace.ddl err_attr_dspace.h5 # test to verify HDFFV-9407: long double full precision -GREPTEST "1.123456789012345" t128bit_float.ddl -m %.35Lf t128bit_float.h5 +GREPTEST OUTTXT "1.123456789012345" t128bit_float.ddl -m %.35Lf t128bit_float.h5 # Clean up temporary files/directories CLEAN_TESTFILES_AND_TESTDIR diff --git a/tools/test/h5repack/h5repackgentest.c b/tools/test/h5repack/h5repackgentest.c index 12883b7..aaac285 100644 --- a/tools/test/h5repack/h5repackgentest.c +++ b/tools/test/h5repack/h5repackgentest.c @@ -42,7 +42,10 @@ #define FILE_UINT8BE "h5repack_uint8be" #define FILE_F32LE "h5repack_f32le" -#define H5REPACKGENTEST_OOPS ret_value = -1; goto done; +#define H5REPACKGENTEST_OOPS { \ + ret_value = -1; \ + goto done; \ +} #define H5REPACKGENTEST_COMMON_CLEANUP(dcpl, file, space) { \ if ((dcpl) != H5P_DEFAULT && (dcpl) != H5I_INVALID_HID) { \ @@ -53,58 +56,37 @@ } struct external_def { - hsize_t type_size; + hsize_t type_size; unsigned n_elts_per_file; unsigned n_elts_total; }; - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Helper function to create and write a dataset to file. * Returns 0 on success, -1 on failure. */ static int -__make_dataset( - hid_t file_id, - const char *dset_name, - hid_t mem_type_id, - hid_t space_id, - hid_t dcpl_id, - void *wdata) -{ - hid_t dset_id = H5I_INVALID_HID; +__make_dataset(hid_t file_id, const char *dset_name, + hid_t mem_type_id, hid_t space_id, hid_t dcpl_id, void *wdata) { + hid_t dset_id = H5I_INVALID_HID; int ret_value = 0; - dset_id = H5Dcreate2( - file_id, - dset_name, - mem_type_id, - space_id, - H5P_DEFAULT, - dcpl_id, - H5P_DEFAULT); - if (dset_id == H5I_INVALID_HID) { + dset_id = H5Dcreate2(file_id, dset_name, mem_type_id, space_id, + H5P_DEFAULT, dcpl_id, + H5P_DEFAULT); + if (dset_id == H5I_INVALID_HID) H5REPACKGENTEST_OOPS; - } - if (H5Dwrite( - dset_id, - mem_type_id, - H5S_ALL, - H5S_ALL, - H5P_DEFAULT, - wdata) - < 0) - { + if (H5Dwrite(dset_id, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata) < 0) H5REPACKGENTEST_OOPS; - } done: - if (dset_id != H5I_INVALID_HID) { (void)H5Dclose(dset_id); } + if (dset_id != H5I_INVALID_HID) + (void) H5Dclose(dset_id); + return ret_value; } /* end __make_dataset() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Helper function to populate the DCPL external storage list. * Creates external files for the DCPL, with each file name following the @@ -114,38 +96,30 @@ done: * Returns 0 on success, -1 on failure. */ static int -__set_dcpl_external_list( - hid_t dcpl, - const char *filename, - unsigned n_elts_per_file, - unsigned n_elts_total, - hsize_t elt_size) -{ +__set_dcpl_external_list(hid_t dcpl, const char *filename, + unsigned n_elts_per_file, unsigned n_elts_total, hsize_t elt_size) { char name[MAX_NAME_SIZE]; unsigned n_external_files = 0; unsigned i = 0; - if (NULL == filename || '\0' == *filename) { + if (NULL == filename || '\0' == *filename) return -1; - } n_external_files = n_elts_total / n_elts_per_file; - if (n_elts_total != (n_external_files * n_elts_per_file)) { + if (n_elts_total != (n_external_files * n_elts_per_file)) return -1; - } + for (i = 0; i < n_external_files; i++) { - if (snprintf(name, MAX_NAME_SIZE, "%s_ex-%u.dat", filename, i) >= MAX_NAME_SIZE) { + if (HDsnprintf(name, MAX_NAME_SIZE, "%s_ex-%u.dat", filename, i) >= MAX_NAME_SIZE) return -1; - } - if (H5Pset_external(dcpl, name, 0, n_elts_per_file * elt_size) < 0) { + + if (H5Pset_external(dcpl, name, 0, n_elts_per_file * elt_size) < 0) return -1; - } } return 0; } /* end __set_dcpl_external_list() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Generalized utility function to write a file with the specified data and * dataset configuration. If `ext` is provided, will attempt to use external @@ -153,141 +127,102 @@ __set_dcpl_external_list( * Returns 0 on success, -1 on failure. */ static int -__make_file( - const char *basename, - struct external_def *ext, - hid_t type_id, - hsize_t rank, - hsize_t *dims, - void *wdata) -{ - char filename[MAX_NAME_SIZE]; - hid_t file_id = H5I_INVALID_HID; - hid_t dcpl_id = H5P_DEFAULT; - hid_t space_id = H5I_INVALID_HID; - int ret_value = 0; +__make_file(const char *basename, struct external_def *ext, + hid_t type_id, hsize_t rank, hsize_t *dims, void *wdata) { + char filename[MAX_NAME_SIZE]; + hid_t file_id = H5I_INVALID_HID; + hid_t dcpl_id = H5P_DEFAULT; + hid_t space_id = H5I_INVALID_HID; + int ret_value = 0; - if (snprintf(filename, - MAX_NAME_SIZE, - "%s%s.h5", - basename, - (NULL != ext) ? "_ex" : "") - >= MAX_NAME_SIZE) - { + if (HDsnprintf(filename, MAX_NAME_SIZE, "%s%s.h5", basename, (NULL != ext) ? "_ex" : "") >= MAX_NAME_SIZE) H5REPACKGENTEST_OOPS; - } if (NULL != ext) { dcpl_id = H5Pcreate(H5P_DATASET_CREATE); - if (dcpl_id == H5I_INVALID_HID) { + if (dcpl_id == H5I_INVALID_HID) H5REPACKGENTEST_OOPS; - } - if (__set_dcpl_external_list( - dcpl_id, - basename, - ext->n_elts_per_file, - ext->n_elts_total, - ext->type_size) - < 0) - { + + if (__set_dcpl_external_list(dcpl_id, basename, ext->n_elts_per_file, ext->n_elts_total, ext->type_size) < 0) H5REPACKGENTEST_OOPS; - } } space_id = H5Screate_simple(rank, dims, NULL); - if (space_id == H5I_INVALID_HID) { + if (space_id == H5I_INVALID_HID) H5REPACKGENTEST_OOPS; - } file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - if (file_id == H5I_INVALID_HID) { + if (file_id == H5I_INVALID_HID) H5REPACKGENTEST_OOPS; - } - if (__make_dataset( - file_id, - "dset", - type_id, - space_id, - dcpl_id, - wdata) - < 0) - { + + if (__make_dataset(file_id, "dset", type_id, space_id, dcpl_id, wdata) < 0) H5REPACKGENTEST_OOPS; - } done: H5REPACKGENTEST_COMMON_CLEANUP(dcpl_id, file_id, space_id); - return ret_value; +return ret_value; } /* end __make_file() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns 0 on success, -1 on failure. */ static int -generate_int32le_1d(hbool_t external) -{ - int32_t wdata[12]; - hsize_t dims[] = {12}; - struct external_def *def_ptr = NULL; - struct external_def def = { (hsize_t)sizeof(int32_t), 6, 12 }; - int32_t n = 0; - int ret_value = 0; +generate_int32le_1d(hbool_t external) { + int32_t wdata[12]; + hsize_t dims[] = { 12 }; + struct external_def *def_ptr = NULL; + struct external_def def = { (hsize_t) sizeof(int32_t), 6, 12 }; + int32_t n = 0; + int ret_value = 0; /* Generate values - */ + */ for (n = 0; n < 12; n++) { - wdata[n] = n-6; + wdata[n] = n - 6; } def_ptr = (TRUE == external) ? (&def) : NULL; - if (__make_file(FILE_INT32LE_1, def_ptr, H5T_STD_I32LE, 1, dims, wdata) < 0) { + if (__make_file(FILE_INT32LE_1, def_ptr, H5T_STD_I32LE, 1, dims, wdata) < 0) ret_value = -1; - } return ret_value; } /* end generate_int32le_1d() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns 0 on success, -1 on failure. */ static int -generate_int32le_2d(hbool_t external) -{ - int32_t wdata[64]; - hsize_t dims[] = {8, 8}; - struct external_def *def_ptr = NULL; - struct external_def def = { (hsize_t)sizeof(int32_t), 64, 64 }; - int32_t n = 0; - int ret_value = 0; +generate_int32le_2d(hbool_t external) { + int32_t wdata[64]; + hsize_t dims[] = { 8, 8 }; + struct external_def *def_ptr = NULL; + struct external_def def = { (hsize_t) sizeof(int32_t), 64, 64 }; + int32_t n = 0; + int ret_value = 0; /* Generate values - */ + */ for (n = 0; n < 64; n++) { - wdata[n] = n-32; + wdata[n] = n - 32; } def_ptr = (TRUE == external) ? (&def) : NULL; - if (__make_file(FILE_INT32LE_2, def_ptr, H5T_STD_I32LE, 2, dims, wdata) < 0) { + if (__make_file(FILE_INT32LE_2, def_ptr, H5T_STD_I32LE, 2, dims, wdata) < 0) ret_value = -1; - } return ret_value; } /* end generate_int32le_2d() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns 0 on success, -1 on failure. */ static int -generate_int32le_3d(hbool_t external) -{ - hsize_t dims[] = {8, 8, 8}; - int32_t wdata[512]; /* 8^3, from dims */ +generate_int32le_3d(hbool_t external) { + hsize_t dims[] = { 8, 8, 8 }; + int32_t wdata[512]; /* 8^3, from dims */ struct external_def *def_ptr = NULL; - struct external_def def = { (hsize_t)sizeof(int32_t), 512, 512 }; + struct external_def def = { (hsize_t) sizeof(int32_t), 512, 512 }; int32_t n = 0; int i = 0; int j = 0; @@ -295,34 +230,31 @@ generate_int32le_3d(hbool_t external) int ret_value = 0; /* generate values, alternating positive and negative - */ - for (i=0, n=0; i < dims[0]; i++) { - for (j=0; j < dims[1]; j++) { - for (k=0; k < dims[2]; k++, n++) { - wdata[n] = (k + j*512 + i*4096) * ((n&1) ? (-1) : (1)); + */ + for (i = 0, n = 0; i < dims[0]; i++) { + for (j = 0; j < dims[1]; j++) { + for (k = 0; k < dims[2]; k++, n++) { + wdata[n] = (k + j * 512 + i * 4096) * ((n & 1) ? (-1) : (1)); } } } def_ptr = (TRUE == external) ? (&def) : NULL; - if (__make_file(FILE_INT32LE_3, def_ptr, H5T_STD_I32LE, 3, dims, wdata) < 0) { + if (__make_file(FILE_INT32LE_3, def_ptr, H5T_STD_I32LE, 3, dims, wdata) < 0) ret_value = -1; - } return ret_value; } /* end generate_int32le_3d() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns 0 on success, -1 on failure. */ static int -generate_uint8be(hbool_t external) -{ - hsize_t dims[] = {4, 8, 8}; - uint8_t wdata[256]; /* 4*8*8, from dims */ +generate_uint8be(hbool_t external) { + hsize_t dims[] = { 4, 8, 8 }; + uint8_t wdata[256]; /* 4*8*8, from dims */ struct external_def *def_ptr = NULL; - struct external_def def = { (hsize_t)sizeof(uint8_t), 64, 256 }; + struct external_def def = { (hsize_t) sizeof(uint8_t), 64, 256 }; uint8_t n = 0; int i = 0; int j = 0; @@ -330,84 +262,79 @@ generate_uint8be(hbool_t external) int ret_value = 0; /* Generate values, ping-pong from ends of range - */ - for (i=0, n=0; i < dims[0]; i++) { - for (j=0; j < dims[1]; j++) { - for (k=0; k < dims[2]; k++, n++) { - wdata[n] = n * ((n&1) ? (-1) : (1)); + */ + for (i = 0, n = 0; i < dims[0]; i++) { + for (j = 0; j < dims[1]; j++) { + for (k = 0; k < dims[2]; k++, n++) { + wdata[n] = n * ((n & 1) ? (-1) : (1)); } } } def_ptr = (TRUE == external) ? (&def) : NULL; - if (__make_file(FILE_UINT8BE, def_ptr, H5T_STD_U8BE, 3, dims, wdata) < 0) { + if (__make_file(FILE_UINT8BE, def_ptr, H5T_STD_U8BE, 3, dims, wdata) < 0) ret_value = -1; - } return ret_value; } /* end generate_uint8be() */ - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Returns 0 on success, -1 on failure. */ static int -generate_f32le(hbool_t external) -{ - hsize_t dims[] = {12, 6}; - float wdata[72]; /* 12*6, from dims */ +generate_f32le(hbool_t external) { + hsize_t dims[] = { 12, 6 }; + float wdata[72]; /* 12*6, from dims */ struct external_def *def_ptr = NULL; - struct external_def def = { - (hsize_t)sizeof(float), - 72, - 72 - }; - float n = 0; - int i = 0; - int j = 0; - int k = 0; - int ret_value = 0; + struct external_def def = { (hsize_t) sizeof(float), 72, 72 }; + float n = 0; + int i = 0; + int j = 0; + int k = 0; + int ret_value = 0; /* Generate values */ - for (i=0, k=0, n=0; i < dims[0]; i++) { - for (j=0; j < dims[1]; j++, k++, n++) { + for (i = 0, k = 0, n = 0; i < dims[0]; i++) { + for (j = 0; j < dims[1]; j++, k++, n++) { wdata[k] = n * 801.1 * ((k % 5 == 1) ? (-1) : (1)); } } def_ptr = (TRUE == external) ? (&def) : NULL; - if (__make_file(FILE_F32LE, def_ptr, H5T_IEEE_F32LE, 2, dims, wdata) < 0) { + if (__make_file(FILE_F32LE, def_ptr, H5T_IEEE_F32LE, 2, dims, wdata) < 0) ret_value = -1; - } return ret_value; } /* end generate_f32le() */ - /* ---------------------------------------------------------------------------- * Create files. * Return 0 on success, nonzero on failure. */ int -main(void) -{ - int i = 0; +main(void) { + int i = 0; int ret_value = 0; - for (i=0; i < 2; i++) { - hbool_t external = (i&1) ? TRUE : FALSE; - if (ret_value == 0) { ret_value -= generate_int32le_1d(external); } - if (ret_value == 0) { ret_value -= generate_int32le_2d(external); } - if (ret_value == 0) { ret_value -= generate_int32le_3d(external); } - if (ret_value == 0) { ret_value -= generate_uint8be(external); } - if (ret_value == 0) { ret_value -= generate_f32le(external); } - } /* end for external data storage or not */ + for (i = 0; i < 2; i++) { + hbool_t external = (i & 1) ? TRUE : FALSE; + if (generate_int32le_1d(external) < 0) + HDprintf("A generate_int32le_1d failed!\n"); - if (ret_value != 0) { - HDprintf("A problem occurred!\n"); - } + if (generate_int32le_2d(external) < 0) + HDprintf("A generate_int32le_2d failed!\n"); - return ret_value; -} /* end main() */ + if (generate_int32le_3d(external) < 0) + HDprintf("A generate_int32le_3d failed!\n"); + if (generate_uint8be(external) < 0) + HDprintf("A generate_uint8be failed!\n"); + + if (generate_f32le(external) < 0) + HDprintf("A generate_f32le failed!\n"); + + } /* end for external data storage or not */ + + return EXIT_SUCCESS; +} /* end main() */ diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index ec8df3c..f3e6cd3 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -4079,7 +4079,7 @@ int write_dset_in(hid_t loc_id, goto out; if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf5) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf5) < 0) goto out; if (H5Dclose(did) < 0) goto out; @@ -4312,7 +4312,7 @@ int write_dset_in(hid_t loc_id, goto out; if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf52) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf52) < 0) goto out; if (H5Dclose(did) < 0) goto out; @@ -4533,7 +4533,7 @@ int write_dset_in(hid_t loc_id, if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf53) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf53) < 0) goto out; if (H5Dclose(did) < 0) @@ -5009,7 +5009,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf5) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf5) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf5) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -5331,7 +5331,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf52) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf52) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf52) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -5793,7 +5793,7 @@ int write_attr_in(hid_t loc_id, goto out; if (H5Awrite(aid, tid, buf53) < 0) goto out; - if (H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf53) < 0) + if (H5Treclaim(tid, sid, H5P_DEFAULT, buf53) < 0) goto out; if (H5Aclose(aid) < 0) goto out; @@ -7036,10 +7036,10 @@ static herr_t make_complex_attr_references(hid_t loc_id) } /* close resource for vlen data */ - status = H5Dvlen_reclaim (vlen_objref_attr_tid, vlen_objref_attr_sid, H5P_DEFAULT, vlen_objref_data); + status = H5Treclaim (vlen_objref_attr_tid, vlen_objref_attr_sid, H5P_DEFAULT, vlen_objref_data); if (status < 0) { - HDfprintf(stderr, "Error: %s %d> H5Dvlen_reclaim failed.\n", FUNC, __LINE__); + HDfprintf(stderr, "Error: %s %d> H5Treclaim failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } @@ -7091,10 +7091,10 @@ static herr_t make_complex_attr_references(hid_t loc_id) } /* close resource for vlen data */ - status = H5Dvlen_reclaim (vlen_regref_attr_tid, vlen_regref_attr_sid, H5P_DEFAULT, vlen_regref_data); + status = H5Treclaim (vlen_regref_attr_tid, vlen_regref_attr_sid, H5P_DEFAULT, vlen_regref_data); if (status < 0) { - HDfprintf(stderr, "Error: %s %d> H5Dvlen_reclaim failed.\n", FUNC, __LINE__); + HDfprintf(stderr, "Error: %s %d> H5Treclaim failed.\n", FUNC, __LINE__); ret = FAIL; goto out; } |