summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--MANIFEST49
-rw-r--r--README.txt2
-rwxr-xr-xbin/trace2
-rw-r--r--[-rwxr-xr-x]c++/COPYING0
-rw-r--r--[-rwxr-xr-x]c++/examples/run-c++-ex.sh.in0
-rw-r--r--[-rwxr-xr-x]c++/examples/testh5c++.sh.in0
-rw-r--r--c++/src/H5AtomType.cpp8
-rw-r--r--c++/src/H5Attribute.cpp25
-rw-r--r--c++/src/H5CommonFG.cpp58
-rw-r--r--c++/src/H5DataSet.cpp48
-rw-r--r--c++/src/H5DataSpace.cpp8
-rw-r--r--c++/src/H5DataType.cpp44
-rw-r--r--c++/src/H5DcreatProp.cpp8
-rw-r--r--c++/src/H5DxferProp.cpp4
-rw-r--r--c++/src/H5FaccProp.cpp66
-rw-r--r--c++/src/H5FcreatProp.cpp10
-rw-r--r--c++/src/H5File.cpp26
-rw-r--r--c++/src/H5Group.cpp30
-rw-r--r--c++/src/H5IdComponent.cpp10
-rw-r--r--c++/src/H5Library.cpp4
-rw-r--r--c++/src/H5Object.cpp24
-rw-r--r--c++/src/H5PredType.cpp8
-rw-r--r--c++/src/H5PredType.h17
-rw-r--r--c++/src/H5PropList.cpp2
-rw-r--r--c++/src/H5StrType.cpp4
-rw-r--r--c++/src/Makefile.in2
-rw-r--r--[-rwxr-xr-x]c++/src/h5c++.in2
-rw-r--r--c++/test/dsets.cpp75
-rw-r--r--[-rwxr-xr-x]config/COPYING0
-rw-r--r--[-rwxr-xr-x]config/Makefile.am.blank0
-rwxr-xr-xconfig/cmake/CTestCustom.cmake3
-rw-r--r--config/cmake/ConfigureChecks.cmake16
-rw-r--r--config/cmake/FindSZIP.cmake18
-rw-r--r--config/cmake/H5pubconf.h.in3
-rw-r--r--config/cmake/HDFLibMacros.cmake87
-rw-r--r--config/cmake/HDFMacros.cmake16
-rw-r--r--config/gnu-flags76
-rw-r--r--config/lt_vers.am2
-rwxr-xr-xconfigure56
-rw-r--r--configure.in37
-rw-r--r--[-rwxr-xr-x]examples/run-c-ex.sh.in0
-rw-r--r--[-rwxr-xr-x]examples/testh5cc.sh.in0
-rw-r--r--[-rwxr-xr-x]fortran/COPYING0
-rw-r--r--[-rwxr-xr-x]fortran/examples/run-fortran-ex.sh.in0
-rw-r--r--[-rwxr-xr-x]fortran/examples/testh5fc.sh.in0
-rw-r--r--fortran/src/H5Of.c57
-rw-r--r--fortran/src/H5Off.f90175
-rw-r--r--fortran/src/H5Pff.f9035
-rw-r--r--fortran/src/H5f90proto.h7
-rw-r--r--fortran/src/Makefile.in2
-rw-r--r--[-rwxr-xr-x]fortran/src/h5fc.in2
-rw-r--r--fortran/src/hdf5_fortrandll.def1
-rw-r--r--fortran/src/phdf5_fortrandll.def1
-rw-r--r--fortran/test/CMakeLists.txt3
-rw-r--r--fortran/test/tH5O.f90256
-rw-r--r--[-rwxr-xr-x]hl/COPYING0
-rw-r--r--[-rwxr-xr-x]hl/Makefile.in0
-rw-r--r--[-rwxr-xr-x]hl/c++/COPYING0
-rw-r--r--[-rwxr-xr-x]hl/c++/examples/run-hlc++-ex.sh.in0
-rw-r--r--hl/c++/src/Makefile.in2
-rw-r--r--[-rwxr-xr-x]hl/examples/run-hlc-ex.sh.in0
-rw-r--r--[-rwxr-xr-x]hl/fortran/COPYING0
-rw-r--r--[-rwxr-xr-x]hl/fortran/examples/run-hlfortran-ex.sh.in0
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5DSfc.c4
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5DSff.f900
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5IMfc.c0
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5IMff.f900
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5LTf90proto.h3
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5LTfc.c32
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5LTff.f9016
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5TBfc.c0
-rw-r--r--[-rwxr-xr-x]hl/fortran/src/H5TBff.f900
-rw-r--r--hl/fortran/src/Makefile.in2
-rw-r--r--hl/fortran/test/tstds.f9010
-rw-r--r--[-rwxr-xr-x]hl/fortran/test/tstimage.f900
-rw-r--r--hl/fortran/test/tstlite.f9053
-rw-r--r--[-rwxr-xr-x]hl/fortran/test/tsttable.f900
-rw-r--r--[-rwxr-xr-x]hl/src/COPYING0
-rw-r--r--hl/src/H5LT.c571
-rw-r--r--hl/src/H5LTpublic.h18
-rw-r--r--hl/src/Makefile.in2
-rw-r--r--hl/test/Makefile.am4
-rw-r--r--hl/test/Makefile.in27
-rw-r--r--hl/test/h5hltest.h6
-rw-r--r--hl/test/test_file_image.c518
-rw-r--r--[-rwxr-xr-x]hl/tools/COPYING0
-rw-r--r--[-rwxr-xr-x]perform/COPYING0
-rw-r--r--release_docs/RELEASE.txt42
-rw-r--r--src/H5A.c30
-rw-r--r--src/H5Aint.c10
-rw-r--r--src/H5Apkg.h26
-rw-r--r--src/H5Aprivate.h32
-rw-r--r--src/H5Bcache.c4
-rw-r--r--src/H5Dchunk.c2
-rw-r--r--src/H5Dcontig.c13
-rw-r--r--src/H5Dint.c4
-rw-r--r--src/H5Dio.c2
-rw-r--r--src/H5Dlayout.c22
-rw-r--r--src/H5Doh.c50
-rw-r--r--src/H5Dpkg.h1
-rw-r--r--src/H5E.c12
-rw-r--r--src/H5Edefin.h1
-rw-r--r--src/H5Einit.h5
-rw-r--r--src/H5Epubgen.h2
-rw-r--r--src/H5Eterm.h3
-rw-r--r--src/H5F.c323
-rw-r--r--src/H5FD.c82
-rw-r--r--src/H5FDcore.c303
-rw-r--r--src/H5FDfamily.c2
-rw-r--r--src/H5FDlog.c2
-rw-r--r--src/H5FDprivate.h26
-rw-r--r--src/H5FDpublic.h40
-rw-r--r--src/H5FDsec2.c2
-rw-r--r--src/H5FDstdio.c673
-rw-r--r--src/H5FSprivate.h2
-rw-r--r--src/H5FSsection.c2
-rw-r--r--src/H5Fmpi.c4
-rw-r--r--src/H5Fprivate.h5
-rw-r--r--src/H5Fpublic.h1
-rw-r--r--src/H5Gname.c11
-rw-r--r--src/H5Goh.c3
-rw-r--r--src/H5HF.c32
-rw-r--r--src/H5HFbtree2.c8
-rw-r--r--src/H5HFdbg.c195
-rw-r--r--src/H5HFhuge.c4
-rw-r--r--src/H5HFiblock.c146
-rw-r--r--src/H5HFpkg.h19
-rw-r--r--src/H5HFsection.c52
-rw-r--r--src/H5HFspace.c181
-rw-r--r--src/H5I.c147
-rw-r--r--src/H5Iprivate.h2
-rw-r--r--src/H5MF.c4
-rw-r--r--src/H5MFdbg.c4
-rw-r--r--src/H5O.c6
-rw-r--r--src/H5Oainfo.c14
-rw-r--r--src/H5Oattr.c1
-rw-r--r--src/H5Oattribute.c22
-rw-r--r--src/H5Ocopy.c813
-rw-r--r--src/H5Odtype.c38
-rw-r--r--src/H5Oefl.c8
-rw-r--r--src/H5Ofill.c2
-rw-r--r--src/H5Olayout.c8
-rw-r--r--src/H5Olinfo.c16
-rw-r--r--src/H5Olink.c16
-rw-r--r--src/H5Omessage.c6
-rw-r--r--src/H5Opkg.h15
-rw-r--r--src/H5Opline.c1
-rw-r--r--src/H5Oprivate.h22
-rw-r--r--src/H5Opublic.h11
-rw-r--r--src/H5Osdspace.c1
-rw-r--r--src/H5Oshared.c17
-rw-r--r--src/H5Oshared.h21
-rw-r--r--src/H5Ostab.c18
-rw-r--r--src/H5Pdcpl.c2
-rw-r--r--src/H5Pfapl.c500
-rw-r--r--src/H5Pint.c54
-rw-r--r--[-rwxr-xr-x]src/H5Pocpl.c0
-rw-r--r--[-rwxr-xr-x]src/H5Pocpypl.c447
-rw-r--r--src/H5Ppublic.h11
-rw-r--r--[-rwxr-xr-x]src/H5SM.c5
-rw-r--r--[-rwxr-xr-x]src/H5SMbtree2.c0
-rw-r--r--[-rwxr-xr-x]src/H5SMpkg.h0
-rw-r--r--[-rwxr-xr-x]src/H5SMprivate.h0
-rw-r--r--src/H5T.c3
-rw-r--r--src/H5Toh.c3
-rw-r--r--src/H5VL.c3
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5private.h2
-rw-r--r--src/H5public.h4
-rw-r--r--src/H5win32defs.h6
-rw-r--r--[-rwxr-xr-x]src/Makefile.am0
-rw-r--r--src/Makefile.in2
-rw-r--r--[-rwxr-xr-x]src/hdf5.lnt0
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/Makefile.am4
-rw-r--r--test/Makefile.in57
-rw-r--r--test/fheap.c132
-rw-r--r--test/file_image.c1335
-rw-r--r--test/file_image_core_test.h5bin0 -> 18528 bytes
-rw-r--r--test/gen_file_image.c91
-rw-r--r--test/istore.c27
-rw-r--r--test/objcopy.c3733
-rw-r--r--testpar/CMakeLists.txt1
-rw-r--r--[-rwxr-xr-x]testpar/COPYING0
-rw-r--r--testpar/Makefile.am4
-rw-r--r--testpar/Makefile.in12
-rw-r--r--testpar/t_file_image.c395
-rw-r--r--testpar/testphdf5.c7
-rw-r--r--testpar/testphdf5.h1
-rw-r--r--[-rwxr-xr-x]tools/COPYING0
-rw-r--r--tools/h5diff/CMakeLists.txt12
-rw-r--r--tools/h5diff/h5diffgentest.c163
-rw-r--r--[-rwxr-xr-x]tools/h5diff/testfiles/h5diff_101w.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5diff/testfiles/h5diff_102w.txt0
-rw-r--r--tools/h5diff/testfiles/h5diff_20.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_21.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_22.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_222.txt3
-rw-r--r--tools/h5diff/testfiles/h5diff_223.txt4
-rw-r--r--tools/h5diff/testfiles/h5diff_224.txt4
-rw-r--r--[-rwxr-xr-x]tools/h5diff/testfiles/h5diff_300.txt0
-rw-r--r--tools/h5diff/testfiles/h5diff_505.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_507.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_509.txt2
-rw-r--r--tools/h5diff/testfiles/h5diff_515.txt7
-rw-r--r--tools/h5diff/testfiles/h5diff_517.txt7
-rw-r--r--[-rwxr-xr-x]tools/h5diff/testfiles/h5diff_enum_invalid_values.h5bin2192 -> 2192 bytes
-rw-r--r--[-rwxr-xr-x]tools/h5diff/testfiles/h5diff_links.h5bin2536 -> 2536 bytes
-rw-r--r--tools/h5diff/testfiles/non_comparables1.h5bin6568 -> 8628 bytes
-rw-r--r--tools/h5diff/testfiles/non_comparables2.h5bin6584 -> 8644 bytes
-rwxr-xr-xtools/h5diff/testh5diff.sh11
-rw-r--r--[-rwxr-xr-x]tools/h5dump/testh5dumpxml.sh.in0
-rw-r--r--[-rwxr-xr-x]tools/h5import/Makefile.in0
-rw-r--r--[-rwxr-xr-x]tools/h5import/h5import.c0
-rw-r--r--[-rwxr-xr-x]tools/h5import/h5import.h0
-rw-r--r--[-rwxr-xr-x]tools/h5import/h5importtest.c0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binfp64.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binin16.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binin32.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binin8.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binuin16.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/binuin32.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtfp32.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtfp32.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtfp64.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtfp64.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtin16.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtin32.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtin8.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtuin16.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtuin32.conf0
-rw-r--r--[-rwxr-xr-x]tools/h5import/testfiles/txtuin32.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5jam/testfiles/u10.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5jam/testfiles/u511.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5jam/testfiles/u512.txt0
-rw-r--r--[-rwxr-xr-x]tools/h5jam/testfiles/u513.txt0
-rw-r--r--tools/h5repack/CMakeLists.txt70
-rw-r--r--tools/h5repack/h5repack.c6
-rw-r--r--tools/h5repack/h5repack.h1
-rw-r--r--[-rwxr-xr-x]tools/h5repack/h5repack.sh.in61
-rw-r--r--tools/h5repack/h5repack_copy.c154
-rw-r--r--tools/h5repack/h5repack_main.c34
-rw-r--r--tools/h5repack/h5repacktst.c67
-rw-r--r--tools/h5stat/h5stat.c281
-rw-r--r--tools/lib/h5diff.c376
-rw-r--r--tools/lib/h5diff.h2
-rw-r--r--[-rwxr-xr-x]tools/misc/h5cc.in2
-rw-r--r--[-rwxr-xr-x]tools/misc/h5redeploy.in0
-rw-r--r--[-rwxr-xr-x]vms/COPYING0
-rw-r--r--vms/src/h5pubconf.h6
-rw-r--r--[-rwxr-xr-x]windows/COPYING0
-rw-r--r--[-rwxr-xr-x]windows/examples/testExamples_exp_output.txt0
-rw-r--r--windows/src/H5pubconf.h6
254 files changed, 12293 insertions, 2094 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe8a5f8..5543b48 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -919,6 +919,7 @@ IF (NOT HDF5_EXTERNALLY_CONFIGURED AND NOT HDF5_NO_PACKAGES)
SET (CPACK_PACKAGE_VENDOR "HDF Group")
SET (CPACK_PACKAGE_NAME "${HDF5_PACKAGE_NAME}")
SET (CPACK_PACKAGE_INSTALL_DIRECTORY "${HDF5_PACKAGE_NAME}")
+ SET (CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${HDF5_PACKAGE_NAME}-${HDF5_PACKAGE_VERSION}-${LIB_TYPE}")
SET (CPACK_PACKAGE_VERSION "${HDF5_PACKAGE_VERSION}")
SET (CPACK_PACKAGE_VERSION_MAJOR "${HDF5_PACKAGE_VERSION_MAJOR}")
SET (CPACK_PACKAGE_VERSION_MINOR "${HDF5_PACKAGE_VERSION_MINOR}")
@@ -935,8 +936,9 @@ IF (NOT HDF5_EXTERNALLY_CONFIGURED AND NOT HDF5_NO_PACKAGES)
SET (CPACK_NSIS_PACKAGE_NAME "HDF5 ${HDF5_PACKAGE_VERSION}")
ELSE (WIN32)
SET (CPACK_RPM_COMPONENT_INSTALL ON)
+ SET (CPACK_ARCHIVE_COMPONENT_INSTALL ON)
+ SET (CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE ON)
ENDIF (WIN32)
- SET (CPACK_MONOLITHIC_INSTALL ON)
INCLUDE(InstallRequiredSystemLibraries)
diff --git a/MANIFEST b/MANIFEST
index fe3a612..a163532 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -963,32 +963,35 @@
./test/filespace_1_8.h5
./test/filespace_1_6.h5
./test/freespace.c
+./test/file_image.c
+./test/file_image_core_test.h5
./test/fill_old.h5
./test/fillval.c
./test/filter_fail.c
./test/flush1.c
./test/flush2.c
-./test/gen_bad_ohdr.c _DO_NOT_DISTRIBUTE_
-./test/gen_bad_compound.c _DO_NOT_DISTRIBUTE_
-./test/gen_bogus.c _DO_NOT_DISTRIBUTE_
-./test/gen_cross.c _DO_NOT_DISTRIBUTE_
-./test/gen_deflate.c _DO_NOT_DISTRIBUTE_
-./test/gen_filespace.c _DO_NOT_DISTRIBUTE_
-./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_
-./test/gen_new_array.c _DO_NOT_DISTRIBUTE_
-./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_
-./test/gen_new_group.c _DO_NOT_DISTRIBUTE_
-./test/gen_new_mtime.c _DO_NOT_DISTRIBUTE_
-./test/gen_new_super.c _DO_NOT_DISTRIBUTE_
-./test/gen_noencoder.c _DO_NOT_DISTRIBUTE_
-./test/gen_nullspace.c _DO_NOT_DISTRIBUTE_
-./test/gen_old_array.c _DO_NOT_DISTRIBUTE_
-./test/gen_old_group.c _DO_NOT_DISTRIBUTE_
-./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_
-./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
-./test/gen_sizes_lheap.c _DO_NOT_DISTRIBUTE_
-./test/gen_specmetaread.c _DO_NOT_DISTRIBUTE_
-./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_
+./test/gen_bad_ohdr.c _DO_NOT_DISTRIBUTE_
+./test/gen_bad_compound.c _DO_NOT_DISTRIBUTE_
+./test/gen_bogus.c _DO_NOT_DISTRIBUTE_
+./test/gen_cross.c _DO_NOT_DISTRIBUTE_
+./test/gen_deflate.c _DO_NOT_DISTRIBUTE_
+./test/gen_file_image.c _DO_NOT_DISTRIBUTE_
+./test/gen_filespace.c _DO_NOT_DISTRIBUTE_
+./test/gen_mergemsg.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_array.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_fill.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_group.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_mtime.c _DO_NOT_DISTRIBUTE_
+./test/gen_new_super.c _DO_NOT_DISTRIBUTE_
+./test/gen_noencoder.c _DO_NOT_DISTRIBUTE_
+./test/gen_nullspace.c _DO_NOT_DISTRIBUTE_
+./test/gen_old_array.c _DO_NOT_DISTRIBUTE_
+./test/gen_old_group.c _DO_NOT_DISTRIBUTE_
+./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_
+./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
+./test/gen_sizes_lheap.c _DO_NOT_DISTRIBUTE_
+./test/gen_specmetaread.c _DO_NOT_DISTRIBUTE_
+./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_
./test/getname.c
./test/gheap.c
./test/group_old.h5
@@ -1083,6 +1086,7 @@
./testpar/t_cache.c
./testpar/t_dset.c
./testpar/t_file.c
+./testpar/t_file_image.c
./testpar/t_mdset.c
./testpar/t_mpi.c
./testpar/t_ph5basic.c
@@ -1815,6 +1819,8 @@
./tools/h5diff/testfiles/h5diff_220.txt
./tools/h5diff/testfiles/h5diff_221.txt
./tools/h5diff/testfiles/h5diff_222.txt
+./tools/h5diff/testfiles/h5diff_223.txt
+./tools/h5diff/testfiles/h5diff_224.txt
./tools/h5diff/testfiles/h5diff_300.txt
./tools/h5diff/testfiles/h5diff_400.txt
./tools/h5diff/testfiles/h5diff_401.txt
@@ -2073,6 +2079,7 @@
./hl/test/sepia.pal
./hl/test/gen_test_ds.c
./hl/test/test_ds.c
+./hl/test/test_file_image.c
./hl/test/test_image.c
./hl/test/test_lite.c
./hl/test/test_packet.c
diff --git a/README.txt b/README.txt
index 1934e39..df15871 100644
--- a/README.txt
+++ b/README.txt
@@ -1,4 +1,4 @@
-HDF5 version 1.9.112 currently under development
+HDF5 version 1.9.114 currently under development
Please refer to the release_docs/INSTALL file for installation instructions.
------------------------------------------------------------------------------
diff --git a/bin/trace b/bin/trace
index bfaae19..a35e106 100755
--- a/bin/trace
+++ b/bin/trace
@@ -109,6 +109,7 @@ $Source = "";
"H5FD_t" => "x",
"H5FD_class_t" => "x",
"H5FD_stream_fapl_t" => "x",
+ "H5FD_file_image_callbacks_t" => "x",
"H5G_iterate_t" => "x",
"H5G_info_t" => "x",
"H5I_free_t" => "x",
@@ -119,6 +120,7 @@ $Source = "";
"H5MM_free_t" => "x",
"H5O_info_t" => "x",
"H5O_iterate_t" => "x",
+ "H5O_mcdt_search_cb_t" => "x",
"H5P_cls_create_func_t" => "x",
"H5P_cls_copy_func_t" => "x",
"H5P_cls_close_func_t" => "x",
diff --git a/c++/COPYING b/c++/COPYING
index 6903daf..6903daf 100755..100644
--- a/c++/COPYING
+++ b/c++/COPYING
diff --git a/c++/examples/run-c++-ex.sh.in b/c++/examples/run-c++-ex.sh.in
index 6b33577..6b33577 100755..100644
--- a/c++/examples/run-c++-ex.sh.in
+++ b/c++/examples/run-c++-ex.sh.in
diff --git a/c++/examples/testh5c++.sh.in b/c++/examples/testh5c++.sh.in
index 4281e3c..4281e3c 100755..100644
--- a/c++/examples/testh5c++.sh.in
+++ b/c++/examples/testh5c++.sh.in
diff --git a/c++/src/H5AtomType.cpp b/c++/src/H5AtomType.cpp
index 773fc5d..975cad6 100644
--- a/c++/src/H5AtomType.cpp
+++ b/c++/src/H5AtomType.cpp
@@ -98,7 +98,7 @@ H5T_order_t AtomType::getOrder() const
//--------------------------------------------------------------------------
// Function: AtomType::getOrder
///\brief This is an overloaded member function, provided for convenience.
-/// It takes a reference to a \c std::string for the buffer that
+/// It takes a reference to a \c H5std_string for the buffer that
/// provide the text description of the returned byte order.
/// The text description can be either of the following:
/// "Little endian byte ordering (0)";
@@ -178,7 +178,7 @@ size_t AtomType::getPrecision() const
///\exception H5::DataTypeIException
///\par Description
/// For information, please see C layer Reference Manuat at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5T.html#Datatype-SetPrecision
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-SetPrecision
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void AtomType::setPrecision( size_t precision ) const
@@ -198,7 +198,7 @@ void AtomType::setPrecision( size_t precision ) const
///\exception H5::DataTypeIException
///\par Description
/// For information, please see C layer Reference Manuat at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5T.html#Datatype-GetOffset
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-GetOffset
// Programmer Binh-Minh Ribler - 2000
// Modification
// 12/05/00: due to C API change
@@ -225,7 +225,7 @@ int AtomType::getOffset() const
///\exception H5::DataTypeIException
///\par Description
/// For information, please see C layer Reference Manuat at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5T.html#Datatype-SetOffset
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-SetOffset
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void AtomType::setOffset( size_t offset ) const
diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp
index dad347f..226ae5c 100644
--- a/c++/src/H5Attribute.cpp
+++ b/c++/src/H5Attribute.cpp
@@ -198,7 +198,7 @@ void Attribute::read(const DataType& mem_type, H5std_string& strg) const
//--------------------------------------------------------------------------
size_t Attribute::getInMemDataSize() const
{
- char *func = "Attribute::getInMemDataSize";
+ const char *func = "Attribute::getInMemDataSize";
// Get the data type of this attribute
hid_t mem_type_id = H5Aget_type(id);
@@ -207,7 +207,8 @@ size_t Attribute::getInMemDataSize() const
throw AttributeIException(func, "H5Aget_type failed");
}
- // Get the data type's size
+ // Get the data type's size by first getting its native type then getting
+ // the native type's size.
hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT);
if (native_type < 0)
{
@@ -219,7 +220,18 @@ size_t Attribute::getInMemDataSize() const
throw AttributeIException(func, "H5Tget_size failed");
}
- // Get number of elements of the attribute
+ // Close the native type and the datatype of this attribute.
+ if (H5Tclose(native_type) < 0)
+ {
+ throw DataSetIException(func, "H5Tclose(native_type) failed");
+ }
+ if (H5Tclose(mem_type_id) < 0)
+ {
+ throw DataSetIException(func, "H5Tclose(mem_type_id) failed");
+ }
+
+ // Get number of elements of the attribute by first getting its dataspace
+ // then getting the number of elements in the dataspace
hid_t space_id = H5Aget_space(id);
if (space_id < 0)
{
@@ -231,6 +243,12 @@ size_t Attribute::getInMemDataSize() const
throw AttributeIException(func, "H5Sget_simple_extent_npoints failed");
}
+ // Close the dataspace
+ if (H5Sclose(space_id) < 0)
+ {
+ throw DataSetIException(func, "H5Sclose failed");
+ }
+
// Calculate and return the size of the data
size_t data_size = type_size * num_elements;
return(data_size);
@@ -451,7 +469,6 @@ void Attribute::p_read_fixed_len(const DataType& mem_type, H5std_string& strg) c
//--------------------------------------------------------------------------
void Attribute::p_read_variable_len(const DataType& mem_type, H5std_string& strg) const
{
-
// Prepare and call C API to read attribute.
char *strg_C;
diff --git a/c++/src/H5CommonFG.cpp b/c++/src/H5CommonFG.cpp
index 5b93bd5..6a8609f 100644
--- a/c++/src/H5CommonFG.cpp
+++ b/c++/src/H5CommonFG.cpp
@@ -31,7 +31,7 @@
#include "H5DataSet.h"
#include "H5File.h"
#include "H5Alltypes.h"
-#include "H5private.h" // for HDstrcpy
+#include "H5private.h" // for HDstrcpy
// There are a few comments that are common to most of the functions
// defined in this file so they are listed here.
@@ -101,7 +101,7 @@ Group CommonFG::createGroup( const char* name, size_t size_hint ) const
// Function: CommonFG::createGroup
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
Group CommonFG::createGroup( const H5std_string& name, size_t size_hint ) const
@@ -139,7 +139,7 @@ Group CommonFG::openGroup( const char* name ) const
// Function: CommonFG::openGroup
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
Group CommonFG::openGroup( const H5std_string& name ) const
@@ -183,7 +183,7 @@ DataSet CommonFG::createDataSet( const char* name, const DataType& data_type, co
// Function: CommonFG::createDataSet
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
DataSet CommonFG::createDataSet( const H5std_string& name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist ) const
@@ -218,7 +218,7 @@ DataSet CommonFG::openDataSet( const char* name ) const
// Function: CommonFG::openDataSet
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
DataSet CommonFG::openDataSet( const H5std_string& name ) const
@@ -275,7 +275,7 @@ void CommonFG::link( H5L_type_t link_type, const char* curr_name, const char* ne
// Function: CommonFG::link
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a curr_name and \a new_name.
+/// \c H5std_string for \a curr_name and \a new_name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::link( H5L_type_t link_type, const H5std_string& curr_name, const H5std_string& new_name ) const
@@ -305,7 +305,7 @@ void CommonFG::unlink( const char* name ) const
// Function: CommonFG::unlink
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::unlink( const H5std_string& name ) const
@@ -322,8 +322,8 @@ void CommonFG::unlink( const H5std_string& name ) const
///\note
/// Exercise care in moving groups as it is possible to render
/// data in a file inaccessible with Group::move. Please refer
-/// to the Group Interface in the HDF5 User's Guide at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/Groups.html
+/// to the Group Interface in the HDF5 User's Guide for details at:
+/// http://www.hdfgroup.org/HDF5/doc/UG/UG_frame09Groups.html
// Programmer Binh-Minh Ribler - 2000
// Modification
// 2007: QAK modified to use H5L APIs - BMR
@@ -341,7 +341,7 @@ void CommonFG::move( const char* src, const char* dst ) const
// Function: CommonFG::move
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a src and \a dst.
+/// \c H5std_string for \a src and \a dst.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::move( const H5std_string& src, const H5std_string& dst ) const
@@ -360,7 +360,7 @@ void CommonFG::move( const H5std_string& src, const H5std_string& dst ) const
///\par Description
/// For more information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5G.html#Group-GetObjinfo
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5G.html#Group-GetObjinfo
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::getObjinfo( const char* name, hbool_t follow_link, H5G_stat_t& statbuf ) const
@@ -376,7 +376,7 @@ void CommonFG::getObjinfo( const char* name, hbool_t follow_link, H5G_stat_t& st
// Function: CommonFG::getObjinfo
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::getObjinfo( const H5std_string& name, hbool_t follow_link, H5G_stat_t& statbuf ) const
@@ -405,7 +405,7 @@ void CommonFG::getObjinfo( const char* name, H5G_stat_t& statbuf ) const
// Function: CommonFG::getObjinfo
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - Nov, 2005
//--------------------------------------------------------------------------
void CommonFG::getObjinfo( const H5std_string& name, H5G_stat_t& statbuf ) const
@@ -462,7 +462,7 @@ H5std_string CommonFG::getLinkval( const char* name, size_t size ) const
// Function: CommonFG::getLinkval
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
H5std_string CommonFG::getLinkval( const H5std_string& name, size_t size ) const
@@ -503,7 +503,7 @@ void CommonFG::setComment( const char* name, const char* comment ) const
// Function: CommonFG::setComment
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name and \a comment.
+/// \c H5std_string for \a name and \a comment.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::setComment( const H5std_string& name, const H5std_string& comment ) const
@@ -535,7 +535,7 @@ void CommonFG::removeComment(const char* name) const
// Function: CommonFG::removeComment
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - May 2005
//--------------------------------------------------------------------------
void CommonFG::removeComment(const H5std_string& name) const
@@ -596,7 +596,7 @@ H5std_string CommonFG::getComment( const char* name, size_t bufsize ) const
// Function: CommonFG::getComment
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
H5std_string CommonFG::getComment( const H5std_string& name, size_t bufsize ) const
@@ -633,7 +633,7 @@ void CommonFG::mount( const char* name, H5File& child, PropList& plist ) const
// Function: CommonFG::mount
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::mount( const H5std_string& name, H5File& child, PropList& plist ) const
@@ -664,7 +664,7 @@ void CommonFG::unmount( const char* name ) const
// Function: CommonFG::unmount
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void CommonFG::unmount( const H5std_string& name ) const
@@ -699,7 +699,7 @@ DataType CommonFG::openDataType( const char* name ) const
// Function: CommonFG::openDataType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
DataType CommonFG::openDataType( const H5std_string& name ) const
@@ -734,7 +734,7 @@ ArrayType CommonFG::openArrayType( const char* name ) const
// Function: CommonFG::openArrayType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - Jul, 2005
//--------------------------------------------------------------------------
ArrayType CommonFG::openArrayType( const H5std_string& name ) const
@@ -769,7 +769,7 @@ CompType CommonFG::openCompType( const char* name ) const
// Function: CommonFG::openCompType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
CompType CommonFG::openCompType( const H5std_string& name ) const
@@ -804,7 +804,7 @@ EnumType CommonFG::openEnumType( const char* name ) const
// Function: CommonFG::openEnumType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
EnumType CommonFG::openEnumType( const H5std_string& name ) const
@@ -839,7 +839,7 @@ IntType CommonFG::openIntType( const char* name ) const
// Function: CommonFG::openIntType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
IntType CommonFG::openIntType( const H5std_string& name ) const
@@ -874,7 +874,7 @@ FloatType CommonFG::openFloatType( const char* name ) const
// Function: CommonFG::openFloatType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
FloatType CommonFG::openFloatType( const H5std_string& name ) const
@@ -909,7 +909,7 @@ StrType CommonFG::openStrType( const char* name ) const
// Function: CommonFG::openStrType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
StrType CommonFG::openStrType( const H5std_string& name ) const
@@ -944,7 +944,7 @@ VarLenType CommonFG::openVarLenType( const char* name ) const
// Function: CommonFG::openVarLenType
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - Jul, 2005
//--------------------------------------------------------------------------
VarLenType CommonFG::openVarLenType( const H5std_string& name ) const
@@ -980,7 +980,7 @@ int CommonFG::iterateElems( const char* name, int *idx, H5G_iterate_t op , void*
// Function: CommonFG::iterateElems
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
int CommonFG::iterateElems( const H5std_string& name, int *idx, H5G_iterate_t op , void* op_data )
@@ -1073,7 +1073,7 @@ ssize_t CommonFG::getObjnameByIdx(hsize_t idx, char* name, size_t size) const
// Function: CommonFG::getObjnameByIdx
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for \a name.
+/// \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - January, 2003
//--------------------------------------------------------------------------
ssize_t CommonFG::getObjnameByIdx(hsize_t idx, H5std_string& name, size_t size) const
diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp
index 7351bbf..f7aaa72 100644
--- a/c++/src/H5DataSet.cpp
+++ b/c++/src/H5DataSet.cpp
@@ -238,7 +238,8 @@ size_t DataSet::getInMemDataSize() const
throw DataSetIException(func, "H5Dget_type failed");
}
- // Get the data type's size
+ // Get the data type's size by first getting its native type then getting
+ // the native type's size.
hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT);
if (native_type < 0)
{
@@ -250,8 +251,19 @@ size_t DataSet::getInMemDataSize() const
throw DataSetIException(func, "H5Tget_size failed");
}
- // Get number of elements of the dataset
- hid_t space_id = H5Dget_space(id); // first get its data space
+ // Close the native type and the datatype of this dataset.
+ if (H5Tclose(native_type) < 0)
+ {
+ throw DataSetIException(func, "H5Tclose(native_type) failed");
+ }
+ if (H5Tclose(mem_type_id) < 0)
+ {
+ throw DataSetIException(func, "H5Tclose(mem_type_id) failed");
+ }
+
+ // Get number of elements of the dataset by first getting its dataspace,
+ // then getting the number of elements in the dataspace
+ hid_t space_id = H5Dget_space(id);
if (space_id < 0)
{
throw DataSetIException(func, "H5Dget_space failed");
@@ -262,6 +274,12 @@ size_t DataSet::getInMemDataSize() const
throw DataSetIException(func, "H5Sget_simple_extent_npoints failed");
}
+ // Close the dataspace
+ if (H5Sclose(space_id) < 0)
+ {
+ throw DataSetIException(func, "H5Sclose failed");
+ }
+
// Calculate and return the size of the data
size_t data_size = type_size * num_elements;
return(data_size);
@@ -411,7 +429,7 @@ void DataSet::read( void* buf, const DataType& mem_type, const DataSpace& mem_sp
//--------------------------------------------------------------------------
// Function: DataSet::read
///\brief This is an overloaded member function, provided for convenience.
-/// It takes a reference to a \c std::string for the buffer.
+/// It takes a reference to a \c H5std_string for the buffer.
///\param buf - IN: Buffer for read data
///\param mem_type - IN: Memory datatype
///\param mem_space - IN: Memory dataspace
@@ -487,7 +505,7 @@ void DataSet::write( const void* buf, const DataType& mem_type, const DataSpace&
//--------------------------------------------------------------------------
// Function: DataSet::write
///\brief This is an overloaded member function, provided for convenience.
-/// It takes a reference to a \c std::string for the buffer.
+/// It takes a reference to a \c H5std_string for the buffer.
// Programmer Binh-Minh Ribler - 2000
// Modification
// Jul 2009
@@ -571,7 +589,7 @@ int DataSet::iterateElems( void* buf, const DataType& type, const DataSpace& spa
/// For more information, please see the Description section in
/// C layer Reference Manual at:
///\par
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5D.html#Dataset-Extend
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5D.html#Dataset-Extend
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataSet::extend( const hsize_t* size ) const
@@ -631,14 +649,14 @@ void DataSet::fillMemBuf(void *buf, DataType& buf_type, DataSpace& space)
// Function: DataSet::getObjType
///\brief Retrieves the type of object that an object reference points to.
///\param ref_type - IN: Type of reference to query, valid values are:
-/// \li \c H5R_OBJECT \tReference is an object reference.
-/// \li \c H5R_DATASET_REGION \tReference is a dataset region reference.
+/// \li \c H5R_OBJECT - Reference is an object reference.
+/// \li \c H5R_DATASET_REGION - Reference is a dataset region reference.
///\param ref - IN: Reference to query
///\return An object type, which can be one of the following:
-/// \li \c H5G_LINK (0) \tObject is a symbolic link.
-/// \li \c H5G_GROUP (1) \tObject is a group.
-/// \li \c H5G_DATASET (2) \tObject is a dataset.
-/// \li \c H5G_TYPE Object (3) \tis a named datatype
+/// \li \c H5G_LINK (0) - Object is a symbolic link.
+/// \li \c H5G_GROUP (1) - Object is a group.
+/// \li \c H5G_DATASET (2) - Object is a dataset.
+/// \li \c H5G_TYPE (3) - Object is a named datatype
///\exception H5::DataSetIException
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
@@ -656,9 +674,9 @@ H5G_obj_t DataSet::getObjType(void *ref, H5R_type_t ref_type) const
//--------------------------------------------------------------------------
// Function: DataSet::getRegion
///\brief Retrieves a dataspace with the region pointed to selected.
+///\param ref - IN: Reference to get region of
///\param ref_type - IN: Type of reference to get region of - default
/// to H5R_DATASET_REGION
-///\param ref - IN: Reference to get region of
///\return DataSpace instance
///\exception H5::DataSetIException
// Programmer Binh-Minh Ribler - May, 2004
@@ -676,7 +694,7 @@ DataSpace DataSet::getRegion(void *ref, H5R_type_t ref_type) const
//--------------------------------------------------------------------------
// Function: DataSet::getId
-// Purpose: Get the id of this attribute
+///\brief Get the id of this dataset.
// Description:
// Class hierarchy is revised to address bugzilla 1068. Class
// AbstractDs and Attribute are moved out of H5Object. In
@@ -758,7 +776,7 @@ void DataSet::p_read_variable_len(const hid_t mem_type_id, const hid_t mem_space
//--------------------------------------------------------------------------
// Function: DataSet::p_setId (private)
-///\brief Sets the identifier of this object to a new value.
+///\brief Sets the identifier of this dataset to a new value.
///
///\exception H5::IdComponentException when the attempt to close the HDF5
/// object fails
diff --git a/c++/src/H5DataSpace.cpp b/c++/src/H5DataSpace.cpp
index 2c6fd37..755ca5b 100644
--- a/c++/src/H5DataSpace.cpp
+++ b/c++/src/H5DataSpace.cpp
@@ -408,7 +408,7 @@ hssize_t DataSpace::getSelectElemNpoints () const
///\par Description
/// For more information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5S.html#Dataspace-SelectElemPointList
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5S.html#Dataspace-SelectElemPointList
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataSpace::getSelectElemPointlist ( hsize_t startpoint, hsize_t numpoints, hsize_t *buf ) const
@@ -432,7 +432,7 @@ void DataSpace::getSelectElemPointlist ( hsize_t startpoint, hsize_t numpoints,
///\par Description
/// For more information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5S.html#Dataspace-SelectBounds
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5S.html#Dataspace-SelectBounds
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataSpace::getSelectBounds ( hsize_t* start, hsize_t* end ) const
@@ -458,7 +458,7 @@ void DataSpace::getSelectBounds ( hsize_t* start, hsize_t* end ) const
///\par Description
/// For more information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5S.html#Dataspace-SelectElements
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5S.html#Dataspace-SelectElements
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataSpace::selectElements ( H5S_seloper_t op, const size_t num_elements, const hsize_t *coord) const
@@ -540,7 +540,7 @@ bool DataSpace::selectValid () const
///\par Description
/// For more information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5S.html#Dataspace-SelectHyperslab
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5S.html#Dataspace-SelectHyperslab
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataSpace::selectHyperslab( H5S_seloper_t op, const hsize_t *count, const hsize_t *start, const hsize_t *stride, const hsize_t *block ) const
diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp
index e13b330..3edb163 100644
--- a/c++/src/H5DataType.cpp
+++ b/c++/src/H5DataType.cpp
@@ -52,16 +52,14 @@ namespace H5 {
// Function: DataType overloaded constructor
///\brief Creates a datatype using an existing datatype's id
///\param existing_id - IN: Id of the existing datatype
-///\param predefined - IN: Indicates whether or not this datatype is
-/// a predefined datatype; default to \c false
// Description
// Constructor creates a copy of an existing DataType using
-// its id. The argument "predefined" is default to false;
-// when a default datatype is created, this argument is set
-// to true so H5Tclose will not be called on it later. - need
-// a reassessment after changing to the new ref counting mech.
-// - BMR 5/2004
+// its id.
// Programmer Binh-Minh Ribler - 2000
+// Modification
+// Dec, 2005
+// Removed second argument, "predefined", after changing to the
+// new ref counting mechanism that relies on C's ref counting.
//--------------------------------------------------------------------------
DataType::DataType(const hid_t existing_id) : H5Object()
{
@@ -210,7 +208,7 @@ void DataType::copy( const DataType& like_type )
///\param dset - IN: Dataset
///\exception H5::DataTypeIException
// Programmer Binh-Minh Ribler - Jan, 2007
-///\parDescription
+///\par Description
/// The resulted dataset will be transient and modifiable.
//--------------------------------------------------------------------------
void DataType::copy(const DataSet& dset)
@@ -517,7 +515,7 @@ DataType DataType::getSuper() const
///\exception H5::DataTypeIException
///\par Description
/// For more information, please see:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5T.html#Datatype-Register
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-Register
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DataType::registerFunc( H5T_pers_t pers, const char* name, const DataType& dest, H5T_conv_t func ) const
@@ -794,17 +792,33 @@ void DataType::close()
// Programmer Binh-Minh Ribler - 2000
// Modification
// - Replaced resetIdComponent() with decRefCount() to use C
-// library ID reference counting mechanism - BMR, Jun 1, 2004
+// library ID reference counting mechanism - BMR, Jun 1, 2004
// - Replaced decRefCount with close() to let the C library
-// handle the reference counting - BMR, Jun 1, 2006
+// handle the reference counting - BMR, Jun 1, 2006
+// - Added the use of H5CPP_EXITED to terminate the HDF5 library
+// and elimiate previous memory leaks. See comments in the
+// header file "H5PredType.h" for details. - BMR, Mar 30, 2012
//--------------------------------------------------------------------------
DataType::~DataType()
{
- try {
- close();
- } catch (Exception close_error) {
- cerr << inMemFunc("~DataType - ") << close_error.getDetailMsg() << endl;
+ try
+ {
+ /* If this is the object AtExit, terminate the HDF5 library. This is
+ to eliminate memory leaks due to the library being re-initiated
+ (after the program has ended) and not re-terminated. */
+ if (id == H5CPP_EXITED)
+ {
+ herr_t ret_value = H5close();
+ if (ret_value == FAIL)
+ throw DataTypeIException(inMemFunc("~DataType - "), "H5close failed");
}
+ // Close the HDF5 datatype
+ else
+ close();
+ }
+ catch (Exception close_error) {
+ cerr << inMemFunc("~DataType - ") << close_error.getDetailMsg() << endl;
+ }
}
#ifndef H5_NO_NAMESPACE
} // end namespace
diff --git a/c++/src/H5DcreatProp.cpp b/c++/src/H5DcreatProp.cpp
index 981085d..ece435c 100644
--- a/c++/src/H5DcreatProp.cpp
+++ b/c++/src/H5DcreatProp.cpp
@@ -106,8 +106,8 @@ int DSetCreatPropList::getChunk( int max_ndims, hsize_t* dim ) const
///\param layout - IN: Type of storage layout for raw data
///\exception H5::PropListIException
///\par Description
-/// For information on setting layout type, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetLayout
+/// For information on valid layout types, please refer to
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetLayout
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DSetCreatPropList::setLayout(H5D_layout_t layout) const
@@ -211,7 +211,7 @@ void DSetCreatPropList::setSzip(unsigned int options_mask, unsigned int pixels_p
///\par
/// For information on setting fill value, please refer to the
/// C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFillValue
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetFillValue
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DSetCreatPropList::setFillValue( const DataType& fvalue_type, const void* value ) const
@@ -459,7 +459,7 @@ bool DSetCreatPropList::allFiltersAvail()
///\par Description
/// Please refer to the Reference Manual of \c H5Pset_shuffle for
/// details.
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetShuffle
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetShuffle
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void DSetCreatPropList::setShuffle() const
diff --git a/c++/src/H5DxferProp.cpp b/c++/src/H5DxferProp.cpp
index 0f7faa2..0785735 100644
--- a/c++/src/H5DxferProp.cpp
+++ b/c++/src/H5DxferProp.cpp
@@ -309,7 +309,7 @@ void DSetMemXferPropList::getMulti(hid_t *memb_dxpl)
///\exception H5::PropListIException
///\par Description
/// For detail, please refer to the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetSmallData
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSmallData
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void DSetMemXferPropList::setSmallDataBlockSize(hsize_t size)
@@ -349,7 +349,7 @@ hsize_t DSetMemXferPropList::getSmallDataBlockSize()
///\par Description
/// For information, please refer to the C layer Reference
/// Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetHyperVectorSize
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetHyperVectorSize
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void DSetMemXferPropList::setHyperVectorSize(size_t vector_size)
diff --git a/c++/src/H5FaccProp.cpp b/c++/src/H5FaccProp.cpp
index f2ab0f3..4fb3836 100644
--- a/c++/src/H5FaccProp.cpp
+++ b/c++/src/H5FaccProp.cpp
@@ -76,7 +76,7 @@ void FileAccPropList::setStdio() const
/// driver was set for the property list. The driver ID is
/// only valid as long as the file driver remains registered.
/// Valid driver identifiers can be found at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-GetDriver
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-GetDriver
///\exception H5::PropListIException
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
@@ -99,7 +99,7 @@ hid_t FileAccPropList::getDriver() const
///\par Description
/// For a list of valid driver identifiers, please see the C
/// layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-GetDriver
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetDriver
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setDriver(hid_t new_driver_id, const void *new_driver_info) const
@@ -157,7 +157,7 @@ hsize_t FileAccPropList::getFamilyOffset() const
///\par Description
/// For more details on the use of \c H5FD_CORE driver, please
/// refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplCore
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetFaplCore
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setCore (size_t increment, hbool_t backing_store) const
@@ -261,7 +261,7 @@ FileAccPropList FileAccPropList::getFamily(hsize_t& memb_size) const
///\exception H5::PropListIException
///\par Description
/// Temporary - For information, please refer to:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplSplit
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetFaplSplit
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setSplit( FileAccPropList& meta_plist, FileAccPropList& raw_plist, const char* meta_ext, const char* raw_ext ) const
@@ -292,47 +292,9 @@ void FileAccPropList::setSplit( FileAccPropList& meta_plist, FileAccPropList& ra
setSplit( meta_plist, raw_plist, meta_ext.c_str(), raw_ext.c_str() );
}
-#ifdef H5_HAVE_STREAM // for Stream Virtual File Driver
-//--------------------------------------------------------------------------
-// Function: FileAccPropList::getStream
-///\brief Retrieves the streaming I/O driver settings
-///\return The streaming I/O file access property list structure
-/// For detail on this structure, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplStream
-///\exception H5::PropListIException
-// Programmer: Binh-Minh Ribler - April, 2004
-//--------------------------------------------------------------------------
-H5FD_stream_fapl_t FileAccPropList::getStream() const
-{
- H5FD_stream_fapl_t fapl;
- herr_t ret_value = H5Pget_fapl_stream(id, &fapl);
- if( ret_value < 0 )
- {
- throw PropListIException("FileAccPropList::getStream", "H5Pget_fapl_stream failed");
- }
- return(fapl);
-}
-
-//--------------------------------------------------------------------------
-// Function: FileAccPropList::setStream
-///\brief Modifies this file access property list to use the Stream
-/// driver.
-///\param fapl - IN: The streaming I/O file access property list
-///\exception H5::PropListIException
-///\par Description
-/// For detail on \a fapl, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplStream
-// Programmer: Binh-Minh Ribler - April, 2004
-//--------------------------------------------------------------------------
-void FileAccPropList::setStream(H5FD_stream_fapl_t &fapl) const
-{
- herr_t ret_value = H5Pset_fapl_stream (id, &fapl);
- if( ret_value < 0 )
- {
- throw PropListIException("FileAccPropList::setStream", "H5Pset_fapl_stream failed");
- }
-}
-#endif // Stream Virtual File Driver
+// Stream Virtual File Driver had been removed from the main library.
+// FileAccPropList::[s,g]etStream are now removed from the C++ API.
+// -BMR, March, 2012
//--------------------------------------------------------------------------
// Function: FileAccPropList::getSieveBufSize
@@ -360,7 +322,7 @@ size_t FileAccPropList::getSieveBufSize() const
///\exception H5::PropListIException
///\par Description
/// For detail on data sieving, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetSieveBufSize
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSieveBufSize
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setSieveBufSize(size_t bufsize) const
@@ -380,7 +342,7 @@ void FileAccPropList::setSieveBufSize(size_t bufsize) const
///\exception H5::PropListIException
///\par Description
/// For more detail, please see the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetMetaBlockSize
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetMetaBlockSize
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setMetaBlockSize(hsize_t &block_size) const
@@ -420,7 +382,7 @@ hsize_t FileAccPropList::getMetaBlockSize() const
///\exception H5::PropListIException
///\par Description
/// For detail on \a flags, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplStream
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetFaplLog
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setLog(const char *logfile, unsigned flags, size_t buf_size) const
@@ -477,7 +439,7 @@ void FileAccPropList::setSec2() const
/// The parameter \a alignment must have a positive value.
///
/// For detail on \a setting alignment, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetAlignment
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetAlignment
// Programmer: Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileAccPropList::setAlignment( hsize_t threshold, hsize_t alignment ) const
@@ -514,7 +476,7 @@ void FileAccPropList::getAlignment( hsize_t &threshold, hsize_t &alignment ) con
///\exception H5::PropListIException
///\par Description
/// More details and valid values for \a dtype can be found at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetMultiType
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetMultiType
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void FileAccPropList::setMultiType(H5FD_mem_t dtype) const
@@ -533,7 +495,7 @@ void FileAccPropList::setMultiType(H5FD_mem_t dtype) const
///\exception H5::PropListIException
///\par Description
/// More details and possible returned values can be found at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-GetMultiType
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-GetMultiType
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
H5FD_mem_t FileAccPropList::getMultiType() const
@@ -634,7 +596,7 @@ H5F_close_degree_t FileAccPropList::getFcloseDegree()
///\exception H5::PropListIException
///\par Description
/// For detail on \a fapl, please refer to
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetFaplStream
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetGCReferences
// Programmer: Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileAccPropList::setGcReferences( unsigned gc_ref ) const
diff --git a/c++/src/H5FcreatProp.cpp b/c++/src/H5FcreatProp.cpp
index 53d18f6..8d9965e 100644
--- a/c++/src/H5FcreatProp.cpp
+++ b/c++/src/H5FcreatProp.cpp
@@ -128,7 +128,7 @@ hsize_t FileCreatPropList::getUserblock() const
///\par Description
/// For information on setting sizes, please refer to the
/// C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetSizes
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSizes
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileCreatPropList::setSizes( size_t sizeof_addr, size_t sizeof_size ) const
@@ -168,7 +168,7 @@ void FileCreatPropList::getSizes( size_t& sizeof_addr, size_t& sizeof_size ) con
///\exception H5::PropListIException
///\par Description
/// For information, please see the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetSymK
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSymK
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileCreatPropList::setSymk( unsigned ik, unsigned lk ) const
@@ -189,7 +189,7 @@ void FileCreatPropList::setSymk( unsigned ik, unsigned lk ) const
///\exception H5::PropListIException
///\par Description
/// For information, please see
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetSymK
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-GetSymK
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileCreatPropList::getSymk( unsigned& ik, unsigned& lk ) const
@@ -210,7 +210,7 @@ void FileCreatPropList::getSymk( unsigned& ik, unsigned& lk ) const
///\exception H5::PropListIException
///\par Description
/// For information, please see the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetIstoreK
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetIstoreK
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void FileCreatPropList::setIstorek( unsigned ik ) const
@@ -230,7 +230,7 @@ void FileCreatPropList::setIstorek( unsigned ik ) const
///\exception H5::PropListIException
///\par Description
/// For information, please see
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5P.html#Property-SetIstoreK
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-GetIstoreK
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
unsigned FileCreatPropList::getIstorek() const
diff --git a/c++/src/H5File.cpp b/c++/src/H5File.cpp
index a773489..da0241f 100644
--- a/c++/src/H5File.cpp
+++ b/c++/src/H5File.cpp
@@ -76,7 +76,7 @@ H5File::H5File() : IdComponent(), id(0) {}
/// For info on file creation in the case of an already-open file,
/// please refer to the \b Special \b case section in the C layer
/// Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5F.html#File-Create
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5F.html#File-Create
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : IdComponent(0)
@@ -88,7 +88,7 @@ H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& c
// Function: H5File overloaded constructor
///\brief This is another overloaded constructor. It differs from the
/// above constructor only in the type of the \a name argument.
-///\param name - IN: Name of the file - \c std::string
+///\param name - IN: Name of the file - \c H5std_string
///\param flags - IN: File access flags
///\param create_plist - IN: File creation property list, used when
/// modifying default file meta-data. Default to
@@ -191,8 +191,8 @@ bool H5File::isHdf5(const char* name)
//--------------------------------------------------------------------------
// Function: H5File::isHdf5
///\brief This is an overloaded member function, provided for convenience.
-/// It takes an \c std::string for \a name.
-///\param name - IN: Name of the file - \c std::string
+/// It takes an \c H5std_string for \a name.
+///\param name - IN: Name of the file - \c H5std_string
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
bool H5File::isHdf5(const H5std_string& name )
@@ -231,8 +231,8 @@ void H5File::openFile(const char* name, unsigned int flags, const FileAccPropLis
//--------------------------------------------------------------------------
// Function: H5File::openFile
///\brief This is an overloaded member function, provided for convenience.
-/// It takes an \c std::string for \a name.
-///\param name - IN: Name of the file - \c std::string
+/// It takes an \c H5std_string for \a name.
+///\param name - IN: Name of the file - \c H5std_string
///\param flags - IN: File access flags
///\param access_plist - IN: File access property list. Default to
/// FileAccPropList::DEFAULT
@@ -512,8 +512,8 @@ H5std_string H5File::getFileName() const
///\brief Retrieves the type of object that an object reference points to.
///\param ref - IN: Reference to query
///\param ref_type - IN: Type of reference, valid values are:
-/// \li \c H5R_OBJECT \tReference is an object reference.
-/// \li \c H5R_DATASET_REGION \tReference is a dataset region reference.
+/// \li \c H5R_OBJECT - Reference is an object reference
+/// \li \c H5R_DATASET_REGION - Reference is a dataset region reference
///\return Object type, which can be one of the following:
/// \li \c H5G_LINK - Object is a symbolic link.
/// \li \c H5G_GROUP - Object is a group.
@@ -600,9 +600,9 @@ void H5File::p_reference(void* ref, const char* name, hid_t space_id, H5R_type_t
///\param name - IN: Name of the object to be referenced
///\param dataspace - IN: Dataspace with selection
///\param ref_type - IN: Type of reference to query, valid values are:
-/// \li \c H5R_OBJECT \tReference is an object reference.
-/// \li \c H5R_DATASET_REGION \tReference is a dataset region
-/// reference. - this is the default
+/// \li \c H5R_OBJECT - Reference is an object reference
+/// \li \c H5R_DATASET_REGION - Reference is a dataset region
+/// reference - this is the default
///\exception H5::IdComponentException
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
@@ -643,9 +643,9 @@ void H5File::reference(void* ref, const char* name) const
// Function: H5File::reference
///\brief This is an overloaded function, provided for your convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for the object's name.
+/// \c H5std_string for the object's name.
///\param ref - IN: Reference pointer
-///\param name - IN: Name of the object to be referenced - \c std::string
+///\param name - IN: Name of the object to be referenced - \c H5std_string
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
void H5File::reference(void* ref, const H5std_string& name) const
diff --git a/c++/src/H5Group.cpp b/c++/src/H5Group.cpp
index afcc7eb..6ec2dbb 100644
--- a/c++/src/H5Group.cpp
+++ b/c++/src/H5Group.cpp
@@ -79,7 +79,7 @@ hid_t Group::getLocId() const
//--------------------------------------------------------------------------
// Function: Group overloaded constructor
///\brief Creates a Group object using the id of an existing group.
-///\param group_id - IN: Id of an existing group
+///\param existing_id - IN: Id of an existing group
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
Group::Group(const hid_t existing_id) : H5Object()
@@ -153,13 +153,13 @@ Group::Group(Attribute& attr, const void* ref, H5R_type_t ref_type) : H5Object()
///\brief Retrieves the type of object that an object reference points to.
///\param ref - IN: Reference to query
///\param ref_type - IN: Type of reference to query, valid values are:
-/// \li \c H5R_OBJECT \tReference is an object reference.
-/// \li \c H5R_DATASET_REGION \tReference is a dataset region reference.
+/// \li \c H5R_OBJECT - Reference is an object reference.
+/// \li \c H5R_DATASET_REGION - Reference is a dataset region reference.
///\return An object type, which can be one of the following:
-/// H5G_LINK Object is a symbolic link.
-/// H5G_GROUP Object is a group.
-/// H5G_DATASET Object is a dataset.
-/// H5G_TYPE Object is a named datatype
+/// \li \c H5G_LINK (0) - Object is a symbolic link.
+/// \li \c H5G_GROUP (1) - Object is a group.
+/// \li \c H5G_DATASET (2) - Object is a dataset.
+/// \li \c H5G_TYPE (3) - Object is a named datatype
///\exception H5::GroupIException
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
@@ -199,10 +199,10 @@ DataSpace Group::getRegion(void *ref, H5R_type_t ref_type) const
// Purpose: Get the id of this attribute
// Modification:
// May 2008 - BMR
-// Class hierarchy is revised to address bugzilla 1068. Class
-// AbstractDS and Attribute are moved out of H5Object. In
-// addition, member IdComponent::id is moved into subclasses, and
-// IdComponent::getId now becomes pure virtual function.
+// Class hierarchy is revised to address bugzilla 1068. Class
+// AbstractDS and Attribute are moved out of H5Object. In
+// addition, member IdComponent::id is moved into subclasses, and
+// IdComponent::getId now becomes pure virtual function.
// Programmer Binh-Minh Ribler - May, 2008
//--------------------------------------------------------------------------
hid_t Group::getId() const
@@ -215,11 +215,11 @@ hid_t Group::getId() const
///\brief Sets the identifier of this object to a new value.
///
///\exception H5::IdComponentException when the attempt to close the HDF5
-/// object fails
+/// object fails
// Description:
-// The underlaying reference counting in the C library ensures
-// that the current valid id of this object is properly closed.
-// Then the object's id is reset to the new id.
+// The underlaying reference counting in the C library ensures
+// that the current valid id of this object is properly closed.
+// Then the object's id is reset to the new id.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void Group::p_setId(const hid_t new_id)
diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp
index 1cac0c1..9f96277 100644
--- a/c++/src/H5IdComponent.cpp
+++ b/c++/src/H5IdComponent.cpp
@@ -13,11 +13,13 @@
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#ifdef H5_VMS
+#ifdef OLD_HEADER_FILENAME
+#include <iostream.h>
+#else
#include <iostream>
-#endif /*H5_VMS*/
-
+#endif
#include <string>
+
#include "H5Include.h"
#include "H5Exception.h"
#include "H5Library.h"
@@ -129,7 +131,7 @@ int IdComponent::getCounter() const
//--------------------------------------------------------------------------
// Function: hdfObjectType
///\brief Given an id, returns the type of the object.
-///return a valid HDF object type, which may be one of the following:
+///\return a valid HDF object type, which may be one of the following:
/// \li \c H5I_FILE
/// \li \c H5I_GROUP
/// \li \c H5I_DATATYPE
diff --git a/c++/src/H5Library.cpp b/c++/src/H5Library.cpp
index e7557b3..ecc5141 100644
--- a/c++/src/H5Library.cpp
+++ b/c++/src/H5Library.cpp
@@ -106,7 +106,7 @@ void H5Library::getLibVersion( unsigned& majnum, unsigned& minnum, unsigned& rel
///\par Description
/// For information about library version, please refer to
/// the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5.html#Library-VersCheck
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5.html#Library-VersCheck
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void H5Library::checkVersion(unsigned majnum, unsigned minnum, unsigned relnum)
@@ -161,7 +161,7 @@ void H5Library::garbageCollect()
/// Setting a value of -1 for a limit means no limit of that type.
/// For more information on free list limits, please refer to C
/// layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5.html#Library-SetFreeListLimits
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5.html#Library-SetFreeListLimits
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
void H5Library::setFreeListLimits(int reg_global_lim, int reg_list_lim,
diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp
index e25c255..3c85502 100644
--- a/c++/src/H5Object.cpp
+++ b/c++/src/H5Object.cpp
@@ -124,7 +124,7 @@ Attribute H5Object::createAttribute( const char* name, const DataType& data_type
// Function: H5Object::createAttribute
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes
-/// a reference to an \c std::string for \a name.
+/// a reference to an \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
Attribute H5Object::createAttribute( const H5std_string& name, const DataType& data_type, const DataSpace& data_space, const PropList& create_plist ) const
@@ -158,7 +158,7 @@ Attribute H5Object::openAttribute( const char* name ) const
// Function: H5Object::openAttribute
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes
-/// a reference to an \c std::string for \a name.
+/// a reference to an \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
Attribute H5Object::openAttribute( const H5std_string& name ) const
@@ -194,15 +194,17 @@ Attribute H5Object::openAttribute( const unsigned int idx ) const
///\brief Iterates a user's function over all the attributes of an H5
/// object, which may be a group, dataset or named datatype.
///\param user_op - IN: User's function to operate on each attribute
-///\param idx - IN/OUT: Starting (IN) and ending (OUT) attribute indices
+///\param _idx - IN/OUT: Starting (IN) and ending (OUT) attribute indices
///\param op_data - IN: User's data to pass to user's operator function
///\return Returned value of the last operator if it was non-zero, or
/// zero if all attributes were processed
///\exception H5::AttributeIException
///\par Description
+/// The signature of user_op is
+/// void (*)(H5::H5Object&, H5std_string, void*).
/// For information, please refer to the C layer Reference Manual
/// at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5A.html#Annot-Iterate
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5A.html#Annot-Iterate
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
int H5Object::iterateAttrs( attr_operator_t user_op, unsigned *_idx, void *op_data )
@@ -267,7 +269,7 @@ void H5Object::removeAttr( const char* name ) const
// Function: H5Object::removeAttr
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes
-/// a reference to an \c std::string for \a name.
+/// a reference to an \c H5std_string for \a name.
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void H5Object::removeAttr( const H5std_string& name ) const
@@ -294,7 +296,7 @@ void H5Object::renameAttr(const char* oldname, const char* newname) const
// Function: H5Object::renameAttr
///\brief This is an overloaded member function, provided for convenience.
/// It differs from the above function in that it takes
-/// a reference to an \c std::string for the names.
+/// a reference to an \c H5std_string for the names.
// Programmer Binh-Minh Ribler - Mar, 2005
//--------------------------------------------------------------------------
void H5Object::renameAttr(const H5std_string& oldname, const H5std_string& newname) const
@@ -366,9 +368,9 @@ void H5Object::p_reference(void* ref, const char* name, hid_t space_id, H5R_type
///\param name - IN: Name of the object to be referenced
///\param dataspace - IN: Dataspace with selection
///\param ref_type - IN: Type of reference to query, valid values are:
-/// \li \c H5R_OBJECT \tReference is an object reference.
-/// \li \c H5R_DATASET_REGION \tReference is a dataset region
-/// reference. - this is the default
+/// \li \c H5R_OBJECT - Reference is an object reference.
+/// \li \c H5R_DATASET_REGION - Reference is a dataset region
+/// reference. - this is the default
///\exception H5::IdComponentException
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
@@ -410,9 +412,9 @@ void H5Object::reference(void* ref, const char* name) const
// Function: H5Object::reference
///\brief This is an overloaded function, provided for your convenience.
/// It differs from the above function in that it takes an
-/// \c std::string for the object's name.
+/// \c H5std_string for the object's name.
///\param ref - IN: Reference pointer
-///\param name - IN: Name of the object to be referenced - \c std::string
+///\param name - IN: Name of the object to be referenced - \c H5std_string
// Programmer Binh-Minh Ribler - May, 2004
//--------------------------------------------------------------------------
void H5Object::reference(void* ref, const H5std_string& name) const
diff --git a/c++/src/H5PredType.cpp b/c++/src/H5PredType.cpp
index 347f02f..9dfc760 100644
--- a/c++/src/H5PredType.cpp
+++ b/c++/src/H5PredType.cpp
@@ -44,7 +44,10 @@ namespace H5 {
//--------------------------------------------------------------------------
PredType::PredType( const hid_t predtype_id ) : AtomType( predtype_id )
{
- id = H5Tcopy(predtype_id);
+ if (predtype_id == H5CPP_EXITED)
+ id = predtype_id;
+ else
+ id = H5Tcopy(predtype_id);
}
//--------------------------------------------------------------------------
@@ -62,7 +65,8 @@ PredType::PredType() : AtomType() {}
//--------------------------------------------------------------------------
PredType::PredType( const PredType& original ) : AtomType( original ) {}
-const PredType PredType::NotAtexit; // only for atexit/global dest. problem
+// Flag to terminate HDF5 library in DataType::~DataType
+const PredType PredType::AtExit(H5CPP_EXITED);
// Definition of pre-defined types
const PredType PredType::C_S1( H5T_C_S1 );
diff --git a/c++/src/H5PredType.h b/c++/src/H5PredType.h
index 69abfcb..9cb1c65 100644
--- a/c++/src/H5PredType.h
+++ b/c++/src/H5PredType.h
@@ -26,9 +26,17 @@
namespace H5 {
#endif
+/* This constant is defined for a workaround to eliminate memory leaks due to
+ the library being re-initiated when PredType destructors are invoked. A
+ PredType instant with H5CPP_EXITED as the value of its "id" is constructed
+ before the other PredType objects are created. At exit, when this special
+ PredType object is to be destructed, no HDF5 library function will be called
+ and the library will be terminated. -BMR, Mar 30, 2012 */
+#define H5CPP_EXITED -3 // -3 is less likely to be used elsewhere
+
class H5_DLLCPP PredType : public AtomType {
public:
- // Returns this class name
+ ///\brief Returns this class name
virtual H5std_string fromClass () const { return("PredType"); }
// Makes a copy of the predefined type and stores the new
@@ -229,9 +237,10 @@ class H5_DLLCPP PredType : public AtomType {
#endif // DOXYGEN_SHOULD_SKIP_THIS
private:
- // added this to work around the atexit/global destructor problem
- // temporarily - it'll prevent the use of atexit to clean up
- static const PredType NotAtexit; // not working yet
+ // Added this to work around the atexit/global destructor problem.
+ // It'll help to terminate the library after other PredType instances
+ // are closed. -BMR, Mar 30, 2012
+ static const PredType AtExit;
protected:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp
index 550c90d..ceea15f 100644
--- a/c++/src/H5PropList.cpp
+++ b/c++/src/H5PropList.cpp
@@ -570,7 +570,7 @@ void PropList::setProperty(const H5std_string& name, void* value) const
/// It differs from the above function only in what arguments it
/// accepts.
///\param name - IN: Name of property to set - \c H5std_string
-///\param strg - IN: Value for the property is a \c std::string
+///\param strg - IN: Value for the property is a \c H5std_string
// Programmer: Binh-Minh Ribler - April, 2004
//--------------------------------------------------------------------------
void PropList::setProperty(const H5std_string& name, H5std_string& strg) const
diff --git a/c++/src/H5StrType.cpp b/c++/src/H5StrType.cpp
index e632c4d..a906b72 100644
--- a/c++/src/H5StrType.cpp
+++ b/c++/src/H5StrType.cpp
@@ -87,7 +87,7 @@ StrType::StrType( const PredType& pred_type, const size_t& size ) : AtomType()
// Function: StrType overloaded constructor
///\brief Creates a string datatype with a specified length
///\param dummy - IN: To simplify calling the previous constructor
-// and avoid prototype clash with another constructor
+/// and avoid prototype clash with another constructor
///\param size - IN: Length of the new string type
///\exception H5::DataTypeIException
///\par Description
@@ -209,7 +209,7 @@ H5T_str_t StrType::getStrpad() const
///\exception H5::DataTypeIException
///\par Description
/// For detail, please refer to the C layer Reference Manual at:
-/// http://hdf.ncsa.uiuc.edu/HDF5/doc/RM_H5T.html#Datatype-SetStrpad
+/// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5T.html#Datatype-SetStrpad
// Programmer Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void StrType::setStrpad( H5T_str_t strpad ) const
diff --git a/c++/src/Makefile.in b/c++/src/Makefile.in
index 159bbf6..395c76c 100644
--- a/c++/src/Makefile.in
+++ b/c++/src/Makefile.in
@@ -431,7 +431,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
# Include src directory
diff --git a/c++/src/h5c++.in b/c++/src/h5c++.in
index 39d3d2a..20435eb 100755..100644
--- a/c++/src/h5c++.in
+++ b/c++/src/h5c++.in
@@ -208,7 +208,7 @@ for arg in $@ ; do
get_output_file="yes"
fi
;;
- -E|-M)
+ -E|-M|-MT)
allargs="$allargs $arg"
compile_args="$compile_args $arg"
dash_c="yes"
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index ee1a206..26abace 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -268,6 +268,77 @@ test_simple_io( H5File& file)
} // test_simple_io
/*-------------------------------------------------------------------------
+ * Function: test_datasize
+ *
+ * Purpose: Tests DataSet::getInMemDataSize().
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler
+ * Thursday, March 22, 2012
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_datasize()
+{
+
+ SUBTEST("DataSet::getInMemDataSize()");
+
+ int points[100][200];
+ int check[100][200];
+ int i, j, n;
+
+ try
+ {
+ // Open FILE1.
+ H5File file(FILE1, H5F_ACC_RDWR, FileCreatPropList::DEFAULT, FileAccPropList::DEFAULT);
+
+ // Open dataset DSET_SIMPLE_IO_NAME.
+ DataSet dset = file.openDataSet (DSET_SIMPLE_IO_NAME);
+
+ // Get the dataset's dataspace to calculate the size for verification.
+ DataSpace space(dset.getSpace());
+
+ // Get the dimension sizes.
+ hsize_t dims[2];
+ int n_dims = space.getSimpleExtentDims(dims);
+
+ // Calculate the supposed size. Size of each value is int (4), from
+ // test_simple_io.
+ int expected_size = 4 * dims[0] * dims[1];
+
+ // getInMemDataSize() returns the in memory size of the data.
+ size_t ds_size = dset.getInMemDataSize();
+
+ // Verify the data size.
+ if (ds_size != expected_size)
+ {
+ H5_FAILED();
+ cerr << " Expected data size = " << expected_size;
+ cerr << " but dset.getInMemDataSize() returned " << ds_size << endl;
+ throw Exception("test_compression", "Failed in testing DataSet::getInMemDataSize()");
+ }
+
+ PASSED();
+ return 0;
+ } // end try
+
+ // catch all dataset, space, plist exceptions
+ catch (Exception E)
+ {
+ cerr << " FAILED" << endl;
+ cerr << " <<< " << E.getDetailMsg() << " >>>" << endl << endl;
+
+ return -1;
+ }
+} // test_datasize
+
+/*-------------------------------------------------------------------------
* Function: test_tconv
*
* Purpose: Test some simple data type conversion stuff.
@@ -1004,6 +1075,10 @@ void test_dset()
nerrors += test_compression(file)<0 ?1:0;
nerrors += test_multiopen (file)<0 ?1:0;
nerrors += test_types(file)<0 ?1:0;
+
+ // Close the file before testing data size.
+ file.close();
+ nerrors += test_datasize() <0 ? 1:0;
}
catch (Exception E)
{
diff --git a/config/COPYING b/config/COPYING
index 6903daf..6903daf 100755..100644
--- a/config/COPYING
+++ b/config/COPYING
diff --git a/config/Makefile.am.blank b/config/Makefile.am.blank
index a091c60..a091c60 100755..100644
--- a/config/Makefile.am.blank
+++ b/config/Makefile.am.blank
diff --git a/config/cmake/CTestCustom.cmake b/config/cmake/CTestCustom.cmake
index 43ef451..e708a00 100755
--- a/config/cmake/CTestCustom.cmake
+++ b/config/cmake/CTestCustom.cmake
@@ -5,9 +5,10 @@ SET (CTEST_CUSTOM_WARNING_EXCEPTION
"H5detect.c.[0-9]+.[ \t]*:[ \t]*warning C4090:"
"H5detect.c.[0-9]+.[ \t]*:[ \t]*warning:[ \t]*passing argument"
"H5detect.c[0-9 \t:]*warning:[ \t]*passing argument"
+ "H5detect.c[0-9 \t:]*note:[ \t]*expected .void .. but argument is of type .volatile"
+ "include/string.h[0-9 \t:]*note:[ \t]*expected .void .. but argument is of type .volatile"
"note:[ \t]*expected .void .. but argument is of type .volatile"
"H5Tconv.c[0-9 \t:]*warning:[ \t]*comparison is always false due to limited range of data type"
- "testhdf5.h.[0-9]+.[ \t]*:[ \t]*warning C4005"
"H5Ztrans.c.[0-9]+.[ \t]*:[ \t]*warning C4244"
"SZIP.src.*:[ \t]*warning"
"POSIX name for this item is deprecated"
diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake
index 7882f3d..24fa7f7 100644
--- a/config/cmake/ConfigureChecks.cmake
+++ b/config/cmake/ConfigureChecks.cmake
@@ -129,6 +129,10 @@ ENDMACRO (CHECK_LIBRARY_EXISTS_CONCAT)
SET (WINDOWS)
IF (WIN32)
+ IF (MINGW)
+ SET (H5_HAVE_MINGW 1)
+ SET (WINDOWS 1) # MinGW tries to imitate Windows
+ ENDIF (MINGW)
SET (H5_HAVE_WIN32_API 1)
IF (NOT UNIX AND NOT CYGWIN AND NOT MINGW)
SET (WINDOWS 1)
@@ -175,7 +179,9 @@ IF (WINDOWS)
SET (H5_HAVE_DIFFTIME 1)
SET (H5_HAVE_LONGJMP 1)
SET (H5_STDC_HEADERS 1)
- SET (H5_HAVE_GETHOSTNAME 1)
+ IF (NOT MINGW)
+ SET (H5_HAVE_GETHOSTNAME 1)
+ ENDIF (NOT MINGW)
SET (H5_HAVE_GETCONSOLESCREENBUFFERINFO 1)
SET (H5_HAVE_FUNCTION 1)
SET (H5_GETTIMEOFDAY_GIVES_TZ 1)
@@ -296,7 +302,6 @@ ENDIF (H5_HAVE_STDINT_H AND CMAKE_CXX_COMPILER_LOADED)
SET (LINUX_LFS 0)
SET (HDF5_EXTRA_FLAGS)
-#IF (CMAKE_SYSTEM MATCHES "Linux-([3-9]\\.[0-9]|2\\.[4-9])\\.")
IF (NOT WINDOWS)
# Linux Specific flags
SET (HDF5_EXTRA_FLAGS -D_POSIX_SOURCE -D_BSD_SOURCE)
@@ -332,7 +337,6 @@ IF (NOT WINDOWS)
ENDIF (HDF5_ENABLE_LARGE_FILE)
SET (CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${HDF5_EXTRA_FLAGS})
ENDIF (NOT WINDOWS)
-#ENDIF (CMAKE_SYSTEM MATCHES "Linux-([3-9]\\.[0-9]|2\\.[4-9])\\.")
ADD_DEFINITIONS (${HDF5_EXTRA_FLAGS})
@@ -633,7 +637,8 @@ ENDIF (NOT WINDOWS)
#-----------------------------------------------------------------------------
# Check if InitOnceExecuteOnce is available
#-----------------------------------------------------------------------------
-IF (WINDOWS AND NOT HDF5_NO_IOEO_TEST)
+IF (WINDOWS)
+ IF (NOT HDF5_NO_IOEO_TEST)
MESSAGE (STATUS "Checking for InitOnceExecuteOnce:")
IF("${H5_HAVE_IOEO}" MATCHES "^${H5_HAVE_IOEO}$")
IF (LARGEFILE)
@@ -691,7 +696,8 @@ IF (WINDOWS AND NOT HDF5_NO_IOEO_TEST)
"Return value: ${HAVE_IOEO_EXITCODE}\n")
ENDIF("${HAVE_IOEO_EXITCODE}" EQUAL 0)
ENDIF("${H5_HAVE_IOEO}" MATCHES "^${H5_HAVE_IOEO}$")
-ENDIF (WINDOWS AND NOT HDF5_NO_IOEO_TEST)
+ ENDIF (NOT HDF5_NO_IOEO_TEST)
+ENDIF (WINDOWS)
#-----------------------------------------------------------------------------
diff --git a/config/cmake/FindSZIP.cmake b/config/cmake/FindSZIP.cmake
index 6118f7a..b358862 100644
--- a/config/cmake/FindSZIP.cmake
+++ b/config/cmake/FindSZIP.cmake
@@ -44,11 +44,11 @@ MACRO (SZIP_ADJUST_LIB_VARS basename)
# if the generator supports configuration types then set
# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
- SET (${basename}_LIBRARY optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG})
+ SET (${basename}_LIBRARY optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG})
ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
- # if there are no configuration types and CMAKE_BUILD_TYPE has no value
- # then just use the release libraries
- SET (${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
+ # if there are no configuration types and CMAKE_BUILD_TYPE has no value
+ # then just use the release libraries
+ SET (${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
ENDIF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
SET (${basename}_LIBRARIES optimized ${${basename}_LIBRARY_RELEASE} debug ${${basename}_LIBRARY_DEBUG})
ENDIF (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE)
@@ -90,13 +90,13 @@ FIND_PATH (SZIP_INCLUDE_DIR
NO_DEFAULT_PATH
)
-IF (WIN32 AND NOT MINGW)
+IF (WIN32)
SET (SZIP_SEARCH_DEBUG_NAMES "sz_d;libsz_d")
- SET (SZIP_SEARCH_RELEASE_NAMES "sz;libsz")
-ELSE (WIN32 AND NOT MINGW)
+ SET (SZIP_SEARCH_RELEASE_NAMES "sz;libsz;libszip")
+ELSE (WIN32)
SET (SZIP_SEARCH_DEBUG_NAMES "sz_d")
- SET (SZIP_SEARCH_RELEASE_NAMES "sz")
-ENDIF (WIN32 AND NOT MINGW)
+ SET (SZIP_SEARCH_RELEASE_NAMES "sz;szip")
+ENDIF (WIN32)
# Look for the library.
FIND_LIBRARY (SZIP_LIBRARY_DEBUG
diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in
index a5ec410..c368cfb 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -6,6 +6,9 @@
/* Define if the Windows virtual file driver should be compiled */
#cmakedefine H5_HAVE_WINDOWS @H5_HAVE_WINDOWS@
+/* Define if using MinGW */
+#cmakedefine H5_HAVE_MINGW @H5_HAVE_MINGW@
+
/* Define if on the Windows platform and default WIN32 API */
#cmakedefine H5_HAVE_WIN32_API @H5_HAVE_WIN32_API@
diff --git a/config/cmake/HDFLibMacros.cmake b/config/cmake/HDFLibMacros.cmake
index 23c81da..b9c1fbb 100644
--- a/config/cmake/HDFLibMacros.cmake
+++ b/config/cmake/HDFLibMacros.cmake
@@ -37,11 +37,11 @@ MACRO (EXTERNAL_JPEG_LIBRARY compress_type libtype jpeg_pic)
EXTERNALPROJECT_GET_PROPERTY (JPEG BINARY_DIR SOURCE_DIR)
IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (JPEG_LIB_NAME "jpeg_D")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
SET (JPEG_LIB_NAME "jpeg_debug")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${CMAKE_BUILD_TYPE} MATCHES "Debug")
SET (JPEG_LIB_NAME "jpeg")
ENDIF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
@@ -51,12 +51,19 @@ MACRO (EXTERNAL_JPEG_LIBRARY compress_type libtype jpeg_pic)
ADD_DEPENDENCIES (jpeg JPEG)
IF (${libtype} MATCHES "SHARED")
- IF (WIN32 AND NOT MINGW)
- SET_TARGET_PROPERTIES(jpeg PROPERTIES
- IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${JPEG_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
- IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${JPEG_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
- )
- ELSE (WIN32 AND NOT MINGW)
+ IF (WIN32)
+ IF (MINGW)
+ SET_TARGET_PROPERTIES(jpeg PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${JPEG_LIB_NAME}.lib"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${JPEG_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ELSE (MINGW)
+ SET_TARGET_PROPERTIES(jpeg PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${JPEG_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${JPEG_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ENDIF (MINGW)
+ ELSE (WIN32)
IF (CYGWIN)
SET_TARGET_PROPERTIES(jpeg PROPERTIES
IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_IMPORT_LIBRARY_PREFIX}${JPEG_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
@@ -69,7 +76,7 @@ MACRO (EXTERNAL_JPEG_LIBRARY compress_type libtype jpeg_pic)
SOVERSION "${JPEG_VERSION_STRING}"
)
ENDIF (CYGWIN)
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${libtype} MATCHES "SHARED")
IF (WIN32 AND NOT MINGW)
SET_TARGET_PROPERTIES(jpeg PROPERTIES
@@ -144,11 +151,11 @@ MACRO (EXTERNAL_SZIP_LIBRARY compress_type libtype encoding)
EXTERNALPROJECT_GET_PROPERTY (SZIP BINARY_DIR SOURCE_DIR)
IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (SZIP_LIB_NAME "szip_D")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
SET (SZIP_LIB_NAME "szip_debug")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${CMAKE_BUILD_TYPE} MATCHES "Debug")
SET (SZIP_LIB_NAME "szip")
ENDIF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
@@ -158,12 +165,19 @@ MACRO (EXTERNAL_SZIP_LIBRARY compress_type libtype encoding)
ADD_DEPENDENCIES (szip SZIP)
IF (${libtype} MATCHES "SHARED")
- IF (WIN32 AND NOT MINGW)
- SET_TARGET_PROPERTIES(szip PROPERTIES
- IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${SZIP_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
- IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${SZIP_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
- )
- ELSE (WIN32 AND NOT MINGW)
+ IF (WIN32)
+ IF (MINGW)
+ SET_TARGET_PROPERTIES(szip PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SZIP_LIB_NAME}.lib"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SZIP_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ELSE (MINGW)
+ SET_TARGET_PROPERTIES(szip PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${SZIP_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${SZIP_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ENDIF (MINGW)
+ ELSE (WIN32)
IF (CYGWIN)
SET_TARGET_PROPERTIES(szip PROPERTIES
IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_IMPORT_LIBRARY_PREFIX}${SZIP_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
@@ -176,7 +190,7 @@ MACRO (EXTERNAL_SZIP_LIBRARY compress_type libtype encoding)
SOVERSION "${SZIP_VERSION_STRING}"
)
ENDIF (CYGWIN)
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${libtype} MATCHES "SHARED")
IF (WIN32 AND NOT MINGW)
SET_TARGET_PROPERTIES(szip PROPERTIES
@@ -249,17 +263,17 @@ MACRO (EXTERNAL_ZLIB_LIBRARY compress_type libtype)
EXTERNALPROJECT_GET_PROPERTY (ZLIB BINARY_DIR SOURCE_DIR)
IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (ZLIB_LIB_NAME "zlib_D")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
SET (ZLIB_LIB_NAME "z_debug")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${CMAKE_BUILD_TYPE} MATCHES "Debug")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (ZLIB_LIB_NAME "zlib")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
SET (ZLIB_LIB_NAME "z")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ENDIF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
# Create imported target szip
@@ -267,12 +281,19 @@ MACRO (EXTERNAL_ZLIB_LIBRARY compress_type libtype)
ADD_DEPENDENCIES (zlib ZLIB)
IF (${libtype} MATCHES "SHARED")
- IF (WIN32 AND NOT MINGW)
- SET_TARGET_PROPERTIES(zlib PROPERTIES
- IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
- IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
- )
- ELSE (WIN32 AND NOT MINGW)
+ IF (WIN32)
+ IF (MINGW)
+ SET_TARGET_PROPERTIES(zlib PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${ZLIB_LIB_NAME}.lib"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${ZLIB_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ELSE (MINGW)
+ SET_TARGET_PROPERTIES(zlib PROPERTIES
+ IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ IMPORTED_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${BLDTYPE}/${CMAKE_IMPORT_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ )
+ ENDIF (MINGW)
+ ELSE (WIN32)
IF (CYGWIN)
SET_TARGET_PROPERTIES(zlib PROPERTIES
IMPORTED_IMPLIB "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_IMPORT_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
@@ -285,7 +306,7 @@ MACRO (EXTERNAL_ZLIB_LIBRARY compress_type libtype)
SOVERSION "${ZLIB_VERSION_STRING}"
)
ENDIF (CYGWIN)
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${libtype} MATCHES "SHARED")
IF (WIN32 AND NOT MINGW)
SET_TARGET_PROPERTIES(zlib PROPERTIES
diff --git a/config/cmake/HDFMacros.cmake b/config/cmake/HDFMacros.cmake
index 6a1ead7..0d3ab5f 100644
--- a/config/cmake/HDFMacros.cmake
+++ b/config/cmake/HDFMacros.cmake
@@ -35,29 +35,29 @@ ENDMACRO (IDE_SOURCE_PROPERTIES)
#-------------------------------------------------------------------------------
MACRO (TARGET_NAMING target libtype)
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
IF (${libtype} MATCHES "SHARED")
SET_TARGET_PROPERTIES (${target} PROPERTIES OUTPUT_NAME "${target}dll")
ENDIF (${libtype} MATCHES "SHARED")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ENDMACRO (TARGET_NAMING)
#-------------------------------------------------------------------------------
MACRO (HDF_SET_LIB_OPTIONS libtarget libname libtype)
# message (STATUS "${libname} libtype: ${libtype}")
IF (${libtype} MATCHES "SHARED")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (LIB_RELEASE_NAME "${libname}")
SET (LIB_DEBUG_NAME "${libname}_D")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
SET (LIB_RELEASE_NAME "${libname}")
SET (LIB_DEBUG_NAME "${libname}_debug")
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ELSE (${libtype} MATCHES "SHARED")
- IF (WIN32 AND NOT MINGW)
+ IF (WIN32)
SET (LIB_RELEASE_NAME "lib${libname}")
SET (LIB_DEBUG_NAME "lib${libname}_D")
- ELSE (WIN32 AND NOT MINGW)
+ ELSE (WIN32)
# if the generator supports configuration types or if the CMAKE_BUILD_TYPE has a value
IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
SET (LIB_RELEASE_NAME "${libname}")
@@ -66,7 +66,7 @@ MACRO (HDF_SET_LIB_OPTIONS libtarget libname libtype)
SET (LIB_RELEASE_NAME "lib${libname}")
SET (LIB_DEBUG_NAME "lib${libname}_debug")
ENDIF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
- ENDIF (WIN32 AND NOT MINGW)
+ ENDIF (WIN32)
ENDIF (${libtype} MATCHES "SHARED")
SET_TARGET_PROPERTIES (${libtarget}
diff --git a/config/gnu-flags b/config/gnu-flags
index 38ea4e4..40aa1da 100644
--- a/config/gnu-flags
+++ b/config/gnu-flags
@@ -186,10 +186,84 @@ esac
# the information from the previous version and adding modifications to that.
case "$cc_vendor-$cc_version" in
+# Closer to the gcc 4.8 release, we should check for additional flags to
+# include and break it out into it's own section, like the other versions
+# below. -QAK
+ gcc-4.[78]*)
+ # Replace -ansi flag with -std=c99 flag
+ H5_CFLAGS="`echo $H5_CFLAGS | sed -e 's/-ansi/-std=c99/g'`"
+
+ # Append warning flags
+ # Don't use the '-Wtraditional' flag, we're way past having K&R C code
+ # H5_CFLAGS="$H5_CFLAGS -Wtraditional"
+ # Don't use the '-Wtraditional-conversion' flag, there's too many warnings
+ # from GCC's assert macro
+ # H5_CFLAGS="$H5_CFLAGS -Wtraditional-conversion"
+
+ # Append warning flags from gcc-3* case
+ # (don't use -Wpadded flag for normal builds, many of the warnings its
+ # issuing can't be fixed and they are making it hard to detect other,
+ # more important warnings)
+ #H5_CFLAGS="$H5_CFLAGS -Wfloat-equal -Wmissing-format-attribute -Wpadded"
+ H5_CFLAGS="$H5_CFLAGS -Wfloat-equal -Wmissing-format-attribute"
+
+ # Append warning flags from gcc-3.2* case
+ H5_CFLAGS="$H5_CFLAGS -Wmissing-noreturn -Wpacked -Wdisabled-optimization"
+
+ # Enable more format checking flags, beyond the basic -Wformat included
+ # in -Wall
+ H5_CFLAGS="$H5_CFLAGS -Wformat=2"
+
+ # The "unreachable code" warning appears to be reliable now...
+ # (this warning was removed in gcc 4.5+)
+ #H5_CFLAGS="$H5_CFLAGS -Wunreachable-code"
+
+ # Append warning flags from gcc-3.3* case
+ H5_CFLAGS="$H5_CFLAGS -Wendif-labels"
+
+ # Append warning flags from gcc-3.4* case
+ H5_CFLAGS="$H5_CFLAGS -Wdeclaration-after-statement -Wold-style-definition -Winvalid-pch"
+
+ # Replace old -W flag with new -Wextra flag
+ H5_CFLAGS="`echo $H5_CFLAGS | sed -e 's/-W\ /-Wextra\ /g'`"
+
+ # Append more extra warning flags that only gcc4.0+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wvariadic-macros -Winit-self -Wmissing-include-dirs -Wswitch-default -Wswitch-enum -Wunused-macros"
+
+ # Append more extra warning flags that only gcc 4.1+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wunsafe-loop-optimizations -Wc++-compat"
+
+ # Append more extra warning flags that only gcc 4.2+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wstrict-overflow"
+
+ # Append more extra warning flags that only gcc 4.3+ know about
+ #
+ # Technically, variable-length arrays are part of the C99 standard, but
+ # we should approach them a bit cautiously... -QAK
+ H5_CFLAGS="$H5_CFLAGS -Wlogical-op -Wlarger-than=2048 -Wvla"
+
+ # Append more extra warning flags that only gcc 4.4+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wsync-nand -Wframe-larger-than=16384 -Wpacked-bitfield-compat"
+
+ # Append more extra warning flags that only gcc 4.5+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wstrict-overflow=5 -Wjump-misses-init -Wunsuffixed-float-constants"
+
+ # Append more extra warning flags that only gcc 4.6+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wdouble-promotion -Wsuggest-attribute=const -Wtrampolines"
+
+ # Append more extra warning flags that only gcc 4.7+ know about
+ H5_CFLAGS="$H5_CFLAGS -Wstack-usage=8192 -Wvector-operation-performance"
+
+ # Try out the new "stack protector" feature in gcc 4.1
+ # (Strictly speaking this isn't really a "warning" flag, so it's added to
+ # the debugging flags)
+ #DEBUG_CFLAGS="$DEBUG_CFLAGS -Wstack-protector -fstack-protector-all"
+ ;;
+
# Closer to the gcc 4.7 release, we should check for additional flags to
# include and break it out into it's own section, like the other versions
# below. -QAK
- gcc-4.[67]*)
+ gcc-4.6*)
# Replace -ansi flag with -std=c99 flag
H5_CFLAGS="`echo $H5_CFLAGS | sed -e 's/-ansi/-std=c99/g'`"
diff --git a/config/lt_vers.am b/config/lt_vers.am
index daf5dc6..316d0c9 100644
--- a/config/lt_vers.am
+++ b/config/lt_vers.am
@@ -17,7 +17,7 @@
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
## If the API changes *at all*, increment LT_VERS_INTERFACE and
diff --git a/configure b/configure
index 15fc172..016f11d 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
#! /bin/sh
-# From configure.in Id: configure.in 22040 2012-03-11 15:52:04Z hdftest .
+# From configure.in Id: configure.in 22149 2012-03-26 20:26:06Z mamcgree .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for HDF5 1.9.112.
+# Generated by GNU Autoconf 2.68 for HDF5 1.9.114.
#
# Report bugs to <help@hdfgroup.org>.
#
@@ -571,8 +571,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='HDF5'
PACKAGE_TARNAME='hdf5'
-PACKAGE_VERSION='1.9.112'
-PACKAGE_STRING='HDF5 1.9.112'
+PACKAGE_VERSION='1.9.114'
+PACKAGE_STRING='HDF5 1.9.114'
PACKAGE_BUGREPORT='help@hdfgroup.org'
PACKAGE_URL=''
@@ -1464,7 +1464,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures HDF5 1.9.112 to adapt to many kinds of systems.
+\`configure' configures HDF5 1.9.114 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1534,7 +1534,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of HDF5 1.9.112:";;
+ short | recursive ) echo "Configuration of HDF5 1.9.114:";;
esac
cat <<\_ACEOF
@@ -1729,7 +1729,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-HDF5 configure 1.9.112
+HDF5 configure 1.9.114
generated by GNU Autoconf 2.68
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2818,7 +2818,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by HDF5 $as_me 1.9.112, which was
+It was created by HDF5 $as_me 1.9.114, which was
generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@
@@ -3639,7 +3639,7 @@ fi
# Define the identity of the package.
PACKAGE='hdf5'
- VERSION='1.9.112'
+ VERSION='1.9.114'
cat >>confdefs.h <<_ACEOF
@@ -21556,22 +21556,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-case $host_os in
- linux* | freebsd* )
- # If gcc is not used, need to set $wl to use "-Wl,"
- if $CC -v 2>&1 | grep '^gcc' > /dev/null ; then
- : using gcc
- else
- echo 'fixing $wl in' $ofile
-ed - $ofile <<EOF 2> /dev/null
-/^wl=""/s//wl="-Wl,"/
-w
-q
-EOF
- fi
- ;;
-esac
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should install only statically linked executables" >&5
$as_echo_n "checking if we should install only statically linked executables... " >&6; }
# Check whether --enable-static_exec was given.
@@ -30645,7 +30629,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by HDF5 $as_me 1.9.112, which was
+This file was extended by HDF5 $as_me 1.9.114, which was
generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -30711,7 +30695,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-HDF5 config.status 1.9.112
+HDF5 config.status 1.9.114
configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
@@ -33505,7 +33489,7 @@ Usage: $0 [OPTIONS]
Report bugs to <bug-libtool@gnu.org>."
lt_cl_version="\
-HDF5 config.lt 1.9.112
+HDF5 config.lt 1.9.114
configured by $0, generated by GNU Autoconf 2.68.
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -34998,6 +34982,22 @@ touch ./config/stamp2
# Finally the makefiles
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+case $host_os in
+ linux* | freebsd* )
+ # If gcc is not used, need to set $wl to use "-Wl,"
+ if $CC -v 2>&1 | grep '^gcc' > /dev/null ; then
+ : using gcc
+ else
+ echo 'fixing $wl in' $ofile
+ed - $ofile <<EOF 2> /dev/null
+g/^wl=""/s//wl="-Wl,"/
+w
+q
+EOF
+ fi
+ ;;
+esac
+
if (./libtool --features | grep '^enable shared libraries' > /dev/null); then
enable_shared=yes
else
diff --git a/configure.in b/configure.in
index 6b7eeff..d919a5b 100644
--- a/configure.in
+++ b/configure.in
@@ -26,7 +26,7 @@ dnl
dnl NOTE: Don't forget to change the version number here when we do a
dnl release!!!
dnl
-AC_INIT([HDF5], [1.9.112], [help@hdfgroup.org])
+AC_INIT([HDF5], [1.9.114], [help@hdfgroup.org])
AC_CONFIG_SRCDIR([src/H5.c])
AM_CONFIG_HEADER([src/H5config.h])
@@ -1027,24 +1027,6 @@ dnl or disabled, it should happen before these macros.
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
-dnl Post processing to patch up some deficiencies in libtool (as of
-dnl Libtool 1.5.14)
-case $host_os in
- linux* | freebsd* )
- # If gcc is not used, need to set $wl to use "-Wl,"
- if $CC -v 2>&1 | grep '^gcc' > /dev/null ; then
- : using gcc
- else
- echo 'fixing $wl in' $ofile
-ed - $ofile <<EOF 2> /dev/null
-/^wl=""/s//wl="-Wl,"/
-w
-q
-EOF
- fi
- ;;
-esac
-
dnl ----------------------------------------------------------------------
dnl Check if we should install only statically linked executables.
dnl This check needs to occur after libtool is initialized because
@@ -4495,6 +4477,23 @@ touch ./config/stamp2
# Finally the makefiles
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+dnl Post processing to patch up some deficiencies in libtool
+case $host_os in
+ linux* | freebsd* )
+ # If gcc is not used, need to set $wl to use "-Wl,"
+ if $CC -v 2>&1 | grep '^gcc' > /dev/null ; then
+ : using gcc
+ else
+ echo 'fixing $wl in' $ofile
+ed - $ofile <<EOF 2> /dev/null
+g/^wl=""/s//wl="-Wl,"/
+w
+q
+EOF
+ fi
+ ;;
+esac
+
dnl Are we compiling static libraries, shared libraries, or both? This
dnl is only used for the libhdf5.settings file. We can't just look at
dnl $enable_static and $enable_shared because if they're yes the ltconfig
diff --git a/examples/run-c-ex.sh.in b/examples/run-c-ex.sh.in
index 8d0bdcd..8d0bdcd 100755..100644
--- a/examples/run-c-ex.sh.in
+++ b/examples/run-c-ex.sh.in
diff --git a/examples/testh5cc.sh.in b/examples/testh5cc.sh.in
index 0e2b851..0e2b851 100755..100644
--- a/examples/testh5cc.sh.in
+++ b/examples/testh5cc.sh.in
diff --git a/fortran/COPYING b/fortran/COPYING
index 6903daf..6903daf 100755..100644
--- a/fortran/COPYING
+++ b/fortran/COPYING
diff --git a/fortran/examples/run-fortran-ex.sh.in b/fortran/examples/run-fortran-ex.sh.in
index 873669f..873669f 100755..100644
--- a/fortran/examples/run-fortran-ex.sh.in
+++ b/fortran/examples/run-fortran-ex.sh.in
diff --git a/fortran/examples/testh5fc.sh.in b/fortran/examples/testh5fc.sh.in
index 234d4e2..234d4e2 100755..100644
--- a/fortran/examples/testh5fc.sh.in
+++ b/fortran/examples/testh5fc.sh.in
diff --git a/fortran/src/H5Of.c b/fortran/src/H5Of.c
index 0df433a..531f09c 100644
--- a/fortran/src/H5Of.c
+++ b/fortran/src/H5Of.c
@@ -334,3 +334,60 @@ nh5oget_info_by_name_c (hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *
return ret_value;
}
+/* ***if* H5Of/H5Ocopy_c
+ * NAME
+ * H5Ocopy_c
+ * PURPOSE
+ * Calls H5Ocopy
+ * INPUTS
+ * src_loc_id - Object identifier indicating the location of the source object to be copied
+ * src_name - Name of the source object to be copied
+ * src_name_len - Length of src_name
+ * dst_loc_id - Location identifier specifying the destination
+ * dst_name - Name to be assigned to the new copy
+ * dst_name_len - Length of dst_name
+ * ocpypl_id - Object copy property list
+ * lcpl_id - Link creation property list for the new hard link
+ *
+ * RETURNS
+ * 0 on success, -1 on failure
+ * AUTHOR
+ * M. Scot Breitenfeld
+ * March 14, 2012
+ * SOURCE
+*/
+int_f
+nh5ocopy_c (hid_t_f *src_loc_id, _fcd src_name, size_t_f *src_name_len,
+ hid_t_f *dst_loc_id, _fcd dst_name, size_t_f *dst_name_len,
+ hid_t_f *ocpypl_id, hid_t_f *lcpl_id )
+/******/
+{
+ char *c_src_name = NULL; /* Buffer to hold C string */
+ char *c_dst_name = NULL; /* Buffer to hold C string */
+
+ int_f ret_value = 0; /* Return value */
+
+ /*
+ * Convert FORTRAN name to C name
+ */
+ if((c_src_name = HD5f2cstring(src_name, (size_t)*src_name_len)) == NULL)
+ HGOTO_DONE(FAIL);
+ if((c_dst_name = HD5f2cstring(dst_name, (size_t)*dst_name_len)) == NULL)
+ HGOTO_DONE(FAIL);
+
+ /*
+ * Call H5Ocopy function.
+ */
+ if(H5Ocopy( (hid_t)*src_loc_id, c_src_name, (hid_t)*dst_loc_id, c_dst_name,
+ (hid_t)*ocpypl_id, (hid_t)*lcpl_id) < 0)
+ HGOTO_DONE(FAIL);
+
+ done:
+ if(c_src_name)
+ HDfree(c_src_name);
+ if(c_dst_name)
+ HDfree(c_dst_name);
+
+ return ret_value;
+
+}
diff --git a/fortran/src/H5Off.f90 b/fortran/src/H5Off.f90
index e69fdb5..4f1ea18 100644
--- a/fortran/src/H5Off.f90
+++ b/fortran/src/H5Off.f90
@@ -49,33 +49,32 @@ CONTAINS
!
! PURPOSE
! Creates a hard link to an object in an HDF5 file.
-! INPUTS
+!
+! Inputs:
! object_id - Object to be linked.
! new_loc_id - File or group identifier specifying location at which object is to be linked.
! new_link_name - Name of link to be created, relative to new_loc_id.
-! OUTPUTS
-! hdferr: - error code
-! Success: 0
-! Failure: -1
-! OPTIONAL PARAMETERS
+!
+! Outputs:
+! hdferr - Returns 0 if successful and -1 if fails.
+!
+! Optional parameters:
! lcpl_id - Link creation property list identifier.
! lapl_id - Link access property list identifier.
+!
! AUTHOR
! M. Scot Breitenfeld
! April 21, 2008
!
-! SOURCE
+! Fortran90 Interface:
SUBROUTINE h5olink_f(object_id, new_loc_id, new_link_name, hdferr, lcpl_id, lapl_id)
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: object_id ! Object to be linked
- INTEGER(HID_T), INTENT(IN) :: new_loc_id ! File or group identifier specifying
- ! location at which object is to be linked.
- CHARACTER(LEN=*), INTENT(IN) :: new_link_name ! Name of link to be created, relative to new_loc_id.
- INTEGER, INTENT(OUT) :: hdferr ! Error code
- ! Success: 0
- ! Failure: -1
- INTEGER(HID_T), OPTIONAL, INTENT(IN) :: lcpl_id ! Link creation property list identifier.
- INTEGER(HID_T), OPTIONAL, INTENT(IN) :: lapl_id ! Link creation property list identifier.
+ INTEGER(HID_T) , INTENT(IN) :: object_id
+ INTEGER(HID_T) , INTENT(IN) :: new_loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: new_link_name
+ INTEGER , INTENT(OUT) :: hdferr
+ INTEGER(HID_T) , INTENT(IN), OPTIONAL :: lcpl_id
+ INTEGER(HID_T) , INTENT(IN), OPTIONAL :: lapl_id
!*****
INTEGER(HID_T) :: lapl_id_default
INTEGER(HID_T) :: lcpl_id_default
@@ -115,33 +114,33 @@ CONTAINS
!
! NAME
! h5oopen_f
+!
! PURPOSE
! Opens an object in an HDF5 file by location identifier and path name.
!
-! INPUTS
-! loc_id - File or group identifier
+! Inputs:
+! loc_id - File or group identifier.
! name - Path to the object, relative to loc_id.
-! OUTPUTS
-! obj_id - Object identifier for the opened object
-! hdferr: - error code
-! Success: 0
-! Failure: -1
-! OPTIONAL PARAMETERS
-! lapl_id - Access property list identifier for the link pointing to the object
+!
+! Outputs:
+! obj_id - Object identifier for the opened object.
+! hdferr - Returns 0 if successful and -1 if fails.
+!
+! Optional parameters:
+! lapl_id - Access property list identifier for the link pointing to the object.
!
! AUTHOR
! M. Scot Breitenfeld
! April 18, 2008
-! SOURCE
+!
+! Fortran90 Interface:
SUBROUTINE h5oopen_f(loc_id, name, obj_id, hdferr, lapl_id)
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: loc_id ! File or group identifier
- CHARACTER(LEN=*), INTENT(IN) :: name ! Path to the object, relative to loc_id
- INTEGER(HID_T), INTENT(OUT) :: obj_id ! Object identifier for the opened object
- INTEGER, INTENT(OUT) :: hdferr ! Error code
- ! Success: 0
- ! Failure: -1
- INTEGER(HID_T), OPTIONAL, INTENT(IN) :: lapl_id ! Attribute access property list
+ INTEGER(HID_T) , INTENT(IN) :: loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: name
+ INTEGER(HID_T) , INTENT(OUT) :: obj_id
+ INTEGER , INTENT(OUT) :: hdferr
+ INTEGER(HID_T) , INTENT(IN), OPTIONAL :: lapl_id
!*****
INTEGER(HID_T) :: lapl_id_default
INTEGER(SIZE_T) :: namelen
@@ -178,20 +177,21 @@ CONTAINS
! PURPOSE
! Closes an object in an HDF5 file.
!
-! INPUTS
-! object_id - Object identifier
-! OUTPUTS
-! hdferr - Returns 0 if successful and -1 if fails
+! Inputs:
+! object_id - Object identifier.
+!
+! Outputs:
+! hdferr - Returns 0 if successful and -1 if fails.
!
! AUTHOR
! M. Scot Breitenfeld
! December 17, 2008
!
-! SOURCE
+! Fortran90 Interface:
SUBROUTINE h5oclose_f(object_id, hdferr)
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: object_id
- INTEGER, INTENT(OUT) :: hdferr
+ INTEGER(HID_T), INTENT(IN) :: object_id
+ INTEGER , INTENT(OUT) :: hdferr
!*****
INTERFACE
INTEGER FUNCTION h5oclose_c(object_id)
@@ -214,25 +214,25 @@ CONTAINS
! PURPOSE
! Opens an object using its address within an HDF5 file.
!
-! INPUTS
-! loc_id - File or group identifier
-! addr - Object’s address in the file
-! OUTPUTS:
-! obj_id - Object identifier for the opened object
-! hdferr - Returns 0 if successful and -1 if fails
+! Inputs:
+! loc_id - File or group identifier.
+! addr - Object’s address in the file.
+!
+! Outputs:
+! obj_id - Object identifier for the opened object.
+! hdferr - Returns 0 if successful and -1 if fails.
!
! AUTHOR
! M. Scot Breitenfeld
! September 14, 2009
!
-! SOURCE
+! Fortran90 Interface:
SUBROUTINE h5oopen_by_addr_f(loc_id, addr, obj_id, hdferr)
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: loc_id ! File or group identifier
- INTEGER(HADDR_T), INTENT(IN) :: addr ! Object’s address in the file
- INTEGER(HID_T), INTENT(OUT) :: obj_id ! Object identifier for the opened object
- INTEGER, INTENT(OUT) :: hdferr ! Error code:
- ! 0 on success and -1 on failure
+ INTEGER(HID_T) , INTENT(IN) :: loc_id
+ INTEGER(HADDR_T), INTENT(IN) :: addr
+ INTEGER(HID_T) , INTENT(OUT) :: obj_id
+ INTEGER , INTENT(OUT) :: hdferr
!*****
INTERFACE
INTEGER FUNCTION h5oopen_by_addr_c(loc_id, addr, obj_id)
@@ -249,6 +249,77 @@ CONTAINS
hdferr = h5oopen_by_addr_c(loc_id, addr, obj_id)
END SUBROUTINE h5oopen_by_addr_f
+!
+!****s* H5O/h5ocopy_f
+! NAME
+! h5ocopy_f
+!
+! PURPOSE
+! Copies an object in an HDF5 file.
+!
+! Inputs:
+! src_loc_id - Object identifier indicating the location of the source object to be copied.
+! src_name - Name of the source object to be copied.
+! dst_loc_id - Location identifier specifying the destination.
+! dst_name - Name to be assigned to the new copy.
+!
+! Optional parameters:
+! ocpypl_id - Object copy property list.
+! lcpl_id - Link creation property list for the new hard link.
+!
+! Outputs:
+! hdferr - Returns 0 if successful and -1 if fails.
+!
+! AUTHOR
+! M. Scot Breitenfeld
+! March 14, 2012
+!
+! Fortran90 Interface:
+ SUBROUTINE h5ocopy_f(src_loc_id, src_name, dst_loc_id, dst_name, hdferr, ocpypl_id, lcpl_id)
+ IMPLICIT NONE
+ INTEGER(HID_T) , INTENT(IN) :: src_loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: src_name
+ INTEGER(HID_T) , INTENT(IN) :: dst_loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: dst_name
+ INTEGER , INTENT(OUT) :: hdferr
+ INTEGER(HID_T) , INTENT(IN), OPTIONAL :: ocpypl_id
+ INTEGER(HID_T) , INTENT(IN), OPTIONAL :: lcpl_id
+!*****
+
+ INTEGER(SIZE_T) :: src_name_len, dst_name_len
+ INTEGER(HID_T) :: ocpypl_id_default, lcpl_id_default
+
+ INTERFACE
+ INTEGER FUNCTION h5ocopy_c(src_loc_id, src_name, src_name_len, &
+ dst_loc_id, dst_name, dst_name_len, ocpypl_id_default, lcpl_id_default)
+ USE H5GLOBAL
+ !DEC$IF DEFINED(HDF5F90_WINDOWS)
+ !DEC$ATTRIBUTES C,reference,decorate,alias:'H5OCOPY_C'::h5ocopy_c
+ !DEC$ENDIF
+ !DEC$ATTRIBUTES reference :: src_name, dst_name
+ INTEGER(HID_T) , INTENT(IN) :: src_loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: src_name
+ INTEGER(HID_T) , INTENT(IN) :: dst_loc_id
+ CHARACTER(LEN=*), INTENT(IN) :: dst_name
+ INTEGER(HID_T) , INTENT(IN) :: ocpypl_id_default
+ INTEGER(HID_T) , INTENT(IN) :: lcpl_id_default
+ INTEGER(SIZE_T) :: src_name_len, dst_name_len
+
+ END FUNCTION h5ocopy_c
+ END INTERFACE
+
+ src_name_len = LEN(src_name)
+ dst_name_len = LEN(dst_name)
+
+ ocpypl_id_default = H5P_DEFAULT_F
+ IF(PRESENT(ocpypl_id)) ocpypl_id_default = ocpypl_id
+ lcpl_id_default = H5P_DEFAULT_F
+ IF(PRESENT(lcpl_id)) lcpl_id_default = lcpl_id
+
+ hdferr = h5ocopy_c(src_loc_id, src_name, src_name_len, &
+ dst_loc_id, dst_name, dst_name_len, ocpypl_id_default, lcpl_id_default)
+
+ END SUBROUTINE h5ocopy_f
END MODULE H5O
diff --git a/fortran/src/H5Pff.f90 b/fortran/src/H5Pff.f90
index 2d874d0..d50e3b9 100644
--- a/fortran/src/H5Pff.f90
+++ b/fortran/src/H5Pff.f90
@@ -53,11 +53,23 @@ CONTAINS
! INPUTS
! class - type of the property class to be created.
! Possible values are:
-! H5P_FILE_CREATE_F
-! H5P_FILE_ACCESS_F
-! H5P_DATASET_CREATE_F
-! H5P_DATASET_XFER_F
-! H5P_FILE_MOUNT_F
+! H5P_OBJECT_CREATE_F
+! H5P_FILE_CREATE_F
+! H5P_FILE_ACCESS_F
+! H5P_DATASET_CREATE_F
+! H5P_DATASET_ACCESS_F
+! H5P_DATASET_XFER_F
+! H5P_FILE_MOUNT_F
+! H5P_GROUP_CREATE_F
+! H5P_GROUP_ACCESS_F
+! H5P_DATATYPE_CREATE_F
+! H5P_DATATYPE_ACCESS_F
+! H5P_STRING_CREATE_F
+! H5P_ATTRIBUTE_CREATE _F
+! H5P_OBJECT_COPY_F
+! H5P_LINK_CREATE_F
+! H5P_LINK_ACCESS_F
+!
! OUTPUTS
! prp_id - property list identifier
! hdferr - error code
@@ -76,16 +88,9 @@ CONTAINS
! Fortran90 Interface:
SUBROUTINE h5pcreate_f(class, prp_id, hdferr)
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: class ! The type of the property list
- ! to be created. Possible values are:
- ! H5P_FILE_CREATE_F
- ! H5P_FILE_ACCESS_F
- ! H5P_DATASET_CREATE_F
- ! H5P_DATASET_XFER_F
- ! H5P_FILE_MOUNT_F
- INTEGER(HID_T), INTENT(OUT) :: prp_id ! Property list identifier
- INTEGER, INTENT(OUT) :: hdferr ! Error code
- ! 0 on success and -1 on failure
+ INTEGER(HID_T), INTENT(IN) :: class
+ INTEGER(HID_T), INTENT(OUT) :: prp_id
+ INTEGER , INTENT(OUT) :: hdferr
!*****
! INTEGER, EXTERNAL :: h5pcreate_c
! MS FORTRAN needs explicit interface for C functions called here.
diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h
index 89957a4..a504653 100644
--- a/fortran/src/H5f90proto.h
+++ b/fortran/src/H5f90proto.h
@@ -805,10 +805,12 @@ H5_FCDLL int_f nh5tconvert_c(hid_t_f *src_id, hid_t_f *dst_id, size_t_f *nelmts,
#define nh5olink_c H5_FC_FUNC_(h5olink_c, H5OLINK_C)
#define nh5oopen_c H5_FC_FUNC_(h5oopen_c, H5OOPEN_C)
-#define nh5oclose_c H5_FC_FUNC_(h5oclose_c, H5OCLOSE_C)
+#define nh5oclose_c H5_FC_FUNC_(h5oclose_c, H5OCLOSE_C)
#define nh5ovisit_c H5_FC_FUNC_(h5ovisit_c,H5OVISIT_C)
#define nh5oget_info_by_name_c H5_FC_FUNC_(h5oget_info_by_name_c ,H5OGET_INFO_BY_NAME_C)
#define nh5oopen_by_addr_c H5_FC_FUNC_(h5oopen_by_addr_c, H5OOPEN_BY_ADDR_C)
+#define nh5ocopy_c H5_FC_FUNC_(h5ocopy_c, H5OCOPY_C)
+
H5_FCDLL int_f nh5oopen_c (hid_t_f *loc_id, _fcd name, size_t_f *namelen, hid_t_f *lapl_id, hid_t_f *obj_id);
H5_FCDLL int_f nh5oclose_c (hid_t_f *object_id );
@@ -818,6 +820,9 @@ H5_FCDLL int_f nh5olink_c (hid_t_f *object_id, hid_t_f *new_loc_id, _fcd name, s
H5_FCDLL int_f nh5ovisit_c (hid_t_f *group_id, int_f *index_type, int_f *order, H5O_iterate_t op, void *op_data);
H5_FCDLL int_f nh5oget_info_by_name_c (hid_t_f *loc_id, _fcd name, size_t_f *namelen,hid_t_f *lapl_id,
H5O_info_t_f *object_info);
+H5_FCDLL int_f nh5ocopy_c (hid_t_f *src_loc_id, _fcd src_name, size_t_f *src_name_len,
+ hid_t_f *dst_loc_id, _fcd dst_name, size_t_f *dst_name_len,
+ hid_t_f *ocpypl_id, hid_t_f *lcpl_id );
/*
* Functions from H5Pf.c
*/
diff --git a/fortran/src/Makefile.in b/fortran/src/Makefile.in
index 35fafee..875f6f7 100644
--- a/fortran/src/Makefile.in
+++ b/fortran/src/Makefile.in
@@ -478,7 +478,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
# Include src directory in both Fortran and C flags (C compiler is used
diff --git a/fortran/src/h5fc.in b/fortran/src/h5fc.in
index 9e9409d..2d7b5b4 100755..100644
--- a/fortran/src/h5fc.in
+++ b/fortran/src/h5fc.in
@@ -189,7 +189,7 @@ for arg in $@ ; do
get_output_file="yes"
fi
;;
- -E|-M)
+ -E|-M|-MT)
allargs="$allargs $arg"
compile_args="$compile_args $arg"
dash_c="yes"
diff --git a/fortran/src/hdf5_fortrandll.def b/fortran/src/hdf5_fortrandll.def
index 6b3aad8..29e83f5 100644
--- a/fortran/src/hdf5_fortrandll.def
+++ b/fortran/src/hdf5_fortrandll.def
@@ -284,6 +284,7 @@ H5L_mp_H5LIS_REGISTERED_F
H5L_mp_H5LMOVE_F
H5L_mp_H5LGET_NAME_BY_IDX_F
; H5O
+H5O_mp_H5OCOPY_F
H5O_mp_H5OLINK_F
H5O_mp_H5OOPEN_F
H5O_mp_H5OOPEN_BY_ADDR_F
diff --git a/fortran/src/phdf5_fortrandll.def b/fortran/src/phdf5_fortrandll.def
index a4bc9eb..7a196cd 100644
--- a/fortran/src/phdf5_fortrandll.def
+++ b/fortran/src/phdf5_fortrandll.def
@@ -284,6 +284,7 @@ H5L_mp_H5LIS_REGISTERED_F
H5L_mp_H5LMOVE_F
H5L_mp_H5LGET_NAME_BY_IDX_F
; H5O
+H5O_mp_H5OCOPY_F
H5O_mp_H5OLINK_F
H5O_mp_H5OOPEN_F
H5O_mp_H5OOPEN_BY_ADDR_F
diff --git a/fortran/test/CMakeLists.txt b/fortran/test/CMakeLists.txt
index e6ddbaf..d19baea 100644
--- a/fortran/test/CMakeLists.txt
+++ b/fortran/test/CMakeLists.txt
@@ -73,6 +73,7 @@ SET_TARGET_PROPERTIES (testhdf5_fortran PROPERTIES LINKER_LANGUAGE Fortran)
SET_TARGET_PROPERTIES (testhdf5_fortran PROPERTIES FOLDER test/fortran)
ADD_TEST (NAME testhdf5_fortran COMMAND $<TARGET_FILE:testhdf5_fortran>)
+SET_TESTS_PROPERTIES(testhdf5_fortran PROPERTIES PASS_REGULAR_EXPRESSION "[ ]*0 error.s")
#-- Adding test for testhdf5_fortran_1_8
ADD_EXECUTABLE (testhdf5_fortran_1_8
@@ -96,6 +97,7 @@ SET_TARGET_PROPERTIES (testhdf5_fortran_1_8 PROPERTIES LINKER_LANGUAGE Fortran)
SET_TARGET_PROPERTIES (testhdf5_fortran_1_8 PROPERTIES FOLDER test/fortran)
ADD_TEST (NAME testhdf5_fortran_1_8 COMMAND $<TARGET_FILE:testhdf5_fortran_1_8>)
+SET_TESTS_PROPERTIES(testhdf5_fortran_1_8 PROPERTIES PASS_REGULAR_EXPRESSION "[ ]*0 error.s")
#-- Adding test for fortranlib_test_F03
IF (FORTRAN_HAVE_ISO_C_BINDING AND HDF5_ENABLE_F2003)
@@ -121,6 +123,7 @@ IF (FORTRAN_HAVE_ISO_C_BINDING AND HDF5_ENABLE_F2003)
SET_TARGET_PROPERTIES (fortranlib_test_F03 PROPERTIES FOLDER test/fortran)
ADD_TEST (NAME fortranlib_test_F03 COMMAND $<TARGET_FILE:fortranlib_test_F03>)
+ SET_TESTS_PROPERTIES(fortranlib_test_F03 PROPERTIES PASS_REGULAR_EXPRESSION "[ ]*0 error.s")
ENDIF (FORTRAN_HAVE_ISO_C_BINDING AND HDF5_ENABLE_F2003)
#-- Adding test for fflush1
diff --git a/fortran/test/tH5O.f90 b/fortran/test/tH5O.f90
index d871e59..247d1d0 100644
--- a/fortran/test/tH5O.f90
+++ b/fortran/test/tH5O.f90
@@ -72,6 +72,7 @@ SUBROUTINE test_h5o_link(total_error)
INTEGER(HID_T) :: type_id
INTEGER(HID_T) :: fapl_id
INTEGER(HID_T) :: lcpl_id
+ INTEGER(HID_T) :: ocpypl_id
INTEGER(HID_T) :: mem_space_id, file_space_id, xfer_prp
CHARACTER(LEN=11), PARAMETER :: TEST_FILENAME = 'TestFile.h5'
INTEGER, PARAMETER :: TEST6_DIM1 = 2, TEST6_DIM2 = 5
@@ -82,52 +83,65 @@ SUBROUTINE test_h5o_link(total_error)
INTEGER, PARAMETER :: TRUE = 1, FALSE = 0
- LOGICAL :: committed ! /* Whether the named datatype is committed */
+ LOGICAL :: committed ! /* Whether the named datatype is committed
INTEGER :: i, n, j
- INTEGER :: error ! /* Value returned from API calls */
-
- ! /* Initialize the raw data */
+ INTEGER :: error ! /* Value returned from API calls
+
+ CHARACTER(LEN=14) :: NAME_DATATYPE_SIMPLE="H5T_NATIVE_INT"
+ CHARACTER(LEN=16) :: NAME_DATATYPE_SIMPLE2="H5T_NATIVE_INT-2"
+ INTEGER(HID_T) :: tid, tid2
+ LOGICAL :: flag
+
+ ! Data for tested h5ocopy_f
+ CHARACTER(LEN=3) , PARAMETER :: dataset = "DS1"
+ INTEGER , PARAMETER :: dim0 = 4
+
+ INTEGER(HSIZE_T), DIMENSION(1:1) :: dims2 = (/dim0/) ! size read/write buffer
+ INTEGER , DIMENSION(1:dim0) :: wdata2, & ! Write buffer
+ rdata2 ! Read buffer
+
+ ! Initialize the raw data
DO i = 1, TEST6_DIM1
DO j = 1, TEST6_DIM2
wdata(i,j) = i*j
ENDDO
ENDDO
- ! /* Create the dataspace */
+ ! Create the dataspace
CALL h5screate_simple_f(2, dims, space_id, error)
CALL check("h5screate_simple_f",error,total_error)
- ! /* Create LCPL with intermediate group creation flag set */
+ ! Create LCPL with intermediate group creation flag set
CALL H5Pcreate_f(H5P_LINK_CREATE_F, lcpl_id, error)
CALL check("h5Pcreate_f",error,total_error)
CALL H5Pset_create_inter_group_f(lcpl_id, TRUE, error)
CALL check("H5Pset_create_inter_group_f",error,total_error)
- ! /* Loop over using new group format */
+ ! Loop over using new group format
! for(new_format = FALSE; new_format <= TRUE; new_format++) {
- !/* Make a FAPL that uses the "use the latest version of the format" bounds */
+ ! Make a FAPL that uses the "use the latest version of the format" bounds
CALL H5Pcreate_f(H5P_FILE_ACCESS_F,fapl_id,error)
CALL check("h5Pcreate_f",error,total_error)
- ! /* Set the "use the latest version of the format" bounds for creating objects in the file */
+ ! Set the "use the latest version of the format" bounds for creating objects in the file
CALL H5Pset_libver_bounds_f(fapl_id, H5F_LIBVER_LATEST_F, H5F_LIBVER_LATEST_F, error)
CALL check("H5Pset_libver_bounds_f",error, total_error)
!!$ ret = H5Pset_libver_bounds(fapl_id, (new_format ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST);
- ! /* Create a new HDF5 file */
+ ! Create a new HDF5 file
CALL H5Fcreate_f(TEST_FILENAME, H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl_id)
CALL check("H5Fcreate_f", error, total_error)
- ! /* Close the FAPL */
+ ! Close the FAPL
CALL h5pclose_f(fapl_id, error)
CALL check("h5pclose_f",error,total_error)
- ! /* Create and commit a datatype with no name */
+ ! Create and commit a datatype with no name
CALL H5Tcopy_f( H5T_NATIVE_INTEGER, type_id, error)
CALL check("H5Tcopy_F",error,total_error)
@@ -138,27 +152,27 @@ SUBROUTINE test_h5o_link(total_error)
CALL check("H5Tcommitted_f",error,total_error)
CALL verifyLogical("H5Tcommitted_f", committed, .TRUE., total_error)
- ! /* Create a dataset with no name using the committed datatype*/
+ ! Create a dataset with no name using the committed datatype
CALL H5Dcreate_anon_f(file_id, type_id, space_id, dset_id, error ) ! using no optional parameters
CALL check("H5Dcreate_anon_f",error,total_error)
- ! /* Verify that we can write to and read from the dataset */
+ ! Verify that we can write to and read from the dataset
- ! /* Write the data to the dataset */
+ ! Write the data to the dataset
!EP CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, wdata, dims, error, &
!EP mem_space_id=H5S_ALL_F, file_space_id=H5S_ALL_F, xfer_prp = H5P_DEFAULT_F)
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, wdata, dims, error)
CALL check("h5dwrite_f", error, total_error)
- ! /* Read the data back */
+ ! Read the data back
!EP CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, rdata, dims, error, &
!EP mem_space_id=H5S_ALL_F, file_space_id=H5S_ALL_F, xfer_prp = H5P_DEFAULT_F)
CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, rdata, dims, error)
CALL check("h5dread_f", error, total_error)
- ! /* Verify the data */
+ ! Verify the data
DO i = 1, TEST6_DIM1
DO j = 1, TEST6_DIM2
CALL VERIFY("H5Dread_f",wdata(i,j),rdata(i,j),total_error)
@@ -166,31 +180,31 @@ SUBROUTINE test_h5o_link(total_error)
ENDDO
ENDDO
- ! /* Create a group with no name*/
+ ! Create a group with no name
CALL H5Gcreate_anon_f(file_id, group_id, error)
CALL check("H5Gcreate_anon", error, total_error)
- ! /* Link nameless datatype into nameless group */
+ ! Link nameless datatype into nameless group
CALL H5Olink_f(type_id, group_id, "datatype", error, H5P_DEFAULT_F)
CALL check("H5Olink_f", error, total_error)
- ! /* Link nameless dataset into nameless group with intermediate group */
+ ! Link nameless dataset into nameless group with intermediate group
CALL H5Olink_f(dset_id, group_id, "inter_group/dataset", error, lcpl_id, H5P_DEFAULT_F)
CALL check("H5Olink_f", error, total_error)
- ! /* Close IDs for dataset and datatype */
+ ! Close IDs for dataset and datatype
CALL h5dclose_f(dset_id, error)
CALL check("h5dclose_f", error, total_error)
CALL h5tclose_f(type_id, error)
CALL check("h5tclose_f", error, total_error)
- ! /* Re-open datatype using new link */
+ ! Re-open datatype using new link
CALL H5Topen_f(group_id, "datatype", type_id, error)
CALL check("h5topen_f", error, total_error)
- ! /* Link nameless group to root group and close the group ID*/
+ ! Link nameless group to root group and close the group ID
CALL H5Olink_f(group_id, file_id, "/group", error)
CALL check("H5Olink_f", error, total_error)
@@ -198,46 +212,162 @@ SUBROUTINE test_h5o_link(total_error)
CALL h5gclose_f(group_id, error)
CALL check("h5gclose_f",error,total_error)
- ! /* Open dataset through root group and verify its data */
+ ! Open dataset through root group and verify its data
CALL H5Dopen_f(file_id, "/group/inter_group/dataset", dset_id, error)
CALL check("test_lcpl.h5dopen_f", error, total_error)
- ! /* Read data from dataset */
+ ! Read data from dataset
!EP CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, rdata, dims, error, &
!EP H5S_ALL_F, H5S_ALL_F, xfer_prp = H5P_DEFAULT_F)
CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, rdata, dims, error)
CALL check("h5dread_f", error, total_error)
- ! /* Verify the data */
+ ! Verify the data
DO i = 1, TEST6_DIM1
DO j = 1, TEST6_DIM2
CALL VERIFY("H5Dread",wdata(i,j),rdata(i,j),total_error)
ENDDO
ENDDO
- ! /* Close open IDs */
+ ! Close open IDs
CALL h5dclose_f(dset_id, error)
CALL check("h5dclose_f",error,total_error)
CALL h5tclose_f(type_id, error)
CALL check("h5tclose_f",error,total_error)
- CALL h5fclose_f(file_id, error)
- CALL check("h5fclose_f",error,total_error)
- ! /* Close remaining IDs */
+ ! Close remaining IDs
CALL h5sclose_f(space_id, error)
CALL check("h5sclose_f",error,total_error)
CALL h5pclose_f(lcpl_id,error)
CALL check("h5pclose_f", error, total_error)
+ ! *********************
+ ! CHECK H5OCOPY_F
+ ! *********************
+
+ DO i = 1, dim0
+ wdata2(i) = i-1
+ ENDDO
+ !
+ ! Create dataspace. Setting size to be the current size.
+ !
+ CALL h5screate_simple_f(1, dims2, space_id, error)
+ CALL check("h5screate_simple_f", error, total_error)
+ !
+ ! Create intermediate groups
+ !
+ CALL h5gcreate_f(file_id,"/G1",group_id,error)
+ CALL check("h5gcreate_f", error, total_error)
+ CALL h5gcreate_f(file_id,"/G1/G2",group_id,error)
+ CALL check("h5gcreate_f", error, total_error)
+ CALL h5gcreate_f(file_id,"/G1/G2/G3",group_id,error)
+ CALL check("h5gcreate_f", error, total_error)
+ !
+ ! Create the dataset
+ !
+ CALL h5dcreate_f(group_id, dataset, H5T_STD_I32LE, space_id, dset_id, error)
+ CALL check("h5dcreate_f", error, total_error)
+ !
+ ! Write the data to the dataset.
+ !
+ CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, wdata2, dims2, error)
+ CALL check("h5dwrite_f", error, total_error)
+ !
+ ! Close and release resources.
+ !
+ CALL h5dclose_f(dset_id , error)
+ CALL check(" h5dclose_f", error, total_error)
+ CALL h5sclose_f(space_id, error)
+ CALL check("h5sclose_f", error, total_error)
+ CALL h5gclose_f(group_id, error)
+ CALL check("h5gclose_f", error, total_error)
+ !
+ ! create property to pass copy options
+ !
+ CALL h5pcreate_f(H5P_LINK_CREATE_F, lcpl_id, error)
+ CALL check("h5Pcreate_f", error, total_error)
+
+ CALL h5pset_create_inter_group_f(lcpl_id, TRUE, error)
+ CALL check("H5Pset_create_inter_group_f", error, total_error)
+ !
+ ! Check optional parameter lcpl_id, this would fail if lcpl_id was not specified
+ !
+ CALL h5ocopy_f(file_id, "/G1/G2/G3/DS1", file_id, "/G1/G_cp1/DS2", error, lcpl_id=lcpl_id)
+ CALL check("h5ocopy_f -- W/ OPTION: lcpl_id", error ,total_error)
+
+ CALL h5pclose_f(lcpl_id, error)
+ CALL check("h5pclose_f",error,total_error)
+
+ CALL h5pcreate_f(H5P_OBJECT_COPY_F, ocpypl_id, error)
+ CALL check("h5Pcreate_f",error,total_error)
+
+ CALL h5pset_copy_object_f(ocpypl_id, H5O_COPY_SHALLOW_HIERARCHY_F, error)
+ CALL check("H5Pset_copy_object_f",error,total_error)
+
+ CALL h5ocopy_f(file_id, "/G1/G2", file_id, "/G1/G_cp2", error, ocpypl_id=ocpypl_id)
+ CALL check("h5ocopy_f",error,total_error)
+
+ ! Makes sure the "DS1" dataset was not copied since we set a
+ ! flag to copy only immediate members of a group.
+ ! Therefore, this should fail.
+ CALL h5dopen_f(file_id, "/G1/G_cp2/DS1", dset_id, error)
+ IF(error.EQ.0)THEN
+ CALL check("h5ocopy_f -- W/ OPTION: ocpypl_id", -1, total_error)
+ ENDIF
+
+ CALL h5pclose_f(ocpypl_id, error)
+ CALL check("h5pclose_f",error,total_error)
+
+ ! create datatype
+ CALL h5tcopy_f(H5T_NATIVE_INTEGER, tid, error)
+ CALL check("h5tcopy_f", error, total_error)
+
+ ! create named datatype
+ CALL h5tcommit_f(file_id, NAME_DATATYPE_SIMPLE, tid, error)
+ CALL check("h5tcommit_f", error, total_error)
+
+ ! close the datatype
+ CALL h5tclose_f(tid, error)
+ CALL check("h5tclose_f",error)
+
+ CALL h5ocopy_f(file_id, NAME_DATATYPE_SIMPLE, file_id, NAME_DATATYPE_SIMPLE2, error)
+ CALL check("h5ocopy_f",error,total_error)
+
+ ! open the datatype for copy
+ CALL h5topen_f(file_id, NAME_DATATYPE_SIMPLE, tid, error)
+ CALL check("h5topen_f",error,total_error)
+
+ ! open the copied datatype
+ CALL h5topen_f(file_id, NAME_DATATYPE_SIMPLE2, tid2, error)
+ CALL check("h5topen_f",error,total_error)
+
+ ! Compare the datatypes
+ CALL h5tequal_f(tid, tid2, flag, error)
+ IF(.NOT.flag)THEN
+ WRITE(*,*) "h5ocopy_f FAILED"
+ total_error = total_error + 1
+ ENDIF
+
+ ! close the destination datatype
+ CALL h5tclose_f(tid, error)
+ CALL check("h5tclose_f",error,total_error)
+
+ ! close the destination datatype
+ CALL h5tclose_f(tid2, error)
+ CALL check("h5tclose_f",error,total_error)
+
+ CALL h5fclose_f(file_id, error)
+ CALL check("h5fclose_f",error,total_error)
+
END SUBROUTINE test_h5o_link
-!/****************************************************************
+!***************************************************************
!**
!** test_h5o_plist(): Test object creation properties
!**
-!****************************************************************/
+!***************************************************************
SUBROUTINE test_h5o_plist(total_error)
@@ -246,31 +376,31 @@ SUBROUTINE test_h5o_plist(total_error)
IMPLICIT NONE
INTEGER, INTENT(OUT) :: total_error
- INTEGER(hid_t) :: fid !/* HDF5 File ID */
- INTEGER(hid_t) :: grp, dset, dtype, dspace !/* Object identifiers */
- INTEGER(hid_t) :: fapl !/* File access property list */
- INTEGER(hid_t) :: gcpl, dcpl, tcpl !/* Object creation properties */
- INTEGER :: def_max_compact, def_min_dense !/* Default phase change parameters */
- INTEGER :: max_compact, min_dense !/* Actual phase change parameters */
- INTEGER :: error !/* Value returned from API calls */
+ INTEGER(hid_t) :: fid ! HDF5 File ID
+ INTEGER(hid_t) :: grp, dset, dtype, dspace ! Object identifiers
+ INTEGER(hid_t) :: fapl ! File access property list
+ INTEGER(hid_t) :: gcpl, dcpl, tcpl ! Object creation properties
+ INTEGER :: def_max_compact, def_min_dense ! Default phase change parameters
+ INTEGER :: max_compact, min_dense ! Actual phase change parameters
+ INTEGER :: error ! Value returned from API calls
CHARACTER(LEN=7), PARAMETER :: TEST_FILENAME = 'test.h5'
! PRINT*,'Testing object creation properties'
- !/* Make a FAPL that uses the "use the latest version of the format" flag */
+ ! Make a FAPL that uses the "use the latest version of the format" flag
CALL H5Pcreate_f(H5P_FILE_ACCESS_F, fapl, error)
CALL check("H5Pcreate_f", error, total_error)
- ! /* Set the "use the latest version of the format" bounds for creating objects in the file */
+ ! Set the "use the latest version of the format" bounds for creating objects in the file
CALL H5Pset_libver_bounds_f(fapl, H5F_LIBVER_LATEST_F, H5F_LIBVER_LATEST_F, error)
CALL check("H5Pcreate_f", error, total_error)
- ! /* Create a new HDF5 file */
+ ! Create a new HDF5 file
CALL H5Fcreate_f(TEST_FILENAME, H5F_ACC_TRUNC_F, fid, error, access_prp=fapl)
CALL check("H5Fcreate_f", error, total_error)
- ! /* Create group, dataset & named datatype creation property lists */
+ ! Create group, dataset & named datatype creation property lists
CALL H5Pcreate_f(H5P_GROUP_CREATE_F, gcpl, error)
CALL check("H5Pcreate_f", error, total_error)
CALL H5Pcreate_f(H5P_DATASET_CREATE_F, dcpl, error)
@@ -278,11 +408,11 @@ SUBROUTINE test_h5o_plist(total_error)
CALL H5Pcreate_f(H5P_DATATYPE_CREATE_F, tcpl, error)
CALL check("H5Pcreate_f", error, total_error)
- ! /* Retrieve default attribute phase change values */
+ ! Retrieve default attribute phase change values
CALL H5Pget_attr_phase_change_f(gcpl, def_max_compact, def_min_dense, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
- ! /* Set non-default attribute phase change values on each creation property list */
+ ! Set non-default attribute phase change values on each creation property list
CALL H5Pset_attr_phase_change_f(gcpl, def_max_compact+1, def_min_dense-1, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
CALL H5Pset_attr_phase_change_f(dcpl, def_max_compact+1, def_min_dense-1, error)
@@ -290,7 +420,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL H5Pset_attr_phase_change_f(tcpl, def_max_compact+1, def_min_dense-1, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
- ! /* Retrieve attribute phase change values on each creation property list and verify */
+ ! Retrieve attribute phase change values on each creation property list and verify
CALL H5Pget_attr_phase_change_f(gcpl, max_compact, min_dense, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", max_compact, (def_max_compact + 1), total_error)
@@ -307,18 +437,18 @@ SUBROUTINE test_h5o_plist(total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", min_dense, (def_min_dense - 1), total_error)
- !/* Create a group, dataset, and committed datatype within the file,
- ! * using the respective type of creation property lists.
- ! */
+ ! Create a group, dataset, and committed datatype within the file,
+ ! using the respective type of creation property lists.
+ !
- !/* Create the group anonymously and link it in */
+ ! Create the group anonymously and link it in
CALL H5Gcreate_anon_f(fid, grp, error, gcpl_id=gcpl)
CALL check("H5Gcreate_anon_f", error, total_error)
CALL H5Olink_f(grp, fid, "group", error)
CALL check("H5Olink_f", error, total_error)
- ! /* Commit the type inside the group anonymously and link it in */
+ ! Commit the type inside the group anonymously and link it in
CALL h5tcopy_f(H5T_NATIVE_INTEGER, dtype, error)
CALL check("h5tcopy_f", error, total_error)
@@ -328,11 +458,11 @@ SUBROUTINE test_h5o_plist(total_error)
CALL H5Olink_f(dtype, fid, "datatype", error)
CALL check("H5Olink_f", error, total_error)
- ! /* Create the dataspace for the dataset. */
+ ! Create the dataspace for the dataset.
CALL h5screate_f(H5S_SCALAR_F, dspace, error)
CALL check("h5screate_f",error,total_error)
- ! /* Create the dataset anonymously and link it in */
+ ! Create the dataset anonymously and link it in
CALL H5Dcreate_anon_f(fid, H5T_NATIVE_INTEGER, dspace, dset, error, dcpl )
CALL check("H5Dcreate_anon_f",error,total_error)
@@ -343,7 +473,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL check("h5sclose_f",error,total_error)
- ! /* Close current creation property lists */
+ ! Close current creation property lists
CALL h5pclose_f(gcpl,error)
CALL check("h5pclose_f", error, total_error)
CALL h5pclose_f(dcpl,error)
@@ -351,7 +481,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL h5pclose_f(tcpl,error)
CALL check("h5pclose_f", error, total_error)
- ! /* Retrieve each object's creation property list */
+ ! Retrieve each object's creation property list
CALL H5Gget_create_plist_f(grp, gcpl, error)
CALL check("H5Gget_create_plist", error, total_error)
@@ -363,7 +493,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL check("H5Dget_create_plist_f", error, total_error)
- ! /* Retrieve attribute phase change values on each creation property list and verify */
+ ! Retrieve attribute phase change values on each creation property list and verify
CALL H5Pget_attr_phase_change_f(gcpl, max_compact, min_dense, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", max_compact, (def_max_compact + 1), total_error)
@@ -380,7 +510,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", min_dense, (def_min_dense - 1), total_error)
- !/* Close current objects */
+ ! Close current objects
CALL h5pclose_f(gcpl,error)
CALL check("h5pclose_f", error, total_error)
@@ -398,11 +528,11 @@ SUBROUTINE test_h5o_plist(total_error)
CALL check("h5dclose_f",error,total_error)
CALL h5fclose_f(fid, error)
CALL check("h5fclose_f",error,total_error)
- ! /* Re-open the file and check that the object creation properties persist */
+ ! Re-open the file and check that the object creation properties persist
CALL h5fopen_f(TEST_FILENAME, H5F_ACC_RDONLY_F, fid, error, access_prp=fapl)
CALL check("H5fopen_f",error,total_error)
- ! /* Re-open objects */
+ ! Re-open objects
CALL H5Gopen_f(fid, "group", grp, error)
CALL check("h5gopen_f", error, total_error)
@@ -412,7 +542,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL H5Dopen_f(fid, "dataset", dset, error)
CALL check("h5dopen_f", error, total_error)
- ! /* Retrieve each object's creation property list */
+ ! Retrieve each object's creation property list
CALL H5Gget_create_plist_f(grp, gcpl, error)
CALL check("H5Gget_create_plist", error, total_error)
@@ -423,7 +553,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL check("H5Dget_create_plist_f", error, total_error)
- ! /* Retrieve attribute phase change values on each creation property list and verify */
+ ! Retrieve attribute phase change values on each creation property list and verify
CALL H5Pget_attr_phase_change_f(gcpl, max_compact, min_dense, error)
CALL check("H5Pget_attr_phase_change_f", error, total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", max_compact, (def_max_compact + 1), total_error)
@@ -440,7 +570,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL VERIFY("H5Pget_attr_phase_change_f", min_dense, (def_min_dense - 1), total_error)
- ! /* Close current objects */
+ ! Close current objects
CALL h5pclose_f(gcpl,error)
CALL check("h5pclose_f", error, total_error)
@@ -459,7 +589,7 @@ SUBROUTINE test_h5o_plist(total_error)
CALL h5fclose_f(fid, error)
CALL check("h5fclose_f",error,total_error)
- ! /* Close the FAPL */
+ ! Close the FAPL
CALL H5Pclose_f(fapl, error)
CALL check("H5Pclose_f", error, total_error)
diff --git a/hl/COPYING b/hl/COPYING
index 6903daf..6903daf 100755..100644
--- a/hl/COPYING
+++ b/hl/COPYING
diff --git a/hl/Makefile.in b/hl/Makefile.in
index 6f7b51c..6f7b51c 100755..100644
--- a/hl/Makefile.in
+++ b/hl/Makefile.in
diff --git a/hl/c++/COPYING b/hl/c++/COPYING
index 6903daf..6903daf 100755..100644
--- a/hl/c++/COPYING
+++ b/hl/c++/COPYING
diff --git a/hl/c++/examples/run-hlc++-ex.sh.in b/hl/c++/examples/run-hlc++-ex.sh.in
index 7742f99..7742f99 100755..100644
--- a/hl/c++/examples/run-hlc++-ex.sh.in
+++ b/hl/c++/examples/run-hlc++-ex.sh.in
diff --git a/hl/c++/src/Makefile.in b/hl/c++/src/Makefile.in
index 6dae65a..9efbd24 100644
--- a/hl/c++/src/Makefile.in
+++ b/hl/c++/src/Makefile.in
@@ -421,7 +421,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
# Include src directory
diff --git a/hl/examples/run-hlc-ex.sh.in b/hl/examples/run-hlc-ex.sh.in
index a82e591..a82e591 100755..100644
--- a/hl/examples/run-hlc-ex.sh.in
+++ b/hl/examples/run-hlc-ex.sh.in
diff --git a/hl/fortran/COPYING b/hl/fortran/COPYING
index 6903daf..6903daf 100755..100644
--- a/hl/fortran/COPYING
+++ b/hl/fortran/COPYING
diff --git a/hl/fortran/examples/run-hlfortran-ex.sh.in b/hl/fortran/examples/run-hlfortran-ex.sh.in
index 2780bff..2780bff 100755..100644
--- a/hl/fortran/examples/run-hlfortran-ex.sh.in
+++ b/hl/fortran/examples/run-hlfortran-ex.sh.in
diff --git a/hl/fortran/src/H5DSfc.c b/hl/fortran/src/H5DSfc.c
index 6816347..3135cfa 100755..100644
--- a/hl/fortran/src/H5DSfc.c
+++ b/hl/fortran/src/H5DSfc.c
@@ -283,7 +283,7 @@ nh5dsget_label_c(hid_t_f *did, int_f *idx, _fcd label, size_t_f *size)
* Convert C name to FORTRAN and place it in the given buffer
*/
- HD5packFstring(c_label, _fcdtocp(label), (size_t)*size+1);
+ HD5packFstring(c_label, _fcdtocp(label), (size_t)*size);
done:
*size = (size_t_f)size_c; /* Don't subtract '1' because H5DSget_label doesn't include the
@@ -332,7 +332,7 @@ nh5dsget_scale_name_c(hid_t_f *did, _fcd name, size_t_f *size)
* Convert C name to FORTRAN and place it in the given buffer
*/
if(size_c != 0) {
- HD5packFstring(c_scale_name, _fcdtocp(name), (size_t)*size+1);
+ HD5packFstring(c_scale_name, _fcdtocp(name), (size_t)*size);
*size = (size_t_f)size_c-1; /* (-1) because we don't include the NULL ending in the length*/
} else {
*size = (size_t_f)size_c; /* if NULL then no name was found */
diff --git a/hl/fortran/src/H5DSff.f90 b/hl/fortran/src/H5DSff.f90
index c3ec587..c3ec587 100755..100644
--- a/hl/fortran/src/H5DSff.f90
+++ b/hl/fortran/src/H5DSff.f90
diff --git a/hl/fortran/src/H5IMfc.c b/hl/fortran/src/H5IMfc.c
index 818096e..818096e 100755..100644
--- a/hl/fortran/src/H5IMfc.c
+++ b/hl/fortran/src/H5IMfc.c
diff --git a/hl/fortran/src/H5IMff.f90 b/hl/fortran/src/H5IMff.f90
index d78dc06..d78dc06 100755..100644
--- a/hl/fortran/src/H5IMff.f90
+++ b/hl/fortran/src/H5IMff.f90
diff --git a/hl/fortran/src/H5LTf90proto.h b/hl/fortran/src/H5LTf90proto.h
index 205871c..8618fc6 100755..100644
--- a/hl/fortran/src/H5LTf90proto.h
+++ b/hl/fortran/src/H5LTf90proto.h
@@ -1140,7 +1140,8 @@ nh5ltget_attribute_string_c(hid_t_f *loc_id,
_fcd dsetname,
int_f *attrnamelen,
_fcd attrname,
- void *buf);
+ _fcd buf,
+ size_t_f *buf_size);
HDF5_HL_F90CSTUBDLL
int_f
diff --git a/hl/fortran/src/H5LTfc.c b/hl/fortran/src/H5LTfc.c
index c0b7695..674636d 100755..100644
--- a/hl/fortran/src/H5LTfc.c
+++ b/hl/fortran/src/H5LTfc.c
@@ -17,8 +17,7 @@
#include "H5LTprivate.h"
#include "H5LTf90proto.h"
-
-
+#include "H5Eprivate.h"
/*-------------------------------------------------------------------------
* Function: H5LTmake_dataset_c
@@ -1719,13 +1718,13 @@ nh5ltget_attribute_string_c(hid_t_f *loc_id,
_fcd dsetname,
int_f *attrnamelen,
_fcd attrname,
- void *buf)
+ _fcd buf, size_t_f *buf_size)
{
int ret_value = -1;
herr_t ret;
- hid_t c_loc_id;
char *c_name = NULL;
char *c_attrname = NULL;
+ char *c_buf = NULL;
int c_namelen;
int c_attrnamelen;
@@ -1741,26 +1740,33 @@ nh5ltget_attribute_string_c(hid_t_f *loc_id,
c_attrname = (char *)HD5f2cstring(attrname, c_attrnamelen);
if (c_attrname == NULL)
goto done;
-
/*
- * Call H5LTget_attribute_int function.
- */
- c_loc_id = (hid_t)*loc_id;
-
- ret = H5LTget_attribute_string(c_loc_id,c_name,c_attrname,buf);
+ * Allocate buffer to hold C attribute string
+ */
+ if ((c_buf = HDmalloc((size_t)*buf_size + 1)) == NULL)
+ goto done;
+ /*
+ * Call H5LTget_attribute_int function.
+ */
+ ret = H5LTget_attribute_string((hid_t)*loc_id,c_name,c_attrname,c_buf);
if (ret < 0)
goto done;
- ret_value = 0;
+ /*
+ * Convert C name to FORTRAN and place it in the given buffer
+ */
+ HD5packFstring(c_buf, _fcdtocp(buf), (size_t)*buf_size);
+ ret_value = 0;
done:
if(c_name!=NULL)
free(c_name);
if(c_attrname!=NULL)
free(c_attrname);
-
+ if(c_buf!=NULL)
+ free(c_buf);
return ret_value;
}
@@ -2157,7 +2163,7 @@ nh5ltpath_valid_c(hid_t_f *loc_id,
/*
* convert FORTRAN name to C name
*/
- if( NULL == (c_path = (char *)HD5f2cstring(path, (int)*pathlen)))
+ if( NULL == (c_path = (char *)HD5f2cstring(path, (size_t)*pathlen)))
goto done;
check_object_valid = FALSE;
diff --git a/hl/fortran/src/H5LTff.f90 b/hl/fortran/src/H5LTff.f90
index 7d53ab7..0302b61 100755..100644
--- a/hl/fortran/src/H5LTff.f90
+++ b/hl/fortran/src/H5LTff.f90
@@ -5969,9 +5969,10 @@ CONTAINS
CHARACTER(len=*), INTENT(inout) :: buf ! data buffer
INTEGER :: namelen ! name length
INTEGER :: attrlen ! name length
+ INTEGER(size_t) :: buf_size ! buf size
INTERFACE
- INTEGER FUNCTION h5ltget_attribute_string_c(loc_id,namelen,dset_name,attrlen,attr_name,buf)
+ INTEGER FUNCTION h5ltget_attribute_string_c(loc_id,namelen,dset_name,attrlen,attr_name,buf,buf_size)
USE h5global
!DEC$IF DEFINED(HDF5F90_WINDOWS)
!DEC$ATTRIBUTES C,reference,decorate,alias:'H5LTGET_ATTRIBUTE_STRING_C'::h5ltget_attribute_string_c
@@ -5984,12 +5985,15 @@ CONTAINS
CHARACTER(len=*), INTENT(in) :: dset_name ! name of the dataset
CHARACTER(len=*), INTENT(in) :: attr_name ! name of the attribute
CHARACTER(len=*), INTENT(inout) :: buf ! data buffer
+ INTEGER(size_t) :: buf_size ! data buffer size
END FUNCTION h5ltget_attribute_string_c
END INTERFACE
namelen = LEN(dset_name)
attrlen = LEN(attr_name)
- errcode = h5ltget_attribute_string_c(loc_id,namelen,dset_name,attrlen,attr_name,buf)
+ buf_size = LEN(buf)
+
+ errcode = h5ltget_attribute_string_c(loc_id,namelen,dset_name,attrlen,attr_name,buf,buf_size)
END SUBROUTINE h5ltget_attribute_string_f
@@ -6335,7 +6339,7 @@ CONTAINS
!DEC$attributes dllexport :: h5ltpath_valid_f
!DEC$endif
!
- INTEGER(hid_t) , INTENT(IN) :: loc_id ! File or group identifier.
+ INTEGER(hid_t) , INTENT(IN) :: loc_id ! An identifier of an object in the file.
CHARACTER(LEN=*), INTENT(IN) :: path ! Path to the object to check, relative to loc_id.
LOGICAL , INTENT(IN) :: check_object_valid ! Indicates whether to check if the final component
! of the path resolves to a valid object
@@ -6360,14 +6364,16 @@ CONTAINS
END FUNCTION h5ltpath_valid_c
END INTERFACE
+ ! Initialize
+ path_valid = .FALSE.
+ errcode = 0
+
check_object_valid_c = 0
IF(check_object_valid) check_object_valid_c = 1
pathlen = LEN(path)
status = h5ltpath_valid_c(loc_id, path, pathlen, check_object_valid_c)
- path_valid = .FALSE.
- errcode = 0
IF(status.EQ.1)THEN
path_valid = .TRUE.
ELSE IF(status.LT.0)THEN
diff --git a/hl/fortran/src/H5TBfc.c b/hl/fortran/src/H5TBfc.c
index 0efc9a8..0efc9a8 100755..100644
--- a/hl/fortran/src/H5TBfc.c
+++ b/hl/fortran/src/H5TBfc.c
diff --git a/hl/fortran/src/H5TBff.f90 b/hl/fortran/src/H5TBff.f90
index 36e13f9..36e13f9 100755..100644
--- a/hl/fortran/src/H5TBff.f90
+++ b/hl/fortran/src/H5TBff.f90
diff --git a/hl/fortran/src/Makefile.in b/hl/fortran/src/Makefile.in
index 62d7309..afefdc7 100644
--- a/hl/fortran/src/Makefile.in
+++ b/hl/fortran/src/Makefile.in
@@ -436,7 +436,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/hl/src -I$(top_builddir)/hl/src \
-I$(top_srcdir)/fortran/src -I$(top_builddir)/fortran/src
diff --git a/hl/fortran/test/tstds.f90 b/hl/fortran/test/tstds.f90
index 8817989..c73e1c4 100644
--- a/hl/fortran/test/tstds.f90
+++ b/hl/fortran/test/tstds.f90
@@ -186,7 +186,10 @@ SUBROUTINE test_testds(err)
name_len = 25
name = ''
CALL H5DSget_scale_name_f(dsid, name, name_len, err)
- IF(err.LT.0.OR.name_len.NE.21.OR.TRIM(name).NE."Dimension Scale Set 1")THEN
+ IF(err.LT.0 .OR. &
+ name_len.NE.21 .OR. &
+ TRIM(name).NE."Dimension Scale Set 1" .OR. &
+ name(22:25).NE.' ')THEN
err = FAILED
CALL write_test_status(err)
RETURN
@@ -293,7 +296,10 @@ SUBROUTINE test_testds(err)
label_len = 25
label = ''
CALL H5DSget_label_f(did, DIM2, label, label_len, err)
- IF(err.LT.0.OR.label(1:label_len).NE."Label12".OR.label_len.NE.7)THEN
+ IF(err.LT.0.OR. &
+ label(1:label_len).NE."Label12" .OR. &
+ label_len.NE.7 .OR. &
+ label(8:25).NE.' ')THEN
err = FAILED
CALL write_test_status(err)
RETURN
diff --git a/hl/fortran/test/tstimage.f90 b/hl/fortran/test/tstimage.f90
index 3794bbf..3794bbf 100755..100644
--- a/hl/fortran/test/tstimage.f90
+++ b/hl/fortran/test/tstimage.f90
diff --git a/hl/fortran/test/tstlite.f90 b/hl/fortran/test/tstlite.f90
index 9329dba..0b5a138 100644
--- a/hl/fortran/test/tstlite.f90
+++ b/hl/fortran/test/tstlite.f90
@@ -1342,7 +1342,9 @@ SUBROUTINE test_attributes()
IMPLICIT NONE
CHARACTER(len=9), PARAMETER :: filename = "dsetf5.h5"! File name
+ CHARACTER(len=9), PARAMETER :: filename1 ="tattr.h5" ! C written attribute file
INTEGER(HID_T) :: file_id ! File identifier
+ INTEGER(HID_T) :: file_id1
INTEGER, PARAMETER :: DIM1 = 10; ! Dimension of array
CHARACTER(LEN=5), PARAMETER :: attrname1 = "attr1" ! Attribute name
CHARACTER(LEN=5), PARAMETER :: attrname2 = "attr2" ! Attribute name
@@ -1350,9 +1352,11 @@ SUBROUTINE test_attributes()
CHARACTER(LEN=5), PARAMETER :: attrname4 = "attr4" ! Attribute name
CHARACTER(LEN=5), PARAMETER :: attrname5 = "attr5" ! Attribute name
CHARACTER(LEN=8), PARAMETER :: buf1 = "mystring" ! Data buffer
+ CHARACTER(LEN=16), PARAMETER :: buf_c = "string attribute"
CHARACTER(LEN=8) :: bufr1 ! Data buffer
CHARACTER(LEN=10) :: bufr1_lg ! Data buffer
- CHARACTER(LEN=6) :: bufr1_sm ! Data buffer
+ CHARACTER(LEN=16) :: bufr_c ! Data buffer
+ CHARACTER(LEN=18) :: bufr_c_lg ! Data buffer
INTEGER, DIMENSION(DIM1) :: buf2 ! Data buffer
INTEGER, DIMENSION(DIM1) :: bufr2 ! Data buffer
REAL, DIMENSION(DIM1) :: buf3 ! Data buffer
@@ -1370,6 +1374,7 @@ SUBROUTINE test_attributes()
INTEGER :: rank = 1 ! Dataset rank
CHARACTER(LEN=5), PARAMETER :: dsetname1 = "dset1" ! Dataset name
INTEGER, DIMENSION(DIM1) :: buf ! Data buffer
+
!
! Initialize FORTRAN predefined datatypes.
@@ -1488,15 +1493,12 @@ SUBROUTINE test_attributes()
CALL passed()
-
-
!-------------------------------------------------------------------------
! string
!-------------------------------------------------------------------------
CALL test_begin(' Set/Get attributes string ')
-
!
! write attribute.
!
@@ -1530,19 +1532,36 @@ SUBROUTINE test_attributes()
STOP
ENDIF
- !
- ! read attribute into a fortran character buf that is smaller then buf1.
- !
- CALL h5ltget_attribute_string_f(file_id,dsetname1,attrname5,bufr1_sm,errcode)
-
- !
- ! compare read and write buffers.
- !
- IF ( buf1(1:6) .NE. bufr1_sm(1:6) ) THEN
- PRINT *, 'smaller read buffer differs from write buffer'
- PRINT *, buf1, ' and ', bufr1_sm
- STOP
- ENDIF
+ !
+ ! ** Test reading a string that was created with a C program **
+ !
+
+!!$ CALL h5fopen_f(filename1, H5F_ACC_RDONLY_F, file_id1, errcode)
+!!$
+!!$ CALL h5ltget_attribute_string_f(file_id1, "/", "attr5", bufr_c, errcode)
+!!$ !
+!!$ ! compare read and write buffers.
+!!$ !
+!!$ IF ( bufr_c .NE. buf_c ) THEN
+!!$ PRINT *, 'read buffer differs from write buffer'
+!!$ PRINT *, bufr1, ' and ', buf_c
+!!$ STOP
+!!$ ENDIF
+!!$ !
+!!$ ! read attribute into a fortran character buf that is larger then buf_c.
+!!$ !
+!!$ CALL h5ltget_attribute_string_f(file_id1, "/", "attr5", bufr_c_lg, errcode)
+!!$
+!!$ !
+!!$ ! compare read and write buffers, make sure C NULL character was removed.
+!!$ !
+!!$ IF ( buf_c(1:16) .NE. bufr_c_lg(1:16) .AND. bufr_c_lg(17:18) .NE. ' ' ) THEN
+!!$ PRINT *, 'larger read buffer differs from write buffer'
+!!$ PRINT *, buf_c, ' and ', bufr_c_lg
+!!$ STOP
+!!$ ENDIF
+
+!!$ CALL h5fclose_f(file_id1, errcode)
CALL passed()
diff --git a/hl/fortran/test/tsttable.f90 b/hl/fortran/test/tsttable.f90
index 66ec5c6..66ec5c6 100755..100644
--- a/hl/fortran/test/tsttable.f90
+++ b/hl/fortran/test/tsttable.f90
diff --git a/hl/src/COPYING b/hl/src/COPYING
index 6903daf..6903daf 100755..100644
--- a/hl/src/COPYING
+++ b/hl/src/COPYING
diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c
index eeaceeb..678642f 100644
--- a/hl/src/H5LT.c
+++ b/hl/src/H5LT.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
+
#include "H5LTprivate.h"
#include "H5private.h"
@@ -31,7 +32,461 @@ char *myinput;
size_t indent = 0;
+/* File Image operations
+
+ A file image is a representation of an HDF5 file in a memory
+ buffer. In order to perform operations on an image in a similar way
+ to a file, the application buffer is copied to a FAPL buffer, which
+ in turn is copied to a VFD buffer. Buffer copying can decrease
+ performance, especially when using large file images. A solution to
+ this issue is to simulate the copying of the application buffer,
+ when actually the same buffer is used for the FAPL and the VFD.
+ This is implemented by using callbacks that simulate the standard
+ functions for memory management (additional callbacks are used for
+ the management of associated data structures). From the application
+ standpoint, a file handle can be obtained from a file image by using
+ the API routine H5LTopen_file_image(). This function takes a flag
+ argument that indicates the HDF5 library how to handle the given image;
+ several flag values can be combined by using the bitwise OR operator.
+ Valid flag values include:
+
+ H5LT_FILE_IMAGE_OPEN_RW indicates the HDF5 library to open the file
+ image in read/write mode. Default is read-only mode.
+
+ H5LT_FILE_IMAGE_DONT_COPY indicates the HDF5 library to not copy the
+ supplied user buffer; the same buffer will be handled by the FAPL and
+ the VFD driver. Default operation copies the user buffer to the FAPL and
+ VFD driver.
+
+ H5LT_FILE_IMAGE_DONT_RELEASE indicates the HDF5 library to not release
+ the buffer handled by the FAPL and the VFD upon closing. This flag value
+ is only applicable when the flag value H5LT_FILE_IMAGE_DONT_COPY is set as
+ well. The application is responsible to release the image buffer.
+*/
+
+/* Data structure to pass application data to callbacks. */
+typedef struct {
+ void *app_image_ptr; /* Pointer to application buffer */
+ size_t app_image_size; /* Size of application buffer */
+ void *fapl_image_ptr; /* Pointer to FAPL buffer */
+ size_t fapl_image_size; /* Size of FAPL buffer */
+ int fapl_ref_count; /* Reference counter for FAPL buffer */
+ void *vfd_image_ptr; /* Pointer to VFD buffer */
+ size_t vfd_image_size; /* Size of VFD buffer */
+ int vfd_ref_count; /* Reference counter for VFD buffer */
+ unsigned flags; /* Flags indicate how the file image will */
+ /* be open */
+ int ref_count; /* Reference counter on udata struct */
+} H5LT_file_image_ud_t;
+
+/* callbacks prototypes for file image ops */
+static void *image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *udata);
+static void *image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
+static void *image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *udata);
+static herr_t image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *udata);
+static void *udata_copy(void *udata);
+static herr_t udata_free(void *udata);
+
+/* Definition of callbacks for file image operations. */
+
+
+/*-------------------------------------------------------------------------
+* Function: image_malloc
+*
+* Purpose: Simulates malloc() function to avoid copying file images.
+* The application buffer is set to the buffer on only one FAPL.
+* Then the FAPL buffer can be copied to other FAPL buffers or
+* to only one VFD buffer.
+*
+* Return: Address of "allocated" buffer, if successful. Otherwise, it returns
+* NULL.
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static void *
+image_malloc(size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+ void * return_value = NULL;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+
+ switch ( file_image_op ) {
+ /* the app buffer is "copied" to only one FAPL. Afterwards, FAPLs can be "copied" */
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
+ if (udata->app_image_ptr == NULL)
+ goto out;
+ if (udata->app_image_size != size)
+ goto out;
+ if (udata->fapl_image_ptr != NULL)
+ goto out;
+ if (udata->fapl_image_size != 0)
+ goto out;
+ if (udata->fapl_ref_count != 0)
+ goto out;
+
+ udata->fapl_image_ptr = udata->app_image_ptr;
+ udata->fapl_image_size = udata->app_image_size;
+ return_value = udata->fapl_image_ptr;
+ udata->fapl_ref_count++;
+ break;
+
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
+ if (udata->fapl_image_ptr == NULL)
+ goto out;
+ if (udata->fapl_image_size != size)
+ goto out;
+ if (udata->fapl_ref_count == 0)
+ goto out;
+ return_value = udata->fapl_image_ptr;
+ udata->fapl_ref_count++;
+ break;
+
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
+ goto out;
+
+ case H5FD_FILE_IMAGE_OP_FILE_OPEN:
+ /* FAPL buffer is "copied" to only one VFD buffer */
+ if (udata->vfd_image_ptr != NULL)
+ goto out;
+ if (udata->vfd_image_size != 0)
+ goto out;
+ if (udata->vfd_ref_count != 0)
+ goto out;
+ if (udata->fapl_image_ptr == NULL)
+ goto out;
+ if (udata->fapl_image_size != size)
+ goto out;
+ if (udata->fapl_ref_count == 0)
+ goto out;
+
+ udata->vfd_image_ptr = udata->fapl_image_ptr;
+ udata->vfd_image_size = size;
+ udata->vfd_ref_count++;
+ return_value = udata->vfd_image_ptr;
+ break;
+
+ /* added unused labels to shut the compiler up */
+ case H5FD_FILE_IMAGE_OP_NO_OP:
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
+ case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
+ case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
+ default:
+ goto out;
+ } /* end switch */
+
+ return(return_value);
+
+out:
+ return NULL;
+} /* end image_malloc() */
+
+
+/*-------------------------------------------------------------------------
+* Function: image_memcpy
+*
+* Purpose: Simulates memcpy() function to avoid copying file images.
+* The image buffer can be set to only one FAPL buffer, and
+* "copied" to only one VFD buffer. The FAPL buffer can be
+* "copied" to other FAPLs buffers.
+*
+* Return: The address of the destination buffer, if successful. Otherwise, it
+* returns NULL.
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static void *
+image_memcpy(void *dest, const void *src, size_t size, H5FD_file_image_op_t file_image_op,
+ void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+
+ switch(file_image_op) {
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
+ if (dest != udata->fapl_image_ptr)
+ goto out;
+ if (src != udata->app_image_ptr)
+ goto out;
+ if (size != udata->fapl_image_size)
+ goto out;
+ if (size != udata->app_image_size)
+ goto out;
+ if (udata->fapl_ref_count == 0)
+ goto out;
+ break;
+
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
+ if (dest != udata->fapl_image_ptr)
+ goto out;
+ if (src != udata->fapl_image_ptr)
+ goto out;
+ if (size != udata->fapl_image_size)
+ goto out;
+ if (udata->fapl_ref_count < 2)
+ goto out;
+ break;
+
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
+ goto out;
+
+ case H5FD_FILE_IMAGE_OP_FILE_OPEN:
+ if (dest != udata->vfd_image_ptr)
+ goto out;
+ if (src != udata->fapl_image_ptr)
+ goto out;
+ if (size != udata->vfd_image_size)
+ goto out;
+ if (size != udata->fapl_image_size)
+ goto out;
+ if (udata->fapl_ref_count == 0)
+ goto out;
+ if (udata->vfd_ref_count != 1)
+ goto out;
+ break;
+
+ /* added unused labels to shut the compiler up */
+ case H5FD_FILE_IMAGE_OP_NO_OP:
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
+ case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
+ case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
+ default:
+ goto out;
+ } /* end switch */
+
+ return(dest);
+
+out:
+ return NULL;
+} /* end image_memcpy() */
+
+
+/*-------------------------------------------------------------------------
+* Function: image_realloc
+*
+* Purpose: Reallocates the shared application image buffer and updates data
+* structures that manage buffer "copying".
+*
+* Return: Address of reallocated buffer, if successful. Otherwise, it returns
+* NULL.
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static void *
+image_realloc(void *ptr, size_t size, H5FD_file_image_op_t file_image_op, void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+ void * return_value = NULL;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+
+ /* realloc() is not allowed when the HDF5 library won't release the image
+ buffer because reallocation may change the address of the buffer. The
+ new address cannot be communicated to the application to release it. */
+ if (udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)
+ goto out;
+
+ /* realloc() is not allowed if the image is open in read-only mode */
+ if (!(udata->flags & H5LT_FILE_IMAGE_OPEN_RW))
+ goto out;
+
+ if (file_image_op == H5FD_FILE_IMAGE_OP_FILE_RESIZE) {
+ if (udata->vfd_image_ptr != ptr)
+ goto out;
+
+ if (udata->vfd_ref_count != 1)
+ goto out;
+
+ if (NULL == (udata->vfd_image_ptr = HDrealloc(ptr, size)))
+ goto out;
+
+ udata->vfd_image_size = size;
+ return_value = udata->vfd_image_ptr;
+ } /* end if */
+ else
+ goto out;
+
+ return(return_value);
+
+out:
+ return NULL;
+} /* end image_realloc() */
+
+
+/*-------------------------------------------------------------------------
+* Function: image_free
+*
+* Purpose: Simulates deallocation of FAPL and VFD buffers by decreasing
+* reference counters. Shared application buffer is actually
+* deallocated if there are no outstanding references.
+*
+* Return: SUCCEED or FAIL
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static herr_t
+image_free(void *ptr, H5FD_file_image_op_t file_image_op, void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+
+ switch(file_image_op) {
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE:
+ if (udata->fapl_image_ptr != ptr)
+ goto out;
+ if (udata->fapl_ref_count == 0)
+ goto out;
+
+ udata->fapl_ref_count--;
+
+ /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
+ if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
+ !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
+ HDfree(udata->fapl_image_ptr);
+ udata->app_image_ptr = NULL;
+ udata->fapl_image_ptr = NULL;
+ udata->vfd_image_ptr = NULL;
+ } /* end if */
+ break;
+
+ case H5FD_FILE_IMAGE_OP_FILE_CLOSE:
+ if (udata->vfd_image_ptr != ptr)
+ goto out;
+ if (udata->vfd_ref_count != 1)
+ goto out;
+
+ udata->vfd_ref_count--;
+
+ /* release the shared buffer only if indicated by the respective flag and there are no outstanding references */
+ if (udata->fapl_ref_count == 0 && udata->vfd_ref_count == 0 &&
+ !(udata->flags & H5LT_FILE_IMAGE_DONT_RELEASE)) {
+ HDfree(udata->vfd_image_ptr);
+ udata->app_image_ptr = NULL;
+ udata->fapl_image_ptr = NULL;
+ udata->vfd_image_ptr = NULL;
+ } /* end if */
+ break;
+
+ /* added unused labels to keep the compiler quite */
+ case H5FD_FILE_IMAGE_OP_NO_OP:
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET:
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY:
+ case H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET:
+ case H5FD_FILE_IMAGE_OP_FILE_OPEN:
+ case H5FD_FILE_IMAGE_OP_FILE_RESIZE:
+ default:
+ goto out;
+ } /* end switch */
+
+ return(SUCCEED);
+
+out:
+ return(FAIL);
+} /* end image_free() */
+
+
+/*-------------------------------------------------------------------------
+* Function: udata_copy
+*
+* Purpose: Simulates the copying of the user data structure utilized in the
+* management of the "copying" of file images.
+*
+* Return: Address of "newly allocated" structure, if successful. Otherwise, it
+* returns NULL.
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static void *
+udata_copy(void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+ if (udata->ref_count == 0)
+ goto out;
+
+ udata->ref_count++;
+
+ return(udata);
+
+out:
+ return NULL;
+} /* end udata_copy */
+
+
+/*-------------------------------------------------------------------------
+* Function: udata_free
+*
+* Purpose: Simulates deallocation of the user data structure utilized in the
+* management of the "copying" of file images. The data structure is
+* actually deallocated when there are no outstanding references.
+*
+* Return: SUCCEED or FAIL
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static herr_t
+udata_free(void *_udata)
+{
+ H5LT_file_image_ud_t *udata = (H5LT_file_image_ud_t *)_udata;
+
+ /* callback is only used if the application buffer is not actually copied */
+ if (!(udata->flags & H5LT_FILE_IMAGE_DONT_COPY))
+ goto out;
+ if (udata->ref_count == 0)
+ goto out;
+
+ udata->ref_count--;
+
+ /* checks that there are no references outstanding before deallocating udata */
+ if (udata->ref_count == 0 && udata->fapl_ref_count == 0 &&
+ udata->vfd_ref_count == 0)
+ HDfree(udata);
+
+ return(SUCCEED);
+
+out:
+ return(FAIL);
+} /* end udata_free */
+
+/* End of callbacks definitions for file image operations */
/*-------------------------------------------------------------------------
*
@@ -388,6 +843,120 @@ out:
return -1;
}
+
+/*-------------------------------------------------------------------------
+* Function: H5LTopen_file_image
+*
+* Purpose: Open a user supplied file image using the core file driver.
+*
+* Return: File identifier, Failure: -1
+*
+* Programmer: Christian Chilan
+*
+* Date: October 3, 2011
+*
+*-------------------------------------------------------------------------
+*/
+hid_t H5LTopen_file_image(void *buf_ptr, size_t buf_size, unsigned flags)
+{
+ hid_t fapl, file_id; /* HDF5 identifiers */
+ unsigned file_open_flags;/* Flags for image open */
+ char file_name[64]; /* Filename buffer */
+ size_t alloc_incr; /* Buffer allocation increment */
+ size_t min_incr = 65536; /* Minimum buffer increment */
+ double buf_prcnt = 0.1f; /* Percentage of buffer size to set
+ as increment */
+ static long file_name_counter;
+ H5FD_file_image_callbacks_t callbacks = {&image_malloc, &image_memcpy,
+ &image_realloc, &image_free,
+ &udata_copy, &udata_free,
+ (void *)NULL};
+
+ /* check arguments */
+ if (buf_ptr == NULL)
+ goto out;
+ if (buf_size == 0)
+ goto out;
+ if (flags & (unsigned)~(H5LT_FILE_IMAGE_ALL))
+ goto out;
+
+ /* Create FAPL to transmit file image */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ goto out;
+
+ /* set allocation increment to a percentage of the supplied buffer size, or
+ * a pre-defined minimum increment value, whichever is larger
+ */
+ if ((buf_prcnt * buf_size) > min_incr)
+ alloc_incr = (size_t)(buf_prcnt * buf_size);
+ else
+ alloc_incr = min_incr;
+
+ /* Configure FAPL to use the core file driver */
+ if (H5Pset_fapl_core(fapl, alloc_incr, FALSE) < 0)
+ goto out;
+
+ /* Set callbacks for file image ops ONLY if the file image is NOT copied */
+ if (flags & H5LT_FILE_IMAGE_DONT_COPY) {
+ H5LT_file_image_ud_t *udata; /* Pointer to udata structure */
+
+ /* Allocate buffer to communicate user data to callbacks */
+ if (NULL == (udata = (H5LT_file_image_ud_t *)HDmalloc(sizeof(H5LT_file_image_ud_t))))
+ goto out;
+
+ /* Initialize udata with info about app buffer containing file image and flags */
+ udata->app_image_ptr = buf_ptr;
+ udata->app_image_size = buf_size;
+ udata->fapl_image_ptr = NULL;
+ udata->fapl_image_size = 0;
+ udata->fapl_ref_count = 0;
+ udata->vfd_image_ptr = NULL;
+ udata->vfd_image_size = 0;
+ udata->vfd_ref_count = 0;
+ udata->flags = flags;
+ udata->ref_count = 1; /* corresponding to the first FAPL */
+
+ /* copy address of udata into callbacks */
+ callbacks.udata = (void *)udata;
+
+ /* Set file image callbacks */
+ if (H5Pset_file_image_callbacks(fapl, &callbacks) < 0) {
+ HDfree(udata);
+ goto out;
+ } /* end if */
+ } /* end if */
+
+ /* Assign file image in user buffer to FAPL */
+ if (H5Pset_file_image(fapl, buf_ptr, buf_size) < 0)
+ goto out;
+
+ /* set file open flags */
+ if (flags & H5LT_FILE_IMAGE_OPEN_RW)
+ file_open_flags = H5F_ACC_RDWR;
+ else
+ file_open_flags = H5F_ACC_RDONLY;
+
+ /* define a unique file name */
+ HDsnprintf(file_name, (sizeof(file_name) - 1), "file_image_%ld", file_name_counter++);
+
+ /* Assign file image in FAPL to the core file driver */
+ if ((file_id = H5Fopen(file_name, file_open_flags, fapl)) < 0)
+ goto out;
+
+ /* Close FAPL */
+ if (H5Pclose(fapl) < 0)
+ goto out;
+
+ /* Return file identifier */
+ return file_id;
+
+out:
+ H5E_BEGIN_TRY {
+ H5Pclose(fapl);
+ } H5E_END_TRY;
+ return -1;
+} /* end H5LTopen_file_image() */
+
/*-------------------------------------------------------------------------
* Function: H5LT_read_dataset
@@ -1801,7 +2370,7 @@ print_enum(hid_t type, char* str, size_t *str_len, hbool_t no_ubuf, size_t indt)
out:
if(0 == nmembs) {
- HDsnprintf(tmp_str, TMP_LEN, "\n%*s <empty>", indt + 4, "");
+ HDsnprintf(tmp_str, TMP_LEN, "\n%*s <empty>", (int)(indt + 4), "");
str = realloc_and_append(no_ubuf, str_len, str, tmp_str);
} /* end if */
diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h
index 6efae68..929c6bd 100644
--- a/hl/src/H5LTpublic.h
+++ b/hl/src/H5LTpublic.h
@@ -16,6 +16,15 @@
#ifndef _H5LTpublic_H
#define _H5LTpublic_H
+/* Flag definitions for H5LTopen_file_image() */
+#define H5LT_FILE_IMAGE_OPEN_RW 0x0001 /* Open image for read-write */
+#define H5LT_FILE_IMAGE_DONT_COPY 0x0002 /* The HDF5 lib won't copy */
+/* user supplied image buffer. The same image is open with the core driver. */
+#define H5LT_FILE_IMAGE_DONT_RELEASE 0x0004 /* The HDF5 lib won't */
+/* deallocate user supplied image buffer. The user application is reponsible */
+/* for doing so. */
+#define H5LT_FILE_IMAGE_ALL 0x0007
+
typedef enum H5LT_lang_t {
H5LT_LANG_ERR = -1, /*this is the first*/
H5LT_DDL = 0, /*for DDL*/
@@ -344,6 +353,15 @@ H5_HLDLL herr_t H5LTfind_attribute( hid_t loc_id, const char *name );
H5_HLDLL htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid);
+/*-------------------------------------------------------------------------
+ *
+ * File image operations functions
+ *
+ *-------------------------------------------------------------------------
+ */
+
+H5_HLDLL hid_t H5LTopen_file_image(void *buf_ptr, size_t buf_size, unsigned flags);
+
#ifdef __cplusplus
}
#endif
diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in
index 2623b3a..f4875bd 100644
--- a/hl/src/Makefile.in
+++ b/hl/src/Makefile.in
@@ -420,7 +420,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
# This library is our main target.
diff --git a/hl/test/Makefile.am b/hl/test/Makefile.am
index 86e3318..76c6f90 100644
--- a/hl/test/Makefile.am
+++ b/hl/test/Makefile.am
@@ -29,7 +29,7 @@ LDADD=$(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
# Test programs. These are our main targets. They should be listed in the
# order to be executed, generally most specific tests to least specific tests.
-TEST_PROG=test_lite test_image test_table test_ds test_packet
+TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet
check_PROGRAMS=$(TEST_PROG)
# These programs generate test files for the tests. They don't need to be
@@ -45,7 +45,7 @@ endif
# Temporary files. These files are the ones created by running `make test'.
CHECK_CLEANFILES+=combine_tables[1-2].h5 test_ds[1-9].h5 test_image[1-3].h5 \
- test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
+ file_img[1-2].h5 test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
test_packet_compress.h5 test_detach.h5
include $(top_srcdir)/config/conclude.am
diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in
index 6aa5a2a..b7548ec 100644
--- a/hl/test/Makefile.in
+++ b/hl/test/Makefile.in
@@ -69,7 +69,8 @@ CONFIG_HEADER = $(top_builddir)/src/H5config.h
CONFIG_CLEAN_FILES = H5srcdir_str.h
CONFIG_CLEAN_VPATH_FILES =
am__EXEEXT_1 = test_lite$(EXEEXT) test_image$(EXEEXT) \
- test_table$(EXEEXT) test_ds$(EXEEXT) test_packet$(EXEEXT)
+ test_file_image$(EXEEXT) test_table$(EXEEXT) test_ds$(EXEEXT) \
+ test_packet$(EXEEXT)
am__EXEEXT_2 = gen_test_ds$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
gen_test_ds_SOURCES = gen_test_ds.c
@@ -83,6 +84,10 @@ test_ds_SOURCES = test_ds.c
test_ds_OBJECTS = test_ds.$(OBJEXT)
test_ds_LDADD = $(LDADD)
test_ds_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
+test_file_image_SOURCES = test_file_image.c
+test_file_image_OBJECTS = test_file_image.$(OBJEXT)
+test_file_image_LDADD = $(LDADD)
+test_file_image_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
test_image_SOURCES = test_image.c
test_image_OBJECTS = test_image.$(OBJEXT)
test_image_LDADD = $(LDADD)
@@ -125,10 +130,10 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
-SOURCES = gen_test_ds.c test_ds.c test_image.c test_lite.c \
- test_packet.c test_table.c
-DIST_SOURCES = gen_test_ds.c test_ds.c test_image.c test_lite.c \
- test_packet.c test_table.c
+SOURCES = gen_test_ds.c test_ds.c test_file_image.c test_image.c \
+ test_lite.c test_packet.c test_table.c
+DIST_SOURCES = gen_test_ds.c test_ds.c test_file_image.c test_image.c \
+ test_lite.c test_packet.c test_table.c
ETAGS = etags
CTAGS = ctags
am__tty_colors = \
@@ -422,16 +427,16 @@ TRACE = perl $(top_srcdir)/bin/trace
# Temporary files. These files are the ones created by running `make test'.
CHECK_CLEANFILES = *.chkexe *.chklog *.clog combine_tables[1-2].h5 \
- test_ds[1-9].h5 test_image[1-3].h5 test_lite[1-2].h5 \
- test_table.h5 test_packet_table.h5 test_packet_compress.h5 \
- test_detach.h5
+ test_ds[1-9].h5 test_image[1-3].h5 file_img[1-2].h5 \
+ test_lite[1-2].h5 test_table.h5 test_packet_table.h5 \
+ test_packet_compress.h5 test_detach.h5
# The tests depend on the hdf5, hdf5 test, and hdf5_hl libraries
LDADD = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5)
# Test programs. These are our main targets. They should be listed in the
# order to be executed, generally most specific tests to least specific tests.
-TEST_PROG = test_lite test_image test_table test_ds test_packet
+TEST_PROG = test_lite test_image test_file_image test_table test_ds test_packet
# These programs generate test files for the tests. They don't need to be
# compiled every time we want to test the library. However, putting
@@ -515,6 +520,9 @@ gen_test_ds$(EXEEXT): $(gen_test_ds_OBJECTS) $(gen_test_ds_DEPENDENCIES)
test_ds$(EXEEXT): $(test_ds_OBJECTS) $(test_ds_DEPENDENCIES)
@rm -f test_ds$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_ds_OBJECTS) $(test_ds_LDADD) $(LIBS)
+test_file_image$(EXEEXT): $(test_file_image_OBJECTS) $(test_file_image_DEPENDENCIES)
+ @rm -f test_file_image$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_file_image_OBJECTS) $(test_file_image_LDADD) $(LIBS)
test_image$(EXEEXT): $(test_image_OBJECTS) $(test_image_DEPENDENCIES)
@rm -f test_image$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_image_OBJECTS) $(test_image_LDADD) $(LIBS)
@@ -536,6 +544,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_test_ds.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ds.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_file_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lite.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@
diff --git a/hl/test/h5hltest.h b/hl/test/h5hltest.h
index 466a0e1..809c4ec 100644
--- a/hl/test/h5hltest.h
+++ b/hl/test/h5hltest.h
@@ -23,9 +23,6 @@
#ifndef _H5HLTEST_H
#define _H5HLTEST_H
-/* Get the HDF5 public header */
-#include "hdf5.h"
-
/* Get the HDF5 test header */
#include "h5test.h"
@@ -36,5 +33,8 @@
#define TESTING2(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);}
#define TESTING3(WHAT) {printf("%-70s", "" WHAT); fflush(stdout);}
+/* Implrements verbose 'assert' with 'goto error' exit */
+#define VERIFY(condition, string) do { if (!(condition)) FAIL_PUTS_ERROR(string) } while(0)
+
#endif /* _H5HLTEST_H */
diff --git a/hl/test/test_file_image.c b/hl/test/test_file_image.c
new file mode 100644
index 0000000..9729421
--- /dev/null
+++ b/hl/test/test_file_image.c
@@ -0,0 +1,518 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+* 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 files COPYING and Copyright.html. COPYING can be found at the root *
+* of the source code distribution tree; Copyright.html can be found at the *
+* root level of an installed copy of the electronic HDF5 document set and *
+* is linked from the top-level documents page. It can also be found at *
+* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+* access to either file, you may request a copy from help@hdfgroup.org. *
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "h5hltest.h"
+#include "H5LTpublic.h"
+
+#define DSET_NAME "dset"
+
+#define RANK 2
+
+/* Test of file image operations.
+
+ The following code provides a means to thoroughly test the file image
+ operations. Main objectives are testing operations with multiple open
+ images and using all possible flag combinations, which are set in the
+ main calling routine. Since the number of open images and flag combinations
+ may differ, the flag combinations are assigned to the images in round-robin
+ fashion. In order to simulate a realistic operation environment, the code
+ operates on as many open objects as possible by using several for-loops
+ instead of using a single loop that opens image i, accesses it, and closes
+ it. The first loop creates the files and obtains images using the function
+ H5Fget_file_image(); two images are set incorrectly (one image is filled
+ with "wrong" data while the other image is not valid). The second loop opens
+ the images using the function H5LTopen_file_image(), and test whether the
+ images have been copied in accordance to the H5LT_FILE_IMAGE_DONT_COPY flag.
+ The third loop reads the open images and verifies that the contents are
+ correct. The fourth loop first perform writes in the images that do not
+ extend the image, and then performs writes that extend the images. The fifth
+ loop reads the extended images and verify that the content are correct. The
+ sixth and final loop closes the file images and deallocates the image
+ buffers if appropriate. */
+
+/*-------------------------------------------------------------------------
+* test file image operations
+*-------------------------------------------------------------------------
+*/
+static int
+test_file_image(size_t open_images, size_t nflags, unsigned *flags)
+{
+ hid_t *file_id, *dset_id, file_space, plist; /* HDF5 ids */
+ hsize_t dims1[RANK] = {2,3}; /* original dimension of datasets */
+ hsize_t max_dims[RANK] = {H5S_UNLIMITED, H5S_UNLIMITED};
+ int data1[6] = {1,2,3,4,5,6}; /* original contents of dataset */
+ int data2[6] = {7,8,9,10,11,12}; /* "wrong" contents of dataset */
+ hsize_t dims3[RANK]; /* array to read dataset dimensions */
+ int data3[15]; /* array to read dataset contents */
+ hsize_t dims4[RANK] = {3,5}; /* extended dimensions of datasets */
+ int data4[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+ /* extended contents of dataset */
+ ssize_t *buf_size; /* pointer to array of buffer sizes */
+ void **buf_ptr; /* pointer to array of pointers to image buffers */
+ char **filename; /* pointer to array of pointers to filenames */
+ unsigned *input_flags; /* pointer to array of flag combinations */
+ size_t i, j, k, nrow, n_values;
+ herr_t status1;
+ void *handle_ptr = NULL; /* pointers to driver buffer */
+ unsigned char **core_buf_ptr_ptr = NULL;
+
+ VERIFY(open_images > 1 , "The number of open images must be greater than 1");
+
+ VERIFY(nflags > 0, "The number of flag combinations must be greater than 0");
+
+ /* allocate array of flags for open images */
+ if (NULL == (input_flags = (unsigned *)HDmalloc(sizeof(unsigned) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* allocate array of pointers for each of the open images */
+ if (NULL == (buf_ptr = (void **)malloc(sizeof(void *) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* allocate array to store the name of each of the open images */
+ if (NULL == (filename = (char **)malloc(sizeof(char *) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* allocate array to store the size of each of the open images */
+ if (NULL == (buf_size = (ssize_t *)malloc(sizeof(ssize_t) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* allocate array for each of the file identifiers */
+ if (NULL == (file_id = (hid_t *)malloc(sizeof(hid_t) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* allocate array for each of the dataset identifiers */
+ if (NULL == (dset_id = (hid_t *)malloc(sizeof(hid_t) * open_images)))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ TESTING("get file images");
+
+ /* create several file images */
+ for (i = 0; i < open_images; i++) {
+
+ /* populate array for flags combinations */
+ input_flags[i] = flags[(nflags + i) % nflags];
+
+ /* allocate name buffer for image i */
+ filename[i] = (char *)HDmalloc(sizeof(char) * 32);
+
+ /* create file name */
+ sprintf(filename[i], "image_file%d.h5", (int)i);
+
+ /* create file */
+ if ((file_id[i] = H5Fcreate(filename[i], H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ FAIL_PUTS_ERROR("H5Fcreate() failed");
+
+ /* define dataspace for the dataset */
+ if ((file_space = H5Screate_simple(RANK, dims1, max_dims)) < 0)
+ FAIL_PUTS_ERROR("H5Screate_simple() failed");
+
+ /* create dataset property list */
+ if ((plist = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+ FAIL_PUTS_ERROR("H5Pcreate() failed");
+
+ /* set property list to create chunked dataset */
+ if (H5Pset_chunk(plist, RANK, dims1) < 0)
+ FAIL_PUTS_ERROR("H5Pset_chunk() failed");
+
+ /* create and write an integer type dataset named "dset" */
+ if ((dset_id[i] = H5Dcreate2(file_id[i], DSET_NAME, H5T_NATIVE_INT, file_space, H5P_DEFAULT, plist, H5P_DEFAULT)) < 0)
+ FAIL_PUTS_ERROR("H5Dcreate() failed");
+
+ /* dataset in open image 1 is written with "wrong" data */
+ if (i == 1) {
+ if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data2) < 0)
+ FAIL_PUTS_ERROR("H5Dwrite() failed");
+ } /* end if*/
+ /* dataset in the rest of the open images is written with correct data */
+ else {
+ if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1) < 0)
+ FAIL_PUTS_ERROR("H5Dwrite() failed");
+ } /* end else */
+
+ /* flush into the file */
+ if (H5Fflush(file_id[i], H5F_SCOPE_LOCAL) < 0)
+ FAIL_PUTS_ERROR("H5Fflush() failed");
+
+ /* close dataset property list */
+ if (H5Pclose(plist) < 0)
+ FAIL_PUTS_ERROR("H5Pclose() failed");
+
+ /* close dataspace */
+ if (H5Sclose(file_space) < 0)
+ FAIL_PUTS_ERROR("H5Sclose() failed");
+
+ /* close dataset */
+ if (H5Dclose(dset_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Dclose() failed");
+
+ /* get size of the file image i */
+ if ((buf_size[i] = H5Fget_file_image(file_id[i], NULL, 0)) < 0)
+ FAIL_PUTS_ERROR("H5Fget_file_image() failed");
+
+ /* allocate buffer for the file image i */
+ if (NULL == (buf_ptr[i] = (void *)HDmalloc((size_t)buf_size[i])))
+ FAIL_PUTS_ERROR("malloc() failed");
+
+ /* buffer for file image 2 is filled with counter data (non-valid image) */
+ if (i == 2) {
+ for (j = 0; j < (size_t)buf_size[i]; j++)
+ ((char*)(buf_ptr[i]))[j] = (char)j;
+ } /* end if */
+ /* buffers for the rest of the file images are filled with data from the respective files */
+ else {
+ if ((buf_size[i] = H5Fget_file_image(file_id[i], buf_ptr[i], (size_t)buf_size[i])) < 0)
+ FAIL_PUTS_ERROR("H5Fget_file_image() failed");
+ } /* end else */
+
+ /* file close */
+ if (H5Fclose (file_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Fclose() failed");
+ } /* end for */
+
+ PASSED();
+
+ TESTING("open file images and check image copies");
+
+ /* open the file images with the core driver for data access */
+ for (i = 0; i < open_images; i++) {
+ /* open file image 2 filled with counter data (non-valid image) */
+ if (i == 2) {
+ H5E_BEGIN_TRY {
+ /* attempt to set file image in the core driver */
+ file_id[i] = H5LTopen_file_image(buf_ptr[i], (size_t)buf_size[i], input_flags[i]);
+ } H5E_END_TRY
+
+ VERIFY(file_id[i] < 0, "H5LTopen_file_image() should have failed");
+ } /* end if */
+ /* open rest of valid file images */
+ else {
+ /* set file image in the core driver */
+ if ((file_id[i] = H5LTopen_file_image(buf_ptr[i], (size_t)buf_size[i], input_flags[i])) < 0)
+ FAIL_PUTS_ERROR("H5LTopen_file_image() failed");
+
+ /* get pointer to the image buffer of the core driver */
+ if (H5Fget_vfd_handle(file_id[i], H5P_DEFAULT, &handle_ptr) < 0)
+ FAIL_PUTS_ERROR("H5Fget_vfd_handle() failed");
+
+ core_buf_ptr_ptr = (unsigned char **)handle_ptr;
+
+ /* test whether the user buffer has been copied or not */
+ if (input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY)
+ VERIFY(*core_buf_ptr_ptr == buf_ptr[i], "vfd buffer and user buffer should have been the same");
+ else
+ VERIFY(*core_buf_ptr_ptr != buf_ptr[i], "vfd buffer and user buffer should be different");
+
+ /* test whether the contents of the user buffer and driver buffer */
+ /* are equal. */
+ if (HDmemcmp(*core_buf_ptr_ptr, buf_ptr[i], (size_t)buf_size[i]) != 0)
+ FAIL_PUTS_ERROR("comparison of vfd and user buffer failed");
+ } /* end else */
+ } /* end for */
+
+ PASSED();
+
+ TESTING("read file images");
+
+ /* read open file images and verify data */
+ for (i = 0; i < open_images; i++) {
+ /* if opening the file image failed, continue next iteration */
+ if (file_id[i] < 0) {
+ HDassert(i == 2);
+ continue;
+ } /* end if */
+
+ /* open dataset in file image */
+ if ((dset_id[i] = H5Dopen2(file_id[i], DSET_NAME, H5P_DEFAULT)) < 0)
+ FAIL_PUTS_ERROR("H5Dopen() failed");
+
+ /* get dataspace for the dataset */
+ if ((file_space = H5Dget_space(dset_id[i])) < 0)
+ FAIL_PUTS_ERROR("H5Dget_space() failed");
+
+ /* get dimensions for the dataset */
+ if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
+ FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");
+
+ /* read dataset */
+ if (H5Dread(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data3) < 0)
+ FAIL_PUTS_ERROR("H5Dread() failed");
+
+ /* compute number of elements in dataset */
+ n_values = (size_t)(dims3[0] * dims3[1]);
+
+ /* determine the number of rows in dataset */
+ nrow = (size_t)dims3[1];
+
+ /* verify contents for file image 1 with "wrong" data */
+ if (i == 1) {
+ /* compare file image values with original data */
+ for (j = 0; j < n_values / nrow; j++)
+ for (k = 0; k < nrow; k++)
+ if (data3[j * nrow + k ] == data1[j * nrow + k ])
+ FAIL_PUTS_ERROR("comparison of image values with original data should have failed");
+ } /* end if */
+ /* verify contents for the rest of the file images */
+ else {
+ /* compare file image values with original data */
+ for (j = 0; j < n_values / nrow; j++)
+ for (k = 0; k < nrow; k++)
+ if (data3[j * nrow + k ] != data1[j * nrow + k ])
+ FAIL_PUTS_ERROR("comparison of image values with original data failed");
+ } /* end else */
+
+ /* close dataspace */
+ if (H5Sclose (file_space) < 0)
+ FAIL_PUTS_ERROR("H5Sclose() failed");
+ } /* end for */
+
+ PASSED();
+
+ TESTING("write and extend file images");
+
+ /* write open file images and verify data */
+ for (i = 0; i < open_images; i++) {
+ /* if opening the file image failed, continue next iteration */
+ if (file_id[i] < 0) {
+ HDassert(i == 2);
+ continue;
+ } /* end if */
+
+ /* test data write when file image access is read-only */
+ if (!(input_flags[i] & H5LT_FILE_IMAGE_OPEN_RW)) {
+ /* write dataset without extending it */
+ H5E_BEGIN_TRY {
+ status1 = H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1);
+ } H5E_END_TRY;
+
+ VERIFY(status1 < 0, "H5Dwrite() should have failed");
+
+ /* extend dimensions of dataset */
+ H5E_BEGIN_TRY {
+ status1 = H5Dset_extent(dset_id[i], dims4);
+ } H5E_END_TRY;
+
+ VERIFY(status1 < 0, "H5Dset_extent() should have failed");
+
+ /* write extended dataset */
+ H5E_BEGIN_TRY {
+ status1 = H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data4);
+ } H5E_END_TRY;
+
+ VERIFY(status1 < 0, "H5Dwrite() should have failed");
+
+ /* close dataset */
+ if (H5Dclose(dset_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Dclose() failed");
+ } /* end if */
+ /* test data write where file image access is read-write */
+ else {
+ if ((input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY) && (input_flags[i] & H5LT_FILE_IMAGE_DONT_RELEASE)) {
+/* This test is disabled currently, since the new attribute causes the file
+ * to increase in size, but the realloc call in H5FD_core_write() fails, causing
+ * the flush operation to fail and the file to fail to close, eventually
+ * triggering the "infinite loop shutting down the library" problem.
+ *
+ * In theory, we could address this through a variety of methods, ranging from
+ * ignoring failures in H5F_dest() (when called from H5F_try_close()), to
+ * allocating space more aggressively when creating the attribute, etc.
+ *
+ * For now, we will just leave the test commented out and assume that
+ * application developers who mark their file image as "don't copy" won't
+ * be likely candidates for modifying their data. - QAK - March 29, 2012
+ */
+#if 0
+ int attr_rank = 1;
+ hsize_t attr_dims[] = {4096};
+ int attr_data[4096];
+ hid_t attr_space_id = -1;
+ hid_t attr_id = -1;
+ herr_t status2;
+ size_t l;
+
+ if ((attr_space_id = H5Screate_simple(attr_rank, attr_dims, attr_dims)) < 0)
+ FAIL_PUTS_ERROR("attr_space H5Screate_simple() failed");
+
+ if((attr_id = H5Acreate_by_name(dset_id[i], ".", "int array_addr", H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ FAIL_PUTS_ERROR("H5Acreate_by_name() failed");
+
+ for(l = 0; l < 4096; l++)
+ attr_data[l] = (int)l;
+
+ /* write data to the attribute and then flush the file. One or the other should
+ * should trigger an extension to the EOA, which in turn should cause the realloc
+ * callback to fail.
+ */
+ H5E_BEGIN_TRY {
+ status1 = status2 = -1;
+
+ status1 = H5Awrite(attr_id, H5T_NATIVE_INT, (const void *)attr_data);
+ if(status1 >= 0)
+ status2 = H5Fflush(file_id[i], H5F_SCOPE_GLOBAL);
+
+ VERIFY(status1 < 0 || status2 < 0, "writing and flushing attr should have failed");
+ } H5E_END_TRY;
+
+ /* close attr and attr_space -- expect errors on close */
+ H5E_BEGIN_TRY {
+ H5Sclose(attr_space_id);
+ H5Aclose(attr_id);
+ } H5E_END_TRY;
+#endif
+ file_id[i] = -1;
+ } /* end if */
+ else {
+ /* write dataset without extending it */
+ if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data1) < 0)
+ FAIL_PUTS_ERROR("H5Dwrite() failed");
+
+ /* extend dimensions of dataset */
+ if (H5Dset_extent(dset_id[i], dims4) < 0)
+ FAIL_PUTS_ERROR("H5Dset_extent() failed");
+
+ /* write extended dataset */
+ if (H5Dwrite(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data4) < 0)
+ FAIL_PUTS_ERROR("H5Dwrite() failed");
+
+ /* close dataset */
+ if (H5Dclose(dset_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Dclose() failed");
+ } /* end else */
+ } /* end else */
+ } /* end for */
+
+ PASSED();
+
+ TESTING("read extended file images");
+
+ /* read open file images and verify data */
+ for (i = 0; i < open_images; i++) {
+ /* if opening the file image failed, continue next iteration */
+ if ((file_id[i] < 0) || (!(input_flags[i] & H5LT_FILE_IMAGE_OPEN_RW )))
+ continue;
+
+ /* open dataset in file image */
+ if ((dset_id[i] = H5Dopen2(file_id[i], DSET_NAME, H5P_DEFAULT)) < 0)
+ FAIL_PUTS_ERROR("H5Dopen() failed");
+
+ /* get dataspace for the dataset */
+ if ((file_space = H5Dget_space(dset_id[i])) < 0)
+ FAIL_PUTS_ERROR("H5Dget_space() failed");
+
+ /* get dimensions for the dataset */
+ if (H5Sget_simple_extent_dims(file_space, dims3, NULL) < 0)
+ FAIL_PUTS_ERROR("H5Sget_simple_extent_dims() failed");
+
+ /* read dataset */
+ if (H5Dread(dset_id[i], H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data3) < 0)
+ FAIL_PUTS_ERROR("H5Dread() failed");
+
+ /* compute number of elements in dataset */
+ n_values = (size_t)(dims3[0] * dims3[1]);
+
+ /* determine the number of rows in dataset */
+ nrow = (size_t)dims3[1];
+
+ /* verify contents for the file images */
+ for (j = 0; j < n_values / nrow; j++)
+ for (k = 0; k < nrow; k++)
+ if (data3[j * nrow + k ] != data4[j * nrow + k ])
+ FAIL_PUTS_ERROR("comparison of image values with original data failed");
+
+ /* close dataspace */
+ if (H5Sclose (file_space) < 0)
+ FAIL_PUTS_ERROR("H5Sclose() failed");
+
+ /* close dataset */
+ if (H5Dclose(dset_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Dclose() failed");
+ } /* end for */
+
+ PASSED()
+
+ TESTING("close file images");
+
+ /* close file images and release buffer if appropriate */
+ for (i = 0; i < open_images; i++) {
+ /* close file is appropriate */
+ if (file_id[i] >= 0) {
+ /* close file image */
+ if (H5Fclose(file_id[i]) < 0)
+ FAIL_PUTS_ERROR("H5Fclose() failed");
+ } /* end if */
+
+ /* delete test data files */
+ if (HDremove(filename[i]) < 0)
+ FAIL_PUTS_ERROR("HDremove() failed");
+
+ /* free shared buffer if appropriate */
+ if (!(input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY) || (input_flags[i] & H5LT_FILE_IMAGE_DONT_RELEASE)) {
+ VERIFY(buf_ptr[i] != NULL, "buffer pointer must be non NULL");
+ HDfree(buf_ptr[i]);
+ } /* end if */
+
+ } /* end for */
+
+ /* release temporary working buffers */
+ HDfree(filename);
+ HDfree(file_id);
+ HDfree(dset_id);
+ HDfree(buf_ptr);
+ HDfree(buf_size);
+ HDfree(input_flags);
+
+ PASSED();
+
+ H5close();
+
+ return 0;
+
+error:
+ H5_FAILED();
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+* the main program
+*-------------------------------------------------------------------------
+*/
+int main( void )
+{
+ int nerrors = 0;
+ size_t open_images = 10; /* number of open file images */
+ size_t nflags = 8; /* number of flag combinations */
+ unsigned flags[8]; /* array with flag combinations */
+
+ /* set flag combinations for testing */
+ flags[0] = 0;
+ flags[1] = H5LT_FILE_IMAGE_DONT_RELEASE;
+ flags[2] = H5LT_FILE_IMAGE_DONT_COPY;
+ flags[3] = H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
+ flags[4] = H5LT_FILE_IMAGE_OPEN_RW;
+ flags[5] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_RELEASE;
+ flags[6] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_COPY;
+ flags[7] = H5LT_FILE_IMAGE_OPEN_RW | H5LT_FILE_IMAGE_DONT_COPY | H5LT_FILE_IMAGE_DONT_RELEASE;
+
+ /* Test file image operations. The flag combinations are assigned to file images in round-robin fashion */
+ nerrors += test_file_image(open_images, nflags, flags) < 0? 1 : 0;
+
+ if (nerrors) goto error;
+ printf("File image tests passed.\n");
+ return 0;
+
+error:
+ printf("***** %d IMAGE TEST%s FAILED! *****\n",nerrors, 1 == nerrors ? "" : "S");
+ return 1;
+}
+
diff --git a/hl/tools/COPYING b/hl/tools/COPYING
index 6903daf..6903daf 100755..100644
--- a/hl/tools/COPYING
+++ b/hl/tools/COPYING
diff --git a/perform/COPYING b/perform/COPYING
index 6903daf..6903daf 100755..100644
--- a/perform/COPYING
+++ b/perform/COPYING
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index f0f296c..8761fb9 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -1,4 +1,4 @@
-HDF5 version 1.9.112 currently under development
+HDF5 version 1.9.114 currently under development
================================================================================
@@ -93,6 +93,11 @@ New Features
Library:
--------
+ - The data sieve buffer size was for all the datasets in the file. It
+ could waste memory if any dataset size is smaller than the sieve buffer
+ size. Now the library picks the smaller one between the dataset size
+ and the sieve buffer size from the file access property. See Issue 7934.
+ (SLU - 2012/4/2)
- I added a new parameter of object access property list to the function
H5Rdereference (Issue 2763). It's called H5Rdereference2 now. The former
H5Rdereference function has been deprecated to H5Rdereference1. (SLU -
@@ -172,6 +177,11 @@ New Features
Fortran Library:
----------------
+
+ - Added for the C API the Fortran wrapper:
+ h5ocopy_f (MSB - 2012/03/22)
+
+
HDF5 Fortran library was enhanced to support Fortran 2003 standard.
The following features are available when the HDF5 library is configured
using --enable-fortran --enable-fortran2003 configure flags AND
@@ -352,7 +362,7 @@ New Features
- New API: h5ltpath_valid (Fortran: h5ltpath_valid_f) which checks
if a path is correct and determines if a link resolves to a valid
- object and does not dangle. (MSB- 2012/3/15)
+ object and checks that the link does not dangle. (MSB- 2012/3/15)
Documentation
-------------
@@ -368,6 +378,16 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed an error that would occur when copying an object with attribute
+ creation order tracked and indexed. (NAF - 2012/3/28 - HDFFV-7762)
+ - Fixed a bug in H5Ocopy(): When copying an opened object, call the
+ object's flush class action to ensure that cached data is flushed
+ so that H5Ocopy will get the correct data.
+ (VC - 2012/3/27 - HDFFV-7853)
+ - When an application tries to write or read many small data chunks and
+ runs out of memory, the library had a seg fault. The fix is to
+ return the error stack with proper information. (SLU - 2012/3/23.
+ Issue 7785)
- H5Pset_data_transform had seg fault in some cases like x*-100. It
works correctly now and handles other cases like 100-x or 2/x.
(SLU - 2012/3/15. Issue 7922)
@@ -379,6 +399,10 @@ Bug Fixes since HDF5-1.8.0 release
2012/1/25. Issue 7756)
- Fixed a seg fault that could occur when shrinking a dataset with chunks
larger than 1 MB. (NAF - 2011/11/30 - HDFFV-7833)
+ - Fixed a bug that could cause file corruption when copying named
+ datatypes to a file using shared messages. (NAF - 2011/11/14)
+ - Fixed a bug that could cause H5Oget_info to return the wrong address
+ after copying a named datatype. (NAF - 2011/11/14)
- The library allowed the conversion of strings between ASCII and UTF8
(Issue 7582). We have corrected it to report an error under this
situation. (SLU - 2011/11/8)
@@ -593,6 +617,12 @@ Bug Fixes since HDF5-1.8.0 release
Configuration
-------------
+ - Fixed Makefile issue in which "-Wl," was not properly specified
+ prior to -rpath when building parallel fortran libraries with
+ an Intel compiler. (MAM - 2012/03/26)
+ - Makefiles generated by other packages using h5cc as the compiler
+ no longer error when 'make' is invoked more than once in order
+ to 'rebuild' after changes to source. (MAM - 2012/03/26)
- Added --enable-fortran2003 flag to enable Fortran2003 support
in the HDF5 Fortran library. The flag should be used along with the
--enable-fortran flag and takes affect only when Fortran compiler
@@ -666,6 +696,10 @@ Bug Fixes since HDF5-1.8.0 release
Tools
-----
+ - h5diff: Fixed failure for comparing same named object with different
+ object types in comparing groups. Prior to the fix, h5diff resulted
+ in error. After the fix, h5diff detects such case as non-comparable
+ and display messages accordingly. HDFFV-7664 (JKM 2012/03/28)
- h5diff: If unique objects exists only in one file and try to exclude
the unique objects with --exclude-path option, h5diff missed
excluding some objects.
@@ -878,6 +912,10 @@ Bug Fixes since HDF5-1.8.0 release
Fortran High-Level APIs:
------
+
+ - Lite: The h5ltget_attribute_string_f used to return the C NULL character in the
+ returned character buffer. The returned Fortran charactor buffer now does
+ not return the C NULL character. (MSB - 2012/3/23)
- Lite: The h5ltget_dataset_info_f function (gets information about a dataset)
was not correctly returning the dimension array. (PVN - 2009/3/23)
- Lite: the h5ltread_dataset_string_f and h5ltget_attribute_string_f functions
diff --git a/src/H5A.c b/src/H5A.c
index c59e098..0ba7361 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -2566,6 +2566,36 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5A_type
+ *
+ * Purpose: Return the datatype for an attribute.
+ *
+ * Return: Success: Ptr to entry
+ * Failure: NULL
+ *
+ * Programmer: Neil Fortner
+ * Friday, November 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5A_type(const H5A_t *attr)
+{
+ H5T_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value = attr->shared->dt;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_type() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Aexists
*
* Purpose: Checks if an attribute with a given name exists on an opened
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 8475330..74c5590 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -795,6 +795,12 @@ H5A_set_version(const H5F_t *f, H5A_t *attr)
*
* Purpose: Copies a message from _MESG to _DEST in file
*
+ * Note that this function assumes that it is copying *all*
+ * the attributes in the object, specifically when it copies
+ * the creation order from source to destination. If this is
+ * to be used to copy only a single attribute, then the
+ * creation order must be handled differently. -NAF
+ *
* Return: Success: Ptr to _DEST
*
* Failure: NULL
@@ -849,6 +855,7 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
/* Copy attribute's name */
attr_dst->shared->name = H5MM_strdup(attr_src->shared->name);
HDassert(attr_dst->shared->name);
+ attr_dst->shared->encoding = attr_src->shared->encoding;
/* Copy attribute's datatype */
/* If source is named, we will keep dst as named, but we will not actually
@@ -1003,6 +1010,9 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
} /* end else */
} /* end if(attr_src->shared->data) */
+ /* Copy the creation order */
+ attr_dst->shared->crt_idx = attr_src->shared->crt_idx;
+
/* Recompute the version to encode the destination attribute */
if(H5A_set_version(file_dst, attr_dst) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version")
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index e7732e2..5257171 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -158,29 +158,6 @@ typedef struct {
H5A_t **attrs; /* Pointer to array of attribute pointers */
} H5A_attr_table_t;
-/* Attribute iteration operator for internal library callbacks */
-typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
-
-/* Describe kind of callback to make for each attribute */
-typedef enum H5A_attr_iter_op_type_t {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_ATTR_OP_APP, /* Application callback */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5A_ATTR_OP_APP2, /* Revised application callback */
- H5A_ATTR_OP_LIB /* Library internal callback */
-} H5A_attr_iter_op_type_t;
-
-typedef struct H5A_attr_iter_op_t {
- H5A_attr_iter_op_type_t op_type;
- union {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_operator1_t app_op; /* Application callback for each attribute */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5A_operator2_t app_op2; /* Revised application callback for each attribute */
- H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
- } u;
-} H5A_attr_iter_op_t;
-
/*****************************/
/* Package Private Variables */
@@ -274,9 +251,6 @@ H5_DLL herr_t H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id,
H5A_t *attr);
H5_DLL herr_t H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id,
const char *old_name, const char *new_name);
-H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, hid_t dxpl_id, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
- const H5A_attr_iter_op_t *op, void *op_data);
H5_DLL herr_t H5O_attr_remove(const H5O_loc_t *loc, const char *name,
hid_t dxpl_id);
H5_DLL herr_t H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index 18219e6..ac9f698 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -24,6 +24,8 @@
/* Private headers needed by this file */
#include "H5Gprivate.h" /* Groups */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Tprivate.h" /* Datatypes */
/**************************/
@@ -41,6 +43,29 @@
/* Forward references of package typedefs */
typedef struct H5A_t H5A_t;
+/* Attribute iteration operator for internal library callbacks */
+typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
+
+/* Describe kind of callback to make for each attribute */
+typedef enum H5A_attr_iter_op_type_t {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ H5A_ATTR_OP_APP, /* Application callback */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_ATTR_OP_APP2, /* Revised application callback */
+ H5A_ATTR_OP_LIB /* Library internal callback */
+} H5A_attr_iter_op_type_t;
+
+typedef struct H5A_attr_iter_op_t {
+ H5A_attr_iter_op_type_t op_type;
+ union {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ H5A_operator1_t app_op; /* Application callback for each attribute */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_operator2_t app_op2; /* Revised application callback for each attribute */
+ H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
+ } u;
+} H5A_attr_iter_op_t;
+
/*****************************/
/* Library-private Variables */
@@ -54,6 +79,13 @@ typedef struct H5A_t H5A_t;
/* General attribute routines */
H5_DLL struct H5O_loc_t *H5A_oloc(H5A_t *attr);
H5_DLL H5G_name_t *H5A_nameof(H5A_t *attr);
+H5_DLL H5T_t *H5A_type(const H5A_t *attr);
+H5_DLL herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
+ hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
+ hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
+H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, hid_t dxpl_id, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
+ const H5A_attr_iter_op_t *op, void *op_data);
#endif /* _H5Aprivate_H */
diff --git a/src/H5Bcache.c b/src/H5Bcache.c
index c0fd121..68fb920 100644
--- a/src/H5Bcache.c
+++ b/src/H5Bcache.c
@@ -152,6 +152,10 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* entries used */
UINT16DECODE(p, bt->nchildren);
+ /* Check if bt->nchildren is greater than two_k */
+ if(bt->nchildren > shared->two_k)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "number of children is greater than maximum")
+
/* sibling pointers */
H5F_addr_decode(udata->f, (const uint8_t **)&p, &(bt->left));
H5F_addr_decode(udata->f, (const uint8_t **)&p, &(bt->right));
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 46925a1..af888a9 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -974,7 +974,7 @@ H5D_free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata)
H5S_select_all(chunk_info->fspace, TRUE);
/* Close the chunk's memory dataspace, if it's not shared */
- if(!chunk_info->mspace_shared)
+ if(!chunk_info->mspace_shared && chunk_info->mspace)
(void)H5S_close(chunk_info->mspace);
/* Free the actual chunk info */
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 674582d..c1ff68c 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -420,6 +420,7 @@ H5D_contig_construct(H5F_t *f, H5D_t *dset)
hsize_t nelmts; /* Number of elements in dataspace */
size_t dt_size; /* Size of datatype */
hsize_t tmp_size; /* Temporary holder for raw data size */
+ size_t tmp_sieve_buf_size; /* Temporary holder for sieve buffer size */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Current size of data in elements */
hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
int ndims; /* Rank of dataspace */
@@ -464,8 +465,15 @@ H5D_contig_construct(H5F_t *f, H5D_t *dset)
/* Assign the dataset's contiguous storage size */
dset->shared->layout.storage.u.contig.size = tmp_size;
- /* Get the sieve buffer size for this dataset */
- dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
+ /* Get the sieve buffer size for the file */
+ tmp_sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
+
+ /* Adjust the sieve buffer size to the smaller one between the dataset size and the buffer size
+ * from the file access property. (SLU - 2012/3/30) */
+ if(tmp_size < tmp_sieve_buf_size)
+ dset->shared->cache.contig.sieve_buf_size = tmp_size;
+ else
+ dset->shared->cache.contig.sieve_buf_size = tmp_sieve_buf_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -965,6 +973,7 @@ H5D_contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len,
/* Allocate room for the data sieve buffer */
if(NULL == (dset_contig->sieve_buf = H5FL_BLK_MALLOC(sieve_buf, dset_contig->sieve_buf_size)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "memory allocation failed")
+
#ifdef H5_CLEAR_MEMORY
if(dset_contig->sieve_size > len)
HDmemset(dset_contig->sieve_buf + len, 0, (dset_contig->sieve_size - len));
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 31cd84b..e17c0f7 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -68,7 +68,6 @@ static herr_t H5D_init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space)
static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset,
hid_t dapl_id);
static herr_t H5D_open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id);
-static herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id);
/*********************/
@@ -2440,7 +2439,8 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id)
udata.dxpl_id = dxpl_id;
/* Iterate over all the open datasets */
- H5I_search(H5I_DATASET, H5D_flush_cb, &udata, FALSE);
+ if(H5I_iterate(H5I_DATASET, H5D_flush_cb, &udata, FALSE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to flush cached dataset info")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 49a8f25..7a58c4a 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -362,6 +362,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
|| dataset->shared->layout.type == H5D_COMPACT);
/* Call storage method's I/O initialization routine */
+ HDmemset(&fm, 0, sizeof(H5D_chunk_map_t));
if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
io_op_init = TRUE;
@@ -585,6 +586,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#endif /*H5_HAVE_PARALLEL*/
/* Call storage method's I/O initialization routine */
+ HDmemset(&fm, 0, sizeof(H5D_chunk_map_t));
if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
io_op_init = TRUE;
diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c
index 7ec6404..53d49aa 100644
--- a/src/H5Dlayout.c
+++ b/src/H5Dlayout.c
@@ -384,6 +384,10 @@ H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t
switch(dataset->shared->layout.type) {
case H5D_CONTIGUOUS:
+ {
+ hsize_t tmp_size; /* Temporary holder for raw data size */
+ size_t tmp_sieve_buf_size; /* Temporary holder for sieve buffer size */
+
/* Compute the size of the contiguous storage for versions of the
* layout message less than version 3 because versions 1 & 2 would
* truncate the dimension sizes to 32-bits of information. - QAK 5/26/04
@@ -392,7 +396,6 @@ H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t
hssize_t snelmts; /* Temporary holder for number of elements in dataspace */
hsize_t nelmts; /* Number of elements in dataspace */
size_t dt_size; /* Size of datatype */
- hsize_t tmp_size; /* Temporary holder for raw data size */
/* Retrieve the number of elements in the dataspace */
if((snelmts = H5S_GET_EXTENT_NPOINTS(dataset->shared->space)) < 0)
@@ -412,10 +415,19 @@ H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t
/* Assign the dataset's contiguous storage size */
dataset->shared->layout.storage.u.contig.size = tmp_size;
- } /* end if */
-
- /* Get the sieve buffer size for this dataset */
- dataset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->oloc.file);
+ } else
+ tmp_size = dataset->shared->layout.storage.u.contig.size;
+
+ /* Get the sieve buffer size for the file */
+ tmp_sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->oloc.file);
+
+ /* Adjust the sieve buffer size to the smaller one between the dataset size and the buffer size
+ * from the file access property. (SLU - 2012/3/30) */
+ if(tmp_size < tmp_sieve_buf_size)
+ dataset->shared->cache.contig.sieve_buf_size = tmp_size;
+ else
+ dataset->shared->cache.contig.sieve_buf_size = tmp_sieve_buf_size;
+ }
break;
case H5D_CHUNKED:
diff --git a/src/H5Doh.c b/src/H5Doh.c
index 7a657ec..e6a715f 100644
--- a/src/H5Doh.c
+++ b/src/H5Doh.c
@@ -56,6 +56,8 @@ static H5O_loc_t *H5O_dset_get_oloc(hid_t obj_id);
static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
H5_ih_info_t *bh_info);
+static herr_t H5O_dset_flush(H5G_loc_t *obj_loc, hid_t dxpl_id);
+
/*********************/
/* Package Variables */
@@ -81,7 +83,8 @@ const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{
H5O_dset_open, /* open an object of this class */
H5O_dset_create, /* create an object of this class */
H5O_dset_get_oloc, /* get an object header location for an object */
- H5O_dset_bh_info /* get the index & heap info for an object */
+ H5O_dset_bh_info, /* get the index & heap info for an object */
+ H5O_dset_flush /* flush an opened object of this class */
}};
/* Declare a free list to manage the H5D_copy_file_ud_t struct */
@@ -431,3 +434,48 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_dset_bh_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_dset_flush
+ *
+ * Purpose: To flush any dataset information cached in memory
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ * February 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_dset_flush(H5G_loc_t *obj_loc, hid_t dxpl_id)
+{
+ H5D_t *dset; /* Dataset opened */
+ H5O_type_t obj_type; /* Type of object at location */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(obj_loc);
+ HDassert(obj_loc->oloc);
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(obj_loc->oloc, &obj_type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type")
+
+ if(obj_type != H5O_TYPE_DATASET)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
+
+ /* Open the dataset */
+ if(NULL == (dset = H5D_open(obj_loc, H5P_DATASET_ACCESS_DEFAULT, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
+
+ if(H5D_flush_real(dset, dxpl_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info")
+
+done:
+ if(dset && H5D_close(dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataset")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_dset_flush() */
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 16de07f..40317f3 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -548,6 +548,7 @@ H5_DLL herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
H5_DLL herr_t H5D_get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache);
H5_DLL herr_t H5D_flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id);
H5_DLL herr_t H5D_mark(H5D_t *dataset, hid_t dxpl_id, unsigned flags);
+H5_DLL herr_t H5D_flush_real(H5D_t *dataset, hid_t dxpl_id);
/* Functions that perform direct serial I/O operations */
H5_DLL herr_t H5D_select_read(const H5D_io_info_t *io_info,
diff --git a/src/H5E.c b/src/H5E.c
index 4e14887..e74211e 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -107,7 +107,7 @@ static H5E_cls_t *H5E_register_class(const char *cls_name, const char *lib_name,
const char *version);
static herr_t H5E_unregister_class(H5E_cls_t *cls);
static ssize_t H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size);
-static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key);
+static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata);
static herr_t H5E_close_msg(H5E_msg_t *err);
static H5E_msg_t *H5E_create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg);
static H5E_t *H5E_get_current_stack(void);
@@ -543,8 +543,8 @@ H5E_unregister_class(H5E_cls_t *cls)
HDassert(cls);
/* Iterate over all the messages and delete those in this error class */
- /* (Ignore return value, since callback isn't designed to return a particular object) */
- (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE);
+ if(H5I_iterate(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_BADITER, FAIL, "unable to free all messages in this error class")
/* Free error class structure */
if(H5E_free_class(cls) < 0)
@@ -631,7 +631,7 @@ H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size)
/*-------------------------------------------------------------------------
* Function: H5E_close_msg_cb
*
- * Purpose: H5I_search callback function to close error messages in the
+ * Purpose: H5I_iterate callback function to close error messages in the
* error class.
*
* Return: Non-negative value on success/Negative on failure
@@ -642,10 +642,10 @@ H5E_get_class_name(const H5E_cls_t *cls, char *name, size_t size)
*-------------------------------------------------------------------------
*/
static int
-H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key)
+H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata)
{
H5E_msg_t *err_msg = (H5E_msg_t*)obj_ptr;
- H5E_cls_t *cls = (H5E_cls_t*)key;
+ H5E_cls_t *cls = (H5E_cls_t*)udata;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 7fa8b12..27275a3 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -94,6 +94,7 @@ hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */
hid_t H5E_CANTGET_g = FAIL; /* Can't get value */
hid_t H5E_CANTSET_g = FAIL; /* Can't set value */
hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */
+hid_t H5E_SETDISALLOWED_g = FAIL; /* Disallowed operation */
/* Free space errors */
hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 7022297..99467ee 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -344,6 +344,11 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class")
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_SETDISALLOWED_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Disallowed operation"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_SETDISALLOWED_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Free space errors */
assert(H5E_CANTMERGE_g==(-1));
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index 12771b2..68c605c 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -157,9 +157,11 @@ H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */
#define H5E_CANTGET (H5OPEN H5E_CANTGET_g)
#define H5E_CANTSET (H5OPEN H5E_CANTSET_g)
#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g)
+#define H5E_SETDISALLOWED (H5OPEN H5E_SETDISALLOWED_g)
H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */
H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */
H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */
+H5_DLLVAR hid_t H5E_SETDISALLOWED_g; /* Disallowed operation */
/* Free space errors */
#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g)
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index 1860c19..28d822a 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -95,7 +95,8 @@ H5E_CANTRELEASE_g=
/* Property list errors */
H5E_CANTGET_g=
H5E_CANTSET_g=
-H5E_DUPCLASS_g=
+H5E_DUPCLASS_g=
+H5E_SETDISALLOWED_g=
/* Free space errors */
H5E_CANTMERGE_g=
diff --git a/src/H5F.c b/src/H5F.c
index 7c7db13..93d7cc6 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -53,7 +53,7 @@ typedef struct H5F_olist_t {
} H5F_olist_t;
/* PRIVATE PROTOTYPES */
-static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
+static herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr);
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
H5FD_t *lf);
@@ -353,42 +353,38 @@ done:
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
- * Modification:
- * Raymond Lu
- * 24 September 2008
- * Changed the return value to ssize_t to accommadate
- * potential large number of objects.
*
*-------------------------------------------------------------------------
*/
ssize_t
-H5Fget_obj_count(hid_t uid, unsigned types)
+H5Fget_obj_count(hid_t file_id, unsigned types)
{
- H5F_t *f = NULL; /* File to query */
- H5VL_id_wrapper_t *id_wrapper; /* user id structure */
- hid_t id;
- ssize_t ret_value; /* Return value */
+ H5F_t *f = NULL; /* File to query */
+ ssize_t ret_value; /* Return value */
+ size_t obj_count = 0; /* Number of opened objects */
FUNC_ENTER_API(FAIL)
- H5TRACE2("Zs", "iIu", uid, types);
+ H5TRACE2("Zs", "iIu", file_id, types);
- if (H5I_FILE_PUBLIC == H5I_get_type(uid)) {
- if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid)))
+ if (H5I_FILE_PUBLIC == H5I_get_type(file_id)) {
+ H5VL_id_wrapper_t *id_wrapper; /* wrapper object */
+
+ if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(file_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier")
- id = id_wrapper->obj_id;
- }
- else {
- id = uid;
+ file_id = id_wrapper->obj_id;
}
- if(id != (hid_t)H5F_OBJ_ALL &&
- (NULL == (f = (H5F_t *)H5I_object_verify(id, H5I_FILE))))
+ if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
if(0 == (types & H5F_OBJ_ALL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
- /* H5F_get_obj_count doesn't fail */
- ret_value = (ssize_t)H5F_get_obj_count(f, types, TRUE);
+ /* Perform the query */
+ if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
+
+ /* Set the return value */
+ ret_value = (ssize_t)obj_count;
done:
FUNC_LEAVE_API(ret_value)
@@ -401,31 +397,30 @@ done:
* Purpose: Private function return the number of opened object IDs
* (files, datasets, groups, datatypes) in the same file.
*
- * Return: Non-negative on success; can't fail.
+ * Return: SUCCEED on success, FAIL on failure.
*
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
- * Modification:
- * Raymond Lu
- * 24 September 2008
- * Changed the return value to size_t to accommadate
- * potential large number of objects.
- *
*-------------------------------------------------------------------------
*/
-size_t
-H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref)
+herr_t
+H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr)
{
- size_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_NOAPI(FAIL)
- /* H5F_get_objects doesn't fail */
- ret_value = H5F_get_objects(f, types, 0, NULL, app_ref);
+ /* Sanity check */
+ HDassert(obj_id_count_ptr);
+
+ /* Perform the query */
+ if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed")
+done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_get_obj_count() */
/*-------------------------------------------------------------------------
@@ -447,34 +442,36 @@ H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref)
*-------------------------------------------------------------------------
*/
ssize_t
-H5Fget_obj_ids(hid_t uid, unsigned types, size_t max_objs, hid_t *oid_list)
+H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list)
{
H5F_t *f = NULL; /* File to query */
- H5VL_id_wrapper_t *id_wrapper; /* user id structure */
- hid_t id;
+ size_t obj_id_count = 0; /* Number of open objects */
ssize_t ret_value; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE4("Zs", "iIuz*i", uid, types, max_objs, oid_list);
+ H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list);
- if (H5I_FILE_PUBLIC == H5I_get_type(uid)) {
- if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid)))
+ if (H5I_FILE_PUBLIC == H5I_get_type(file_id)) {
+ H5VL_id_wrapper_t *id_wrapper; /* wrapper object */
+
+ if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(file_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier")
- id = id_wrapper->obj_id;
- }
- else {
- id = uid;
+ file_id = id_wrapper->obj_id;
}
- if(id != (hid_t)H5F_OBJ_ALL &&
- (NULL == (f = (H5F_t *)H5I_object_verify(id, H5I_FILE))))
+ /* Check arguments */
+ if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
if(0 == (types & H5F_OBJ_ALL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
HDassert(oid_list);
- /* H5F_get_objects doesn't fail */
- ret_value = (ssize_t)H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE);
+ /* Perform the query */
+ if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_id_count) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed")
+
+ /* Set the return value */
+ ret_value = (ssize_t)obj_id_count;
if (H5VL_replace_with_uids (oid_list, ret_value) <= 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get IDs")
@@ -494,26 +491,25 @@ done:
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
- * Modification:
- * Raymond Lu
- * 24 September 2008
- * Changed the return value and MAX_OBJTS to size_t to accommadate
- * potential large number of objects.
- *
*-------------------------------------------------------------------------
*/
-size_t
-H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref)
+herr_t
+H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr)
{
- size_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_NOAPI(FAIL)
- /* H5F_get_objects doesn't fail */
- ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref);
+ /* Sanity check */
+ HDassert(obj_id_count_ptr);
+
+ /* Perform the query */
+ if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed")
+done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_get_obj_ids() */
/*---------------------------------------------------------------------------
@@ -529,14 +525,18 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list
*
*---------------------------------------------------------------------------
*/
-static size_t
-H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref)
+static herr_t
+H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr)
{
size_t obj_id_count=0; /* Number of open IDs */
H5F_olist_t olist; /* Structure to hold search results */
- size_t ret_value; /* Return value */
+ htri_t type_exists; /* Whether objects of a type are open */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert(obj_id_count_ptr);
/* Set up search information */
olist.obj_id_list = (max_index==0 ? NULL : obj_id_list);
@@ -554,45 +554,50 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_
olist.file_info.ptr.shared = f ? f->shared : NULL;
} /* end else */
- /* Search through file IDs to count the number, and put their
- * IDs on the object list. H5I_search returns NULL if no object
- * is found, so don't return failure in this function. */
+ /* Iterate through file IDs to count the number, and put their
+ * IDs on the object list. */
if(types & H5F_OBJ_FILE) {
olist.obj_type = H5I_FILE;
- (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref);
+ if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)")
} /* end if */
/* Search through dataset IDs to count number of datasets, and put their
* IDs on the object list */
if(types & H5F_OBJ_DATASET) {
olist.obj_type = H5I_DATASET;
- (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref);
- }
+ if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)")
+ } /* end if */
/* Search through group IDs to count number of groups, and put their
* IDs on the object list */
if(types & H5F_OBJ_GROUP) {
olist.obj_type = H5I_GROUP;
- (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref);
- }
+ if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)")
+ } /* end if */
/* Search through datatype IDs to count number of named datatypes, and put their
* IDs on the object list */
if(types & H5F_OBJ_DATATYPE) {
olist.obj_type = H5I_DATATYPE;
- (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref);
- }
+ if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)")
+ } /* end if */
/* Search through attribute IDs to count number of attributes, and put their
* IDs on the object list */
if(types & H5F_OBJ_ATTR) {
olist.obj_type = H5I_ATTR;
- (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref);
- }
+ if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)")
+ } /* end if */
/* Set the number of objects currently open */
- ret_value = obj_id_count;
+ *obj_id_count_ptr = obj_id_count;
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_objects() */
@@ -610,8 +615,6 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_
* Programmer: Raymond Lu
* Wednesday, Dec 5, 2001
*
- * Modification:
- *
*-------------------------------------------------------------------------
*/
static int
@@ -643,8 +646,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
/* Check if we've filled up the array. Return TRUE only if
* we have filled up the array. Otherwise return FALSE(RET_VALUE is
- * preset to FALSE) because H5I_search needs the return value of FALSE
- * to continue searching. */
+ * preset to FALSE) because H5I_iterate needs the return value of
+ * FALSE to continue the iteration. */
if(olist->max_index>0 && olist->list_index>=olist->max_index)
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
}
@@ -709,8 +712,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
/* Check if we've filled up the array. Return TRUE only if
* we have filled up the array. Otherwise return FALSE(RET_VALUE is
- * preset to FALSE) because H5I_search needs the return value of FALSE
- * to continue searching. */
+ * preset to FALSE) because H5I_iterate needs the return value of
+ * FALSE to continue iterating. */
if(olist->max_index>0 && olist->list_index>=olist->max_index)
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
} /* end if */
@@ -1679,8 +1682,6 @@ done:
* Programmer: Quincey Koziol
* Tuesday, July 19, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1762,27 +1763,36 @@ H5F_try_close(H5F_t *f)
if(f->nopen_objs > 0) {
size_t obj_count; /* # of open objects */
hid_t objs[128]; /* Array of objects to close */
+ herr_t result; /* Local result from obj ID query */
size_t u; /* Local index variable */
/* Get the list of IDs of open dataset, group, & attribute objects */
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
+ while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
+ && obj_count != 0 ) {
+
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u]) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
} /* end while */
+ if(result < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)")
/* Get the list of IDs of open named datatype objects */
/* (Do this separately from the dataset & attribute IDs, because
* they could be using one of the named datatypes and then the
* open named datatype ID will get closed twice)
*/
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
+ while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
+ && obj_count != 0) {
+
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u]) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
} /* end while */
+ if(result < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)")
} /* end if */
} /* end if */
@@ -2427,6 +2437,139 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Fget_file_image
+ *
+ * Purpose: If a buffer is provided (via the buf_ptr argument) and is
+ * big enough (size in buf_len argument), load *buf_ptr with
+ * an image of the open file whose ID is provided in the
+ * file_id parameter, and return the number of bytes copied
+ * to the buffer.
+ *
+ * If the buffer exists, but is too small to contain an image
+ * of the indicated file, return a negative number.
+ *
+ * Finally, if no buffer is provided, return the size of the
+ * buffer needed. This value is simply the eoa of the target
+ * file.
+ *
+ * Note that any user block is skipped.
+ *
+ * Also note that the function may not be used on files
+ * opened with either the split/multi file driver or the
+ * family file driver.
+ *
+ * In the former case, the sparse address space makes the
+ * get file image operation impractical, due to the size of
+ * the image typically required.
+ *
+ * In the case of the family file driver, the problem is
+ * the driver message in the super block, which will prevent
+ * the image being opened with any driver other than the
+ * family file driver -- which negates the purpose of the
+ * operation. This can be fixed, but no resources for
+ * this now.
+ *
+ * Return: Success: Bytes copied / number of bytes needed.
+ * Failure: negative value
+ *
+ * Programmer: John Mainzer
+ * 11/15/11
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len)
+{
+ H5F_t *file; /* File object for file ID */
+ H5FD_t *fd_ptr; /* file driver */
+ haddr_t eoa; /* End of file address */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("Zs", "i*xz", file_id, buf_ptr, buf_len);
+
+ /* Check args */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ if(!file || !file->shared || !file->shared->lf)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer")
+ fd_ptr = file->shared->lf;
+ if(!fd_ptr->cls)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer")
+
+ /* the address space used by the split and multi file drivers is not
+ * a good fit for this call. Since the plan is to depreciate these
+ * drivers anyway, don't bother to do a "force fit".
+ *
+ * The following clause tests for the multi file driver, and fails
+ * if the supplied file has the multi file driver as its top level
+ * file driver. However, this test will not work if there is some
+ * other file driver sitting on top of the multi file driver.
+ *
+ * I'm not sure if this is possible at present, but in all likelyhood,
+ * it will become possible in the future. On the other hand, we may
+ * remove the split/multi file drivers before then.
+ *
+ * I am leaving this solution in for now, but we should review it,
+ * and improve the solution if necessary.
+ *
+ * JRM -- 11/11/22
+ */
+ if(HDstrcmp(fd_ptr->cls->name, "multi") == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.")
+
+ /* While the family file driver is conceptually fully compatible
+ * with the get file image operation, it sets a file driver message
+ * in the super block that prevents the image being opened with any
+ * driver other than the family file driver. Needless to say, this
+ * rather defeats the purpose of the get file image operation.
+ *
+ * While this problem is quire solvable, the required time and
+ * resources are lacking at present. Hence, for now, we don't
+ * allow the get file image operation to be perfomed on files
+ * opened with the family file driver.
+ *
+ * Observe that the following test only looks at the top level
+ * driver, and fails if there is some other driver sitting on to
+ * of the family file driver.
+ *
+ * I don't think this can happen at present, but that may change
+ * in the future.
+ * JRM -- 12/21/11
+ */
+ if(HDstrcmp(fd_ptr->cls->name, "family") == 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.")
+
+
+ /* Go get the actual file size */
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
+
+ /* set ret_value = to eoa -- will overwrite this if appropriate */
+ ret_value = (ssize_t)eoa;
+
+ /* test to see if a buffer was provided -- if not, we are done */
+ if(buf_ptr != NULL) {
+ size_t space_needed; /* size of file image */
+
+ /* Check for buffer too small */
+ if((haddr_t)buf_len < eoa)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small")
+
+ space_needed = (size_t)eoa;
+
+ /* read in the file image */
+ /* (Note compensation for base address addition in internal routine) */
+ if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Fget_file_image() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Fget_mdc_config
*
* Purpose: Retrieves the current automatic cache resize configuration
diff --git a/src/H5FD.c b/src/H5FD.c
index 66fa3b9..18b0eb6 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -70,6 +70,10 @@ static herr_t H5FD_pl_copy(void *(*copy_func)(const void *), size_t pl_size,
static herr_t H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *),
void *pl);
static herr_t H5FD_free_cls(H5FD_class_t *cls);
+static herr_t H5FD_fapl_copy(hid_t driver_id, const void *fapl, void **copied_fapl);
+static herr_t H5FD_dxpl_copy(hid_t driver_id, const void *dxpl, void **copied_dxpl);
+static int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
+static int H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/);
/*********************/
/* Package Variables */
@@ -750,17 +754,15 @@ done:
* Programmer: Robb Matzke
* Tuesday, August 3, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl)
{
H5FD_class_t *driver;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
/* Check args */
if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
@@ -871,17 +873,15 @@ done:
* Programmer: Robb Matzke
* Tuesday, August 3, 1999
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl, void **copied_dxpl)
{
H5FD_class_t *driver;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
/* Check args */
if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
@@ -1039,6 +1039,8 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
H5FD_t *file = NULL; /* VFD file struct */
hid_t driver_id = -1; /* VFD ID */
H5P_genplist_t *plist; /* Property list pointer */
+ unsigned long driver_flags = 0; /* File-inspecific driver feature flags */
+ H5FD_file_image_info_t file_image_info; /* Initial file image */
H5FD_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1061,6 +1063,19 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
if(NULL == driver->open)
HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method")
+ /* Query driver flag */
+ H5FD_driver_query(driver, &driver_flags);
+
+ /* Get initial file image info */
+ if(H5P_get(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file image info")
+
+ /* If an image is provided, make sure the driver supports this feature */
+ HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) ||
+ ((file_image_info.buffer == NULL) && (file_image_info.size == 0)));
+ if((file_image_info.buffer != NULL) && !(driver_flags & H5FD_FEAT_ALLOW_FILE_IMAGE))
+ HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file image set, but not supported.")
+
/* Dispatch to file driver */
if(HADDR_UNDEF == maxaddr)
maxaddr = driver->maxaddr;
@@ -1318,19 +1333,17 @@ done:
* Programmer: Quincey Koziol
* Friday, August 25, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-int
+static int
H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/)
{
- int ret_value=0;
+ int ret_value = 0; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
- assert(f);
- assert(flags);
+ HDassert(f);
+ HDassert(flags);
/* Check for query driver and call it */
if(f->cls->query)
@@ -1340,7 +1353,44 @@ H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/)
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5FD_query() */
+
+
+/*-------------------------------------------------------------------------
+* Function: H5FD_driver_query
+*
+* Purpose: Similar to H5FD_query(), but intended for cases when we don't
+* have a file available (e.g. before one is opened). Since we
+* can't use the file to get the driver, the driver is passed in
+* as a parameter.
+*
+* Return: Success: non-negative
+* Failure: negative
+*
+* Programmer: Jacob Gruber
+* Wednesday, August 17, 2011
+*
+*-------------------------------------------------------------------------
+*/
+static int
+H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/)
+{
+ int ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(driver);
+ HDassert(flags);
+
+ /* Check for the driver to query and then query it */
+ if(driver->query)
+ ret_value = (driver->query)(NULL, flags);
+ else
+ *flags = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_driver_query() */
/*-------------------------------------------------------------------------
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 940d4c7..1fef36c 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -101,6 +101,7 @@ typedef struct H5FD_core_t {
HANDLE hFile; /* Native windows file handle */
#endif /* H5_HAVE_WIN32_API */
hbool_t dirty; /*changes not saved? */
+ H5FD_file_image_callbacks_t fi_callbacks; /* file image callbacks */
} H5FD_core_t;
/* Driver-specific file access properties */
@@ -412,6 +413,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
#endif
h5_stat_t sb;
int fd=-1;
+ H5FD_file_image_info_t file_image_info;
H5FD_t *ret_value;
FUNC_ENTER_NOAPI_NOINIT
@@ -434,10 +436,32 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
+ /* Retrieve initial file image info */
+ if(H5P_get(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial file image info")
+
+ /* If the file image exists and this is an open, make sure the file doesn't exist */
+ HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) ||
+ ((file_image_info.buffer == NULL) && (file_image_info.size == 0)));
+ if((file_image_info.buffer != NULL) && !(H5F_ACC_CREAT & flags)) {
+ if(HDopen(name, o_flags, 0666) >= 0)
+ HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file already exists")
+
+ /* If backing store is requested, create and stat the file
+ * Note: We are forcing the O_CREAT flag here, even though this is
+ * technically an open.
+ */
+ if(fa->backing_store) {
+ if((fd = HDopen(name, o_flags | O_CREAT, 0666)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file")
+ if(HDfstat(fd, &sb) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
+ } /* end if */
+ } /* end if */
/* Open backing store, and get stat() from file. The only case that backing
* store is off is when the backing_store flag is off and H5F_ACC_CREAT is
* on. */
- if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
+ else if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
if(fa && (fd = HDopen(name, o_flags, 0666)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
if(HDfstat(fd, &sb) < 0)
@@ -460,6 +484,9 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
/* If save data in backing store. */
file->backing_store = fa->backing_store;
+ /* Save file image callbacks */
+ file->fi_callbacks = file_image_info.callbacks;
+
if(fd >= 0) {
/* Retrieve information for determining uniqueness of file */
#ifdef H5_HAVE_WIN32_API
@@ -491,51 +518,70 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
size_t size;
/* Retrieve file size */
- size = (size_t)sb.st_size;
+ if(file_image_info.buffer && file_image_info.size > 0)
+ size = file_image_info.size;
+ else
+ size = (size_t)sb.st_size;
/* Check if we should allocate the memory buffer and read in existing data */
if(size) {
- /* Allocate memory for the file's data */
- if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block")
+ /* Allocate memory for the file's data, using the file image callback if available. */
+ if(file->fi_callbacks.image_malloc) {
+ if(NULL == (file->mem = (unsigned char*)file->fi_callbacks.image_malloc(size, H5FD_FILE_IMAGE_OP_FILE_OPEN, file->fi_callbacks.udata)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "image malloc callback failed")
+ } /* end if */
+ else {
+ if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "unable to allocate memory block")
+ } /* end else */
/* Set up data structures */
file->eof = size;
- /* Read in existing data, being careful of interrupted system calls,
- * partial results, and the end of the file.
- */
- while(size > 0) {
-
- h5_core_io_t bytes_in = 0; /* # of bytes to read */
- h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */
-
- /* Trying to read more bytes than the return type can handle is
- * undefined behavior in POSIX.
- */
- if(size > H5_CORE_MAX_IO_BYTES_g)
- bytes_in = H5_CORE_MAX_IO_BYTES_g;
- else
- bytes_in = (h5_core_io_t)size;
-
- do {
- bytes_read = HDread(file->fd, file->mem, bytes_in);
- } while(-1 == bytes_read && EINTR == errno);
-
- if(-1 == bytes_read) { /* error */
- int myerrno = errno;
- time_t mytime = HDtime(NULL);
- HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
-
- HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset);
+ /* If there is an initial file image, copy it, using the callback if possible */
+ if(file_image_info.buffer && file_image_info.size > 0) {
+ if(file->fi_callbacks.image_memcpy) {
+ if(file->mem != file->fi_callbacks.image_memcpy(file->mem, file_image_info.buffer, size, H5FD_FILE_IMAGE_OP_FILE_OPEN, file->fi_callbacks.udata))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, NULL, "image_memcpy callback failed")
} /* end if */
-
- HDassert(bytes_read >= 0);
- HDassert((size_t)bytes_read <= size);
-
- size -= (size_t)bytes_read;
-
- } /* end while */
+ else
+ HDmemcpy(file->mem, file_image_info.buffer, size);
+ } /* end if */
+ /* Read in existing data from the file if there is no image */
+ else {
+ /* Read in existing data, being careful of interrupted system calls,
+ * partial results, and the end of the file.
+ */
+ while(size > 0) {
+ h5_core_io_t bytes_in = 0; /* # of bytes to read */
+ h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */
+
+ /* Trying to read more bytes than the return type can handle is
+ * undefined behavior in POSIX.
+ */
+ if(size > H5_CORE_MAX_IO_BYTES_g)
+ bytes_in = H5_CORE_MAX_IO_BYTES_g;
+ else
+ bytes_in = (h5_core_io_t)size;
+
+ do {
+ bytes_read = HDread(file->fd, file->mem, bytes_in);
+ } while(-1 == bytes_read && EINTR == errno);
+
+ if(-1 == bytes_read) { /* error */
+ int myerrno = errno;
+ time_t mytime = HDtime(NULL);
+ HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
+
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset);
+ } /* end if */
+
+ HDassert(bytes_read >= 0);
+ HDassert((size_t)bytes_read <= size);
+
+ size -= (size_t)bytes_read;
+ } /* end while */
+ } /* end else */
} /* end if */
} /* end if */
@@ -578,8 +624,15 @@ H5FD_core_close(H5FD_t *_file)
HDclose(file->fd);
if(file->name)
H5MM_xfree(file->name);
- if(file->mem)
- H5MM_xfree(file->mem);
+ if(file->mem) {
+ /* Use image callback if available */
+ if(file->fi_callbacks.image_free) {
+ if(file->fi_callbacks.image_free(file->mem, H5FD_FILE_IMAGE_OP_FILE_CLOSE, file->fi_callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "image_free callback failed")
+ } /* end if */
+ else
+ H5MM_xfree(file->mem);
+ } /* end if */
HDmemset(file, 0, sizeof(H5FD_core_t));
H5MM_xfree(file);
@@ -700,9 +753,11 @@ H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */)
*flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
*flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+ *flags |= H5FD_FEAT_ALLOW_FILE_IMAGE; /* OK to use file image feature with this VFD */
+ *flags |= H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS; /* OK to use file image callbacks with this VFD */
/* If the backing store is open, a POSIX file handle is available */
- if(file->fd >= 0 && file->backing_store)
+ if(file && file->fd >= 0 && file->backing_store)
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
} /* end if */
@@ -976,9 +1031,16 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
if((addr + size) % file->increment)
new_eof += file->increment;
- /* (Re)allocate memory for the file buffer */
- if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block of %llu bytes", (unsigned long long)new_eof)
+ /* (Re)allocate memory for the file buffer, using callbacks if available */
+ if(file->fi_callbacks.image_realloc) {
+ if(NULL == (x = (unsigned char *)file->fi_callbacks.image_realloc(file->mem, new_eof, H5FD_FILE_IMAGE_OP_FILE_RESIZE, file->fi_callbacks.udata)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block of %llu bytes with callback", (unsigned long long)new_eof)
+ } /* end if */
+ else {
+ if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block of %llu bytes", (unsigned long long)new_eof)
+ } /* end else */
+
#ifdef H5_CLEAR_MEMORY
HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
#endif /* H5_CLEAR_MEMORY */
@@ -989,6 +1051,8 @@ HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
/* Write from BUF to memory */
HDmemcpy(file->mem + addr, buf, size);
+
+ /* Mark memory buffer as modified */
file->dirty = TRUE;
done:
@@ -1075,6 +1139,28 @@ done:
* Purpose: Makes sure that the true file size is the same (or larger)
* than the end-of-address.
*
+ * Addendum -- 12/2/11
+ * For file images opened with the core file driver, it is
+ * necessary that we avoid reallocating the core file driver's
+ * buffer uneccessarily.
+ *
+ * To this end, I have made the following functional changes
+ * to this function.
+ *
+ * If we are closing, and there is no backing store, this
+ * function becomes a no-op.
+ *
+ * If we are closing, and there is backing store, we set the
+ * eof to equal the eoa, and truncate the backing store to
+ * the new eof
+ *
+ * If we are not closing, we realloc the buffer to size equal
+ * to the smallest multiple of the allocation increment that
+ * equals or exceeds the eoa and set the eof accordingly.
+ * Note that we no longer truncate the backing store to the
+ * new eof if applicable.
+ * -- JRM
+ *
* Return: Success: Non-negative
* Failure: Negative
*
@@ -1085,7 +1171,7 @@ done:
*/
/* ARGSUSED */
static herr_t
-H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
+H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing)
{
H5FD_core_t *file = (H5FD_core_t*)_file;
size_t new_eof; /* New size of memory buffer */
@@ -1095,78 +1181,83 @@ H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
HDassert(file);
- /* Determine new size of memory buffer */
- H5_ASSIGN_OVERFLOW(new_eof, file->increment * (file->eoa / file->increment), hsize_t, size_t);
- if(file->eoa % file->increment)
- new_eof += file->increment;
-
- /* Extend the file to make sure it's large enough */
- if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) {
- unsigned char *x; /* Pointer to new buffer for file data */
+ /* if we are closing and not using backing store, do nothing */
+ if(!closing || file->backing_store) {
+ if(closing) /* set eof to eoa */
+ new_eof = file->eoa;
+ else { /* set eof to smallest multiple of increment that exceeds eoa */
+ /* Determine new size of memory buffer */
+ H5_ASSIGN_OVERFLOW(new_eof, file->increment * (file->eoa / file->increment), hsize_t, size_t);
+ if(file->eoa % file->increment)
+ new_eof += file->increment;
+ } /* end else */
+
+ /* Extend the file to make sure it's large enough */
+ if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) {
+ unsigned char *x; /* Pointer to new buffer for file data */
+
+ /* (Re)allocate memory for the file buffer, using callback if available */
+ if(file->fi_callbacks.image_realloc) {
+ if(NULL == (x = (unsigned char *)file->fi_callbacks.image_realloc(file->mem, new_eof, H5FD_FILE_IMAGE_OP_FILE_RESIZE, file->fi_callbacks.udata)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block with callback")
+ } /* end if */
+ else {
+ if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate memory block")
+ } /* end else */
- /* (Re)allocate memory for the file buffer */
- if(NULL == (x = (unsigned char *)H5MM_realloc(file->mem, new_eof)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
#ifdef H5_CLEAR_MEMORY
-if(file->eof < new_eof)
- HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
+ if(file->eof < new_eof)
+ HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
#endif /* H5_CLEAR_MEMORY */
- file->mem = x;
+ file->mem = x;
- /* Update backing store, if using it */
- if(file->fd >= 0 && file->backing_store) {
+ /* Update backing store, if using it and if closing */
+ if(closing && (file->fd >= 0) && file->backing_store) {
#ifdef H5_HAVE_WIN32_API
- LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
- DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
- * Only used as an error code here.
- */
- DWORD dwError; /* DWORD error code from GetLastError() */
- BOOL bError; /* Boolean error flag */
-
- /* Windows uses this odd QuadPart union for 32/64-bit portability */
- li.QuadPart = (__int64)file->eoa;
-
- /* Extend the file to make sure it's large enough.
- *
- * Since INVALID_SET_FILE_POINTER can technically be a valid return value
- * from SetFilePointer(), we also need to check GetLastError().
- */
- dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
- if(INVALID_SET_FILE_POINTER == dwPtrLow) {
- dwError = GetLastError();
- if(dwError != NO_ERROR )
- HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
- }
-
- bError = SetEndOfFile(file->hFile);
- if(0 == bError)
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+ LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
+ DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
+ * Only used as an error code here.
+ */
+ DWORD dwError; /* DWORD error code from GetLastError() */
+ BOOL bError; /* Boolean error flag */
+
+ /* Windows uses this odd QuadPart union for 32/64-bit portability */
+ li.QuadPart = (__int64)file->eoa;
+
+ /* Extend the file to make sure it's large enough.
+ *
+ * Since INVALID_SET_FILE_POINTER can technically be a valid return value
+ * from SetFilePointer(), we also need to check GetLastError().
+ */
+ dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(INVALID_SET_FILE_POINTER == dwPtrLow) {
+ dwError = GetLastError();
+ if(dwError != NO_ERROR )
+ HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
+ }
+
+ bError = SetEndOfFile(file->hFile);
+ if(0 == bError)
+ HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* H5_HAVE_WIN32_API */
#ifdef H5_VMS
- /* Reset seek offset to the beginning of the file, so that the file isn't
- * re-extended later. This may happen on Open VMS. */
- if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET))
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
-#endif
- if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa))
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+ /* Reset seek offset to the beginning of the file, so that the file isn't
+ * re-extended later. This may happen on Open VMS. */
+ if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET))
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
+#endif /* H5_VMS */
+ if(-1 == HDftruncate(file->fd, (HDoff_t)new_eof))
+ HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#endif /* H5_HAVE_WIN32_API */
+ } /* end if */
-#ifdef H5_VMS
- /* Reset seek offset to the beginning of the file, so that the file isn't
- * re-extended later. This may happen on Open VMS. */
- if(-1 == HDlseek(file->fd, 0, SEEK_SET))
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
-#endif
-
- if(-1 == HDftruncate(file->fd, (off_t)new_eof))
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+ /* Update the eof value */
+ file->eof = new_eof;
} /* end if */
-
- /* Update the eof value */
- file->eof = new_eof;
- } /* end if */
+ } /* end if(file->eof < file->eoa) */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_core_truncate() */
+
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 17683ce..6f6d757 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -995,7 +995,7 @@ H5FD_family_query(const H5FD_t * _file, unsigned long *flags /* out */)
*flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
/* Check for flags that are set by h5repart */
- if(file->repart_members)
+ if(file && file->repart_members)
*flags |= H5FD_FEAT_DIRTY_SBLK_LOAD; /* Mark the superblock dirty when it is loaded (so the family member sizes are rewritten) */
} /* end if */
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index cb5ce3c..0b5c677 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -918,7 +918,7 @@ H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */)
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
/* Check for flags that are set by h5repart */
- if(file->fam_to_sec2)
+ if(file && file->fam_to_sec2)
*flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
} /* end if */
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 4f7d059..9c19562 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -52,6 +52,29 @@ typedef enum {
} H5FD_file_op_t;
+/* Define structure to hold initial file image and other relevant information */
+typedef struct {
+ void *buffer;
+ size_t size;
+ H5FD_file_image_callbacks_t callbacks;
+} H5FD_file_image_info_t;
+
+/* Define default file image info */
+#define H5FD_DEFAULT_FILE_IMAGE_INFO { \
+ /* file image buffer */ NULL, \
+ /* buffer size */ 0, \
+ { /* Callbacks */ \
+ /* image_malloc */ NULL, \
+ /* image_memcpy */ NULL, \
+ /* image_realloc */ NULL, \
+ /* image_free */ NULL, \
+ /* udata_copy */ NULL, \
+ /* udata_free */ NULL, \
+ /* udata */ NULL, \
+ } \
+}
+
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -72,17 +95,14 @@ H5_DLL herr_t H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf);
H5_DLL herr_t H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf);
H5_DLL void *H5FD_fapl_get(H5FD_t *file);
H5_DLL herr_t H5FD_fapl_open(struct H5P_genplist_t *plist, hid_t driver_id, const void *driver_info);
-H5_DLL herr_t H5FD_fapl_copy(hid_t driver_id, const void *fapl, void **copied_fapl);
H5_DLL herr_t H5FD_fapl_close(hid_t driver_id, void *fapl);
H5_DLL herr_t H5FD_dxpl_open(struct H5P_genplist_t *plist, hid_t driver_id, const void *driver_info);
-H5_DLL herr_t H5FD_dxpl_copy(hid_t driver_id, const void *dxpl, void **copied_dxpl);
H5_DLL herr_t H5FD_dxpl_close(hid_t driver_id, void *dxpl);
H5_DLL hid_t H5FD_register(const void *cls, size_t size, hbool_t app_ref);
H5_DLL H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
H5_DLL herr_t H5FD_close(H5FD_t *file);
H5_DLL int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2);
-H5_DLL int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
H5_DLL haddr_t H5FD_alloc(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
hsize_t size, haddr_t *align_addr, hsize_t *align_size);
H5_DLL herr_t H5FD_free(H5FD_t *file, hid_t dxpl_id, H5FD_mem_t type, struct H5F_t *f,
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index f495e2d..ab19c68 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -222,6 +222,19 @@ typedef enum H5F_mem_t H5FD_mem_t;
* instead of the default H5D_ALLOC_TIME_LATE
*/
#define H5FD_FEAT_ALLOCATE_EARLY 0x00000200
+ /*
+ * Defining the H5FD_FEAT_ALLOW_FILE_IMAGE for a VFL driver means that
+ * the driver is able to use a file image in the fapl as the initial
+ * contents of a file.
+ */
+#define H5FD_FEAT_ALLOW_FILE_IMAGE 0x00000400
+ /*
+ * Defining the H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS for a VFL driver
+ * means that the driver is able to use callbacks to make a copy of the
+ * image to store in memory.
+ */
+#define H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS 0x00000800
+
/* Forward declaration */
typedef struct H5FD_t H5FD_t;
@@ -291,6 +304,33 @@ struct H5FD_t {
hsize_t alignment; /* Allocation alignment */
};
+/* Define enum for the source of file image callbacks */
+typedef enum {
+ H5FD_FILE_IMAGE_OP_NO_OP,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE,
+ H5FD_FILE_IMAGE_OP_FILE_OPEN,
+ H5FD_FILE_IMAGE_OP_FILE_RESIZE,
+ H5FD_FILE_IMAGE_OP_FILE_CLOSE,
+} H5FD_file_image_op_t;
+
+/* Define structure to hold file image callbacks */
+typedef struct {
+ void *(*image_malloc)(size_t size, H5FD_file_image_op_t file_image_op,
+ void *udata);
+ void *(*image_memcpy)(void *dest, const void *src, size_t size,
+ H5FD_file_image_op_t file_image_op, void *udata);
+ void *(*image_realloc)(void *ptr, size_t size,
+ H5FD_file_image_op_t file_image_op, void *udata);
+ herr_t (*image_free)(void *ptr, H5FD_file_image_op_t file_image_op,
+ void *udata);
+ void *(*udata_copy)(void *udata);
+ herr_t (*udata_free)(void *udata);
+ void *udata;
+} H5FD_file_image_callbacks_t;
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index 6d4a76a..4201e07 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -560,7 +560,7 @@ H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */)
*flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
/* Check for flags that are set by h5repart */
- if(file->fam_to_sec2)
+ if(file && file->fam_to_sec2)
*flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
} /* end if */
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index b67e01e..4733eba 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -13,37 +13,33 @@
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/*
- * Programmer: Robb Matzke <matzke@llnl.gov>
- * Wednesday, October 22, 1997
- *
- * Purpose: This is the Posix stdio.h I/O subclass of H5Flow.
- * It also serves as an example of coding a simple file driver,
- * therefore, it should not use any non-public definitions.
+/* Programmer: Robb Matzke <matzke@llnl.gov>
+ * Wednesday, October 22, 1997
*
- * Notes: Ported to the new H5FD architecture on 10/18/99 - QAK
+ * Purpose: The C STDIO virtual file driver which only uses calls from stdio.h.
+ * This also serves as an example of coding a simple file driver,
+ * therefore, it should not use any non-public definitions.
*
+ * NOTE: This driver is not as well tested as the standard SEC2 driver
+ * and is not intended for production use!
*/
#include <assert.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-/* Disable certain warnings in PC-Lint: */
-/*lint --emacro( {534, 830}, H5P_FILE_ACCESS) */
-/*lint --emacro( {534, 830}, H5F_ACC_RDWR, H5F_ACC_EXCL) */
-/*lint -esym( 534, H5Eclear2, H5Epush2) */
-
#include "hdf5.h"
-#ifdef H5_HAVE_STDIO_H
-#include <stdio.h>
-#endif
#ifdef H5_HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef H5_HAVE_WIN32_API
+/* The following two defines must be before any windows headers are included */
+#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
+#define NOGDI /* Exclude Graphic Display Interface macros */
+
#include <windows.h>
#include <io.h>
@@ -54,7 +50,6 @@
#endif
-
#ifdef MAX
#undef MAX
#endif /* MAX */
@@ -63,6 +58,9 @@
/* The driver identification number, initialized at runtime */
static hid_t H5FD_STDIO_g = 0;
+/* The maximum number of bytes which can be written in a single I/O operation */
+static size_t H5_STDIO_MAX_IO_BYTES_g = (size_t)-1;
+
/* File operations */
typedef enum {
H5FD_STDIO_OP_UNKNOWN=0,
@@ -71,55 +69,71 @@ typedef enum {
H5FD_STDIO_OP_SEEK=3
} H5FD_stdio_file_op;
-/*
- * The description of a file belonging to this driver. The `eoa' and `eof'
+/* The description of a file belonging to this driver. The 'eoa' and 'eof'
* determine the amount of hdf5 address space in use and the high-water mark
- * of the file (the current size of the underlying Unix file). The `pos'
+ * of the file (the current size of the underlying Unix file). The 'pos'
* value is used to eliminate file position updates when they would be a
* no-op. Unfortunately we've found systems that use separate file position
* indicators for reading and writing so the lseek can only be eliminated if
* the current operation is the same as the previous operation. When opening
- * a file the `eof' will be set to the current file size, `eoa' will be set
- * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error
- * occurs), and `op' will be set to H5F_OP_UNKNOWN.
+ * a file the 'eof' will be set to the current file size, 'eoa' will be set
+ * to zero, 'pos' will be set to H5F_ADDR_UNDEF (as it is when an error
+ * occurs), and 'op' will be set to H5F_OP_UNKNOWN.
*/
typedef struct H5FD_stdio_t {
- H5FD_t pub; /*public stuff, must be first */
- FILE * fp; /*the file handle */
- haddr_t eoa; /*end of allocated region */
- haddr_t eof; /*end of file; current file size*/
- haddr_t pos; /*current file I/O position */
- H5FD_stdio_file_op op; /*last operation */
- unsigned write_access; /* Flag to indicate the file was opened with write access */
+ H5FD_t pub; /* public stuff, must be first */
+ FILE *fp; /* the file handle */
+ int fd; /* file descriptor (for truncate) */
+ haddr_t eoa; /* end of allocated region */
+ haddr_t eof; /* end of file; current file size */
+ haddr_t pos; /* current file I/O position */
+ unsigned write_access; /* Flag to indicate the file was opened with write access */
+ H5FD_stdio_file_op op; /* last operation */
#ifndef H5_HAVE_WIN32_API
- /*
- * On most systems the combination of device and i-node number uniquely
- * identify a file.
+ /* On most systems the combination of device and i-node number uniquely
+ * identify a file. Note that Cygwin, MinGW and other Windows POSIX
+ * environments have the stat function (which fakes inodes)
+ * and will use the 'device + inodes' scheme as opposed to the
+ * Windows code further below.
*/
- dev_t device; /*file device number */
- ino_t inode; /*file i-node number */
+ dev_t device; /* file device number */
+#ifdef H5_VMS
+ ino_t inode[3]; /* file i-node number */
#else
- /*
- * On H5_HAVE_WIN32_API the low-order word of a unique identifier associated with the
- * file and the volume serial number uniquely identify a file. This number
- * (which, both? -rpm) may change when the system is restarted or when the
- * file is opened. After a process opens a file, the identifier is
- * constant until the file is closed. An application can use this
- * identifier and the volume serial number to determine whether two
- * handles refer to the same file.
+ ino_t inode; /* file i-node number */
+#endif /* H5_VMS */
+#else
+ /* Files in windows are uniquely identified by the volume serial
+ * number and the file index (both low and high parts).
+ *
+ * There are caveats where these numbers can change, especially
+ * on FAT file systems. On NTFS, however, a file should keep
+ * those numbers the same until renamed or deleted (though you
+ * can use ReplaceFile() on NTFS to keep the numbers the same
+ * while renaming).
+ *
+ * See the MSDN "BY_HANDLE_FILE_INFORMATION Structure" entry for
+ * more information.
+ *
+ * http://msdn.microsoft.com/en-us/library/aa363788(v=VS.85).aspx
*/
- DWORD fileindexlo;
- DWORD fileindexhi;
-#endif
+ DWORD nFileIndexLow;
+ DWORD nFileIndexHigh;
+ DWORD dwVolumeSerialNumber;
+
+ HANDLE hFile; /* Native windows file handle */
+#endif /* H5_HAVE_WIN32_API */
} H5FD_stdio_t;
/* Use similar structure as in H5private.h by defining Windows stuff first. */
#ifdef H5_HAVE_WIN32_API
- # define file_fseek _fseeki64
- # define file_offset_t __int64
- # define file_ftruncate _chsize_s /* Supported in VS 2005 or newer */
- # define file_ftell _ftelli64
-#endif
+#ifndef H5_HAVE_MINGW
+ #define file_fseek _fseeki64
+ #define file_offset_t __int64
+ #define file_ftruncate _chsize_s /* Supported in VS 2005 or newer */
+ #define file_ftell _ftelli64
+#endif /* H5_HAVE_MINGW */
+#endif /* H5_HAVE_WIN32_API */
/* Use file_xxx to indicate these are local macros, avoiding confusing
* with the global HD_xxx macros.
@@ -128,20 +142,19 @@ typedef struct H5FD_stdio_t {
*/
#ifndef file_fseek
#ifdef H5_HAVE_FSEEKO64
- # define file_fseek fseeko64
- # define file_offset_t off64_t
- # define file_ftruncate ftruncate64
- # define file_ftell ftello64
+ #define file_fseek fseeko64
+ #define file_offset_t off64_t
+ #define file_ftruncate ftruncate64
+ #define file_ftell ftello64
#else
- # define file_fseek fseeko
- # define file_offset_t off_t
- # define file_ftruncate ftruncate
- # define file_ftell ftello
- #endif
-#endif
-
-/*
- * These macros check for overflow of various quantities. These macros
+ #define file_fseek fseeko
+ #define file_offset_t off_t
+ #define file_ftruncate ftruncate
+ #define file_ftell ftello
+ #endif /* H5_HAVE_FSEEKO64 */
+#endif /* file_fseek */
+
+/* These macros check for overflow of various quantities. These macros
* assume that file_offset_t is signed and haddr_t and size_t are unsigned.
*
* ADDR_OVERFLOW: Checks whether a file address of type `haddr_t'
@@ -182,38 +195,38 @@ static herr_t H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
static herr_t H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
static const H5FD_class_t H5FD_stdio_g = {
- "stdio", /*name */
- MAXADDR, /*maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
- H5FD_stdio_term, /*terminate */
- NULL, /*sb_size */
- NULL, /*sb_encode */
- NULL, /*sb_decode */
- 0, /*fapl_size */
- NULL, /*fapl_get */
- NULL, /*fapl_copy */
- NULL, /*fapl_free */
- 0, /*dxpl_size */
- NULL, /*dxpl_copy */
- NULL, /*dxpl_free */
- H5FD_stdio_open, /*open */
- H5FD_stdio_close, /*close */
- H5FD_stdio_cmp, /*cmp */
- H5FD_stdio_query, /*query */
- NULL, /*get_type_map */
- H5FD_stdio_alloc, /*alloc */
- NULL, /*free */
- H5FD_stdio_get_eoa, /*get_eoa */
- H5FD_stdio_set_eoa, /*set_eoa */
- H5FD_stdio_get_eof, /*get_eof */
- H5FD_stdio_get_handle, /*get_handle */
- H5FD_stdio_read, /*read */
- H5FD_stdio_write, /*write */
- H5FD_stdio_flush, /*flush */
- H5FD_stdio_truncate, /*truncate */
- NULL, /*lock */
- NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
+ "stdio", /* name */
+ MAXADDR, /* maxaddr */
+ H5F_CLOSE_WEAK, /* fc_degree */
+ H5FD_stdio_term, /* terminate */
+ NULL, /* sb_size */
+ NULL, /* sb_encode */
+ NULL, /* sb_decode */
+ 0, /* fapl_size */
+ NULL, /* fapl_get */
+ NULL, /* fapl_copy */
+ NULL, /* fapl_free */
+ 0, /* dxpl_size */
+ NULL, /* dxpl_copy */
+ NULL, /* dxpl_free */
+ H5FD_stdio_open, /* open */
+ H5FD_stdio_close, /* close */
+ H5FD_stdio_cmp, /* cmp */
+ H5FD_stdio_query, /* query */
+ NULL, /* get_type_map */
+ H5FD_stdio_alloc, /* alloc */
+ NULL, /* free */
+ H5FD_stdio_get_eoa, /* get_eoa */
+ H5FD_stdio_set_eoa, /* set_eoa */
+ H5FD_stdio_get_eof, /* get_eof */
+ H5FD_stdio_get_handle, /* get_handle */
+ H5FD_stdio_read, /* read */
+ H5FD_stdio_write, /* write */
+ H5FD_stdio_flush, /* flush */
+ H5FD_stdio_truncate, /* truncate */
+ NULL, /* lock */
+ NULL, /* unlock */
+ H5FD_FLMAP_SINGLE /* fl_map */
};
@@ -230,9 +243,6 @@ static const H5FD_class_t H5FD_stdio_g = {
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
hid_t
@@ -243,8 +253,8 @@ H5FD_stdio_init(void)
if (H5I_VFL!=H5Iget_type(H5FD_STDIO_g))
H5FD_STDIO_g = H5FDregister(&H5FD_stdio_g);
- return(H5FD_STDIO_g);
-}
+ return H5FD_STDIO_g;
+} /* end H5FD_stdio_init() */
/*---------------------------------------------------------------------------
@@ -263,7 +273,7 @@ static herr_t
H5FD_stdio_term(void)
{
/* Reset VFL ID */
- H5FD_STDIO_g=0;
+ H5FD_STDIO_g = 0;
return 0;
} /* end H5FD_stdio_term() */
@@ -281,15 +291,12 @@ H5FD_stdio_term(void)
* Programmer: Robb Matzke
* Thursday, February 19, 1998
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_fapl_stdio(hid_t fapl_id)
{
- static const char *func="H5FDset_fapl_stdio"; /*for error reporting*/
+ static const char *func = "H5FDset_fapl_stdio"; /*for error reporting*/
/*NO TRACE*/
@@ -300,7 +307,7 @@ H5Pset_fapl_stdio(hid_t fapl_id)
H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not a file access property list", -1)
return H5Pset_driver(fapl_id, H5FD_STDIO, NULL);
-}
+} /* end H5Pset_fapl_stdio() */
/*-------------------------------------------------------------------------
@@ -308,50 +315,44 @@ H5Pset_fapl_stdio(hid_t fapl_id)
*
* Purpose: Create and/or opens a Standard C file as an HDF5 file.
*
- * Bugs: H5F_ACC_EXCL has a race condition. (? -QAK)
- *
* Errors:
- * IO CANTOPENFILE File doesn't exist and CREAT wasn't
- * specified.
- * IO CANTOPENFILE Fopen failed.
- * IO FILEEXISTS File exists but CREAT and EXCL were
- * specified.
+ * IO CANTOPENFILE File doesn't exist and CREAT wasn't
+ * specified.
+ * IO CANTOPENFILE fopen() failed.
+ * IO FILEEXISTS File exists but CREAT and EXCL were
+ * specified.
*
- * Return: Success: A pointer to a new file data structure. The
- * public fields will be initialized by the
- * caller, which is always H5FD_open().
+ * Return:
+ * Success: A pointer to a new file data structure. The
+ * public fields will be initialized by the
+ * caller, which is always H5FD_open().
*
- * Failure: NULL
+ * Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
- * Modifications:
- * Ported to VFL/H5FD layer - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static H5FD_t *
H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr)
{
- FILE *f = NULL;
- unsigned write_access=0; /* File opened with write access? */
- H5FD_stdio_t *file=NULL;
- static const char *func="H5FD_stdio_open"; /* Function Name for error reporting */
+ FILE *f = NULL;
+ unsigned write_access = 0; /* File opened with write access? */
+ H5FD_stdio_t *file = NULL;
+ static const char *func = "H5FD_stdio_open"; /* Function Name for error reporting */
#ifdef H5_HAVE_WIN32_API
- HFILE filehandle;
- struct _BY_HANDLE_FILE_INFORMATION fileinfo;
- int fd;
+ struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#else /* H5_HAVE_WIN32_API */
- struct stat sb;
+ struct stat sb;
#endif /* H5_HAVE_WIN32_API */
/* Sanity check on file offsets */
- assert(sizeof(file_offset_t)>=sizeof(size_t));
+ assert(sizeof(file_offset_t) >= sizeof(size_t));
- /* Shut compiler up */
- fapl_id=fapl_id;
+ /* Quiet compiler */
+ fapl_id = fapl_id;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -359,15 +360,16 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
/* Check arguments */
if (!name || !*name)
H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL)
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
+ if (0 == maxaddr || HADDR_UNDEF == maxaddr)
H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL)
if (ADDR_OVERFLOW(maxaddr))
H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL)
+ /* Attempt to open/create the file */
if (access(name, F_OK) < 0) {
if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
f = fopen(name, "wb+");
- write_access=1; /* Note the write access */
+ write_access = 1; /* Note the write access */
}
else
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL)
@@ -378,7 +380,7 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
f = fopen(name, "wb+");
else
f = fopen(name, "rb+");
- write_access=1; /* Note the write access */
+ write_access = 1; /* Note the write access */
} else {
f = fopen(name, "rb");
}
@@ -393,30 +395,46 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
file->fp = f;
file->op = H5FD_STDIO_OP_SEEK;
file->pos = HADDR_UNDEF;
- file->write_access=write_access; /* Note the write_access for later */
+ file->write_access = write_access; /* Note the write_access for later */
if(file_fseek(file->fp, (file_offset_t)0, SEEK_END) < 0) {
file->op = H5FD_STDIO_OP_UNKNOWN;
} else {
- file_offset_t x = file_ftell (file->fp);
- assert (x>=0);
+ file_offset_t x = file_ftell(file->fp);
+ assert (x >= 0);
file->eof = (haddr_t)x;
}
- /* The unique key */
+ /* Get the file descriptor (needed for truncate and some Windows information) */
+ file->fd = fileno(file->fp);
+ if(file->fd < 0)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get file descriptor", NULL);
+
+
#ifdef H5_HAVE_WIN32_API
-/*#error "Needs correct fileindexhi & fileindexlo, code below is from sec2 driver"*/
- fd = _fileno(f);
- filehandle = _get_osfhandle(fd);
- (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo);
- file->fileindexhi = fileinfo.nFileIndexHigh;
- file->fileindexlo = fileinfo.nFileIndexLow;
-#else
- fstat(fileno(file->fp), &sb);
+ file->hFile = (HANDLE)_get_osfhandle(file->fd);
+ if(INVALID_HANDLE_VALUE == file->hFile)
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file handle", NULL);
+
+ if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo))
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file desinformationcriptor", NULL);
+
+ file->nFileIndexHigh = fileinfo.nFileIndexHigh;
+ file->nFileIndexLow = fileinfo.nFileIndexLow;
+ file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber;
+#else /* H5_HAVE_WIN32_API */
+ fstat(file->fd, &sb);
file->device = sb.st_dev;
+#ifdef H5_VMS
+ file->inode[0] = sb.st_ino[0];
+ file->inode[1] = sb.st_ino[1];
+ file->inode[2] = sb.st_ino[2];
+#else /* H5_VMS */
file->inode = sb.st_ino;
-#endif
- return((H5FD_t*)file);
-} /* end H5FD_stdio_open() */
+#endif /* H5_VMS */
+#endif /* H5_HAVE_WIN32_API */
+
+ return (H5FD_t*)file;
+} /* end H5FD_stdio_open() */
/*-------------------------------------------------------------------------
@@ -432,16 +450,13 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
- * Modifications:
- * Ported to VFL/H5FD layer - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_stdio_close(H5FD_t *_file)
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
- static const char *func="H5FD_stdio_close"; /* Function Name for error reporting */
+ static const char *func = "H5FD_stdio_close"; /* Function Name for error reporting */
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -451,8 +466,8 @@ H5FD_stdio_close(H5FD_t *_file)
free(file);
- return(0);
-}
+ return 0;
+} /* end H5FD_stdio_close() */
/*-------------------------------------------------------------------------
@@ -461,17 +476,14 @@ H5FD_stdio_close(H5FD_t *_file)
* Purpose: Compares two files belonging to this driver using an
* arbitrary (but consistent) ordering.
*
- * Return: Success: A value like strcmp()
+ * Return:
+ * Success: A value like strcmp()
*
- * Failure: never fails (arguments were checked by the
- * caller).
+ * Failure: never fails (arguments were checked by the caller).
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static int
@@ -484,30 +496,37 @@ H5FD_stdio_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
H5Eclear2(H5E_DEFAULT);
#ifdef H5_HAVE_WIN32_API
- if (f1->fileindexhi < f2->fileindexhi) return -1;
- if (f1->fileindexhi > f2->fileindexhi) return 1;
+ if(f1->dwVolumeSerialNumber < f2->dwVolumeSerialNumber) return -1;
+ if(f1->dwVolumeSerialNumber > f2->dwVolumeSerialNumber) return 1;
- if (f1->fileindexlo < f2->fileindexlo) return -1;
- if (f1->fileindexlo > f2->fileindexlo) return 1;
+ if(f1->nFileIndexHigh < f2->nFileIndexHigh) return -1;
+ if(f1->nFileIndexHigh > f2->nFileIndexHigh) return 1;
-#else
+ if(f1->nFileIndexLow < f2->nFileIndexLow) return -1;
+ if(f1->nFileIndexLow > f2->nFileIndexLow) return 1;
+#else /* H5_HAVE_WIN32_API */
#ifdef H5_DEV_T_IS_SCALAR
- if (f1->device < f2->device) return -1;
- if (f1->device > f2->device) return 1;
+ if(f1->device < f2->device) return -1;
+ if(f1->device > f2->device) return 1;
#else /* H5_DEV_T_IS_SCALAR */
/* If dev_t isn't a scalar value on this system, just use memcmp to
* determine if the values are the same or not. The actual return value
* shouldn't really matter...
*/
- if(memcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) return -1;
- if(memcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) return 1;
+ if(memcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) return -1;
+ if(memcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) return 1;
#endif /* H5_DEV_T_IS_SCALAR */
+#ifdef H5_VMS
+ if(memcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) return -1;
+ if(memcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) return 1;
+#else /* H5_VMS */
+ if(f1->inode < f2->inode) return -1;
+ if(f1->inode > f2->inode) return 1;
+#endif /* H5_VMS */
+#endif /* H5_HAVE_WIN32_API */
- if (f1->inode < f2->inode) return -1;
- if (f1->inode > f2->inode) return 1;
-#endif
return 0;
-}
+} /* H5FD_stdio_cmp() */
/*-------------------------------------------------------------------------
@@ -523,14 +542,12 @@ H5FD_stdio_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
* Programmer: Quincey Koziol
* Friday, August 25, 2000
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */)
{
- /* Shut compiler up */
+ /* Quiet the compiler */
_f=_f;
/* Set the VFL feature flags that this driver supports */
@@ -542,37 +559,35 @@ H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
- return(0);
-}
+ return 0;
+} /* end H5FD_stdio_query() */
/*-------------------------------------------------------------------------
* Function: H5FD_stdio_alloc
*
- * Purpose: Allocates file memory. If fseeko isn't available, makes
+ * Purpose: Allocates file memory. If fseeko isn't available, makes
* sure the file size isn't bigger than 2GB because the
* parameter OFFSET of fseek is of the type LONG INT, limiting
* the file size to 2GB.
*
- * Return: Success: Address of new memory
+ * Return:
+ * Success: Address of new memory
*
- * Failure: HADDR_UNDEF
+ * Failure: HADDR_UNDEF
*
* Programmer: Raymond Lu
* 30 March 2007
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static haddr_t
H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, hsize_t size)
{
- H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
- haddr_t addr;
- haddr_t ret_value; /* Return value */
+ H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
+ haddr_t addr;
- /* Shut compiler up */
+ /* Quiet compiler */
type = type;
dxpl_id = dxpl_id;
@@ -591,19 +606,16 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp
file->eoa = addr + size;
- /* Set return value */
- ret_value = addr;
-
- return(ret_value);
-} /* H5FD_stdio_alloc() */
+ return addr;
+} /* end H5FD_stdio_alloc() */
/*-------------------------------------------------------------------------
* Function: H5FD_stdio_get_eoa
*
* Purpose: Gets the end-of-address marker for the file. The EOA marker
- * is the first address past the last byte allocated in the
- * format address space.
+ * is the first address past the last byte allocated in the
+ * format address space.
*
* Return: Success: The end-of-address marker.
*
@@ -612,28 +624,21 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp
* Programmer: Robb Matzke
* Monday, August 2, 1999
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
- *
*-------------------------------------------------------------------------
*/
static haddr_t
-H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t /*unused*/ type)
+H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type)
{
- const H5FD_stdio_t *file = (const H5FD_stdio_t *)_file;
+ const H5FD_stdio_t *file = (const H5FD_stdio_t *)_file;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
- /* Shut compiler up */
+ /* Quiet compiler */
type = type;
- return(file->eoa);
-}
+ return file->eoa;
+} /* end H5FD_stdio_get_eoa() */
/*-------------------------------------------------------------------------
@@ -645,33 +650,27 @@ H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t /*unused*/ type)
*
* Return: Success: 0
*
- * Failure: -1
+ * Failure: Does not fail
*
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
- * Raymond Lu
- * 21 Dec. 2006
- * Added the parameter TYPE. It's only used for MULTI driver.
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t /*unused*/ type, haddr_t addr)
+H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, haddr_t addr)
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
- /* Shut compiler up */
+ /* Quiet the compiler */
type = type;
file->eoa = addr;
- return(0);
+ return 0;
}
@@ -691,9 +690,6 @@ H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t /*unused*/ type, haddr_t addr)
* Programmer: Robb Matzke
* Thursday, July 29, 1999
*
- * Modifications:
- * Stolen from the sec2 driver - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static haddr_t
@@ -704,8 +700,8 @@ H5FD_stdio_get_eof(const H5FD_t *_file)
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
- return(MAX(file->eof, file->eoa));
-}
+ return MAX(file->eof, file->eoa);
+} /* end H5FD_stdio_get_eof() */
/*-------------------------------------------------------------------------
@@ -718,64 +714,56 @@ H5FD_stdio_get_eof(const H5FD_t *_file)
* Programmer: Raymond Lu
* Sept. 16, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_stdio_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle)
{
H5FD_stdio_t *file = (H5FD_stdio_t *)_file;
- static const char *func="H5FD_stdio_get_handle"; /* Function Name for error reporting */
+ static const char *func = "H5FD_stdio_get_handle"; /* Function Name for error reporting */
- /* Shut compiler up */
- fapl=fapl;
+ /* Quiet the compiler */
+ fapl = fapl;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
*file_handle = &(file->fp);
- if(*file_handle==NULL)
+ if(*file_handle == NULL)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "get handle failed", -1)
- return(0);
-}
+
+ return 0;
+} /* end H5FD_stdio_get_handle() */
/*-------------------------------------------------------------------------
- * Function: H5F_stdio_read
+ * Function: H5FD_stdio_read
*
* Purpose: Reads SIZE bytes beginning at address ADDR in file LF and
* places them in buffer BUF. Reading past the logical or
* physical end of file returns zeros instead of failing.
*
* Errors:
- * IO READERROR Fread failed.
- * IO SEEKERROR Fseek failed.
+ * IO READERROR fread failed.
+ * IO SEEKERROR fseek failed.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
- * Modifications:
- * June 2, 1998 Albert Cheng
- * Added xfer_mode argument
- *
- * Ported to VFL/H5FD layer - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
void *buf/*out*/)
{
- size_t n;
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
- static const char *func="H5FD_stdio_read"; /* Function Name for error reporting */
+ static const char *func = "H5FD_stdio_read"; /* Function Name for error reporting */
- /* Shut compiler up */
- type=type;
- dxpl_id=dxpl_id;
+ /* Quiet the compiler */
+ type = type;
+ dxpl_id = dxpl_id;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
@@ -790,16 +778,14 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz
/* Check easy cases */
if (0 == size)
- return(0);
+ return 0;
if ((haddr_t)addr >= file->eof) {
memset(buf, 0, size);
- return(0);
+ return 0;
}
- /*
- * Seek to the correct file position.
- */
- if (!(file->op == H5FD_STDIO_OP_READ || file->op==H5FD_STDIO_OP_SEEK) ||
+ /* Seek to the correct file position. */
+ if (!(file->op == H5FD_STDIO_OP_READ || file->op == H5FD_STDIO_OP_SEEK) ||
file->pos != addr) {
if (file_fseek(file->fp, (file_offset_t)addr, SEEK_SET) < 0) {
file->op = H5FD_STDIO_OP_UNKNOWN;
@@ -809,59 +795,70 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz
file->pos = addr;
}
- /*
- * Read zeros past the logical end of file (physical is handled below)
- */
+ /* Read zeros past the logical end of file (physical is handled below) */
if (addr + size > file->eof) {
size_t nbytes = (size_t) (addr + size - file->eof);
memset((unsigned char *)buf + size - nbytes, 0, nbytes);
size -= nbytes;
}
- /*
- * Read the data. Since we're reading single-byte values, a partial read
+ /* Read the data. Since we're reading single-byte values, a partial read
* will advance the file position by N. If N is zero or an error
* occurs then the file position is undefined.
*/
- n = fread(buf, (size_t)1, size, file->fp);
- if(n == 0 && ferror(file->fp)) {
- file->op = H5FD_STDIO_OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "fread failed", -1)
- } else if (n < size) {
- memset((unsigned char *)buf + n, 0, (size - n));
- }
+ while(size > 0) {
- /*
- * Update the file position data.
- */
+ size_t bytes_in = 0; /* # of bytes to read */
+ size_t bytes_read = 0; /* # of bytes actually read */
+ size_t item_size = 1; /* size of items in bytes */
+
+ if(size > H5_STDIO_MAX_IO_BYTES_g)
+ bytes_in = H5_STDIO_MAX_IO_BYTES_g;
+ else
+ bytes_in = size;
+
+ bytes_read = fread(buf, item_size, bytes_in, file->fp);
+
+ if(0 == bytes_read && ferror(file->fp)) { /* error */
+ file->op = H5FD_STDIO_OP_UNKNOWN;
+ file->pos = HADDR_UNDEF;
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "fread failed", -1)
+ } /* end if */
+
+ if(0 == bytes_read && feof(file->fp)) {
+ /* end of file but not end of format address space */
+ memset((unsigned char *)buf, 0, size);
+ break;
+ } /* end if */
+
+ size -= bytes_read;
+ addr += (haddr_t)bytes_read;
+ buf = (char *)buf + bytes_read;
+ } /* end while */
+
+ /* Update the file position data. */
file->op = H5FD_STDIO_OP_READ;
- file->pos = addr+n; /*checked for overflow above*/
- return(0);
+ file->pos = addr;
+
+ return 0;
}
/*-------------------------------------------------------------------------
- * Function: H5F_stdio_write
+ * Function: H5FD_stdio_write
*
* Purpose: Writes SIZE bytes from the beginning of BUF into file LF at
* file address ADDR.
*
* Errors:
- * IO SEEKERROR Fseek failed.
- * IO WRITEERROR Fwrite failed.
+ * IO SEEKERROR fseek failed.
+ * IO WRITEERROR fwrite failed.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* Wednesday, October 22, 1997
*
- * Modifications:
- * June 2, 1998 Albert Cheng
- * Added xfer_mode argument
- *
- * Ported to VFL/H5FD layer - QAK, 10/18/99
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -869,26 +866,24 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *buf)
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
- static const char *func="H5FD_stdio_write"; /* Function Name for error reporting */
+ static const char *func = "H5FD_stdio_write"; /* Function Name for error reporting */
- /* Shut compiler up */
- dxpl_id=dxpl_id;
- type=type;
+ /* Quiet the compiler */
+ dxpl_id = dxpl_id;
+ type = type;
/* Clear the error stack */
H5Eclear2(H5E_DEFAULT);
/* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
+ if (HADDR_UNDEF == addr)
H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1)
if (REGION_OVERFLOW(addr, size))
H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1)
- if (addr+size>file->eoa)
+ if (addr+size > file->eoa)
H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1)
- /*
- * Seek to the correct file position.
- */
+ /* Seek to the correct file position. */
if ((file->op != H5FD_STDIO_OP_WRITE && file->op != H5FD_STDIO_OP_SEEK) ||
file->pos != addr) {
if (file_fseek(file->fp, (file_offset_t)addr, SEEK_SET) < 0) {
@@ -899,33 +894,51 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
file->pos = addr;
}
- /*
- * Write the buffer. On successful return, the file position will be
- * advanced by the number of bytes read. Otherwise nobody knows where it
- * is.
+ /* Write the buffer. On successful return, the file position will be
+ * advanced by the number of bytes read. On failure, the file position is
+ * undefined.
*/
- if(size != fwrite(buf, (size_t)1, size, file->fp)) {
- file->op = H5FD_STDIO_OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fwrite failed", -1)
+ while(size > 0) {
+
+ size_t bytes_in = 0; /* # of bytes to write */
+ size_t bytes_wrote = 0; /* # of bytes written */
+ size_t item_size = 1; /* size of items in bytes */
+
+ if(size > H5_STDIO_MAX_IO_BYTES_g)
+ bytes_in = H5_STDIO_MAX_IO_BYTES_g;
+ else
+ bytes_in = size;
+
+ bytes_wrote = fwrite(buf, item_size, bytes_in, file->fp);
+
+ if(bytes_wrote != bytes_in || (0 == bytes_wrote && ferror(file->fp))) { /* error */
+ file->op = H5FD_STDIO_OP_UNKNOWN;
+ file->pos = HADDR_UNDEF;
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fwrite failed", -1)
+ } /* end if */
+
+ assert(bytes_wrote > 0);
+ assert((size_t)bytes_wrote <= size);
+
+ size -= bytes_wrote;
+ addr += (haddr_t)bytes_wrote;
+ buf = (const char *)buf + bytes_wrote;
}
- /*
- * Update seek optimizing data.
- */
+ /* Update seek optimizing data. */
file->op = H5FD_STDIO_OP_WRITE;
- file->pos = addr + size;
+ file->pos = addr;
/* Update EOF if necessary */
- if (file->pos>file->eof)
+ if (file->pos > file->eof)
file->eof = file->pos;
- return(0);
+ return 0;
}
/*-------------------------------------------------------------------------
- * Function: H5F_stdio_flush
+ * Function: H5FD_stdio_flush
*
* Purpose: Makes sure that all data is on disk.
*
@@ -946,7 +959,7 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
static const char *func = "H5FD_stdio_flush"; /* Function Name for error reporting */
- /* Shut compiler up */
+ /* Quiet the compiler */
dxpl_id = dxpl_id;
/* Clear the error stack */
@@ -954,7 +967,6 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
/* Only try to flush the file if we have write access */
if(file->write_access) {
- /* Flush */
if(!closing) {
if(fflush(file->fp) < 0)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1)
@@ -965,12 +977,12 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
} /* end if */
} /* end if */
- return(0);
+ return 0;
} /* end H5FD_stdio_flush() */
/*-------------------------------------------------------------------------
- * Function: H5F_stdio_truncate
+ * Function: H5FD_stdio_truncate
*
* Purpose: Makes sure that the true file size is the same (or larger)
* than the end-of-address.
@@ -984,9 +996,6 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing)
* Programmer: Quincey Koziol
* Thursday, January 31, 2008
*
- * Modifications:
- * Vailin Choi; June 2010
- * Fix for window failures manifested from tests in mf.c.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -995,7 +1004,7 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing)
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
static const char *func = "H5FD_stdio_truncate"; /* Function Name for error reporting */
- /* Shut compiler up */
+ /* Quiet the compiler */
dxpl_id = dxpl_id;
closing = closing;
@@ -1006,30 +1015,42 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing)
if(file->write_access) {
/* Makes sure that the true file size is the same as the end-of-address. */
if(file->eoa != file->eof) {
- int fd = fileno(file->fp); /* File descriptor for HDF5 file */
#ifdef H5_HAVE_WIN32_API
- HFILE filehandle; /* Windows file handle */
- LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
+ LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
+ DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
+ * Only used as an error code here.
+ */
+ DWORD dwError; /* DWORD error code from GetLastError() */
+ BOOL bError; /* Boolean error flag */
- /* Reset seek offset to beginning of file, so that file isn't re-extended later */
+ /* Reset seek offset to beginning of file, so that file isn't re-extended later */
rewind(file->fp);
- /* Map the posix file handle to a Windows file handle */
- filehandle = _get_osfhandle(fd);
-
- /* Translate 64-bit integers into form Windows wants */
- /* [This algorithm is from the Windows documentation for SetFilePointer()] */
- li.QuadPart = (LONGLONG)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle) == 0)
+ /* Windows uses this odd QuadPart union for 32/64-bit portability */
+ li.QuadPart = (__int64)file->eoa;
+
+ /* Extend the file to make sure it's large enough.
+ *
+ * Since INVALID_SET_FILE_POINTER can technically be a valid return value
+ * from SetFilePointer(), we also need to check GetLastError().
+ */
+ dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(INVALID_SET_FILE_POINTER == dwPtrLow) {
+ dwError = GetLastError();
+ if(dwError != NO_ERROR )
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_FILEOPEN, "unable to set file pointer", -1)
+ }
+
+ bError = SetEndOfFile(file->hFile);
+ if(0 == bError)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1)
#else /* H5_HAVE_WIN32_API */
/* Reset seek offset to beginning of file, so that file isn't re-extended later */
rewind(file->fp);
/* Truncate file to proper length */
- if(-1 == file_ftruncate(fd, (file_offset_t)file->eoa))
+ if(-1 == file_ftruncate(file->fd, (file_offset_t)file->eoa))
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1)
#endif /* H5_HAVE_WIN32_API */
@@ -1044,10 +1065,10 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing)
else {
/* Double-check for problems */
if(file->eoa > file->eof)
- H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_TRUNCATED, "eoa>eof!", -1)
- } /* end else */
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_TRUNCATED, "eoa > eof!", -1)
+ } /* end else */
- return(0);
+ return 0;
} /* end H5FD_stdio_truncate() */
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index ca7104c..f6a0034 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -155,7 +155,7 @@ typedef struct H5FS_stat_t {
} H5FS_stat_t;
/* Typedef for iteration operations */
-typedef herr_t (*H5FS_operator_t)(const H5FS_section_info_t *sect,
+typedef herr_t (*H5FS_operator_t)(H5FS_section_info_t *sect,
void *operator_data/*in,out*/);
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index 914fa58..0f126c2 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -2244,7 +2244,7 @@ H5FS_sect_assert(const H5FS_t *fspace)
hsize_t separate_obj; /* The number of separate objects managed */
FUNC_ENTER_NOAPI_NOINIT_NOERR
-#ifndef QAK
+#ifdef QAK
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_sect_assert", fspace->tot_sect_count);
#endif /* QAK */
diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c
index 0f612be..966528a 100644
--- a/src/H5Fmpi.c
+++ b/src/H5Fmpi.c
@@ -202,7 +202,7 @@ H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag)
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "iMi", file_id, flag);
+ H5TRACE2("e", "ib", file_id, flag);
/* Check args */
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
@@ -242,7 +242,7 @@ H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag)
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "iMi", file_id, flag);
+ H5TRACE2("e", "i*b", file_id, flag);
/* Check args */
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 939bc3f..7e45cfa 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -417,6 +417,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */
#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */
#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
+#define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */
/* ======================== File Mount properties ====================*/
#define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */
@@ -530,8 +531,8 @@ H5_DLL H5F_t *H5F_get_parent(const H5F_t *f);
H5_DLL unsigned H5F_get_nmounts(const H5F_t *f);
H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref);
H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
-H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref);
-H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
+H5_DLL herr_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr);
+H5_DLL herr_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr);
H5_DLL struct H5VL_class_t *H5F_get_vol_cls(const H5F_t *f);
/* Functions than retrieve values set/cached from the superblock/FCPL */
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index d88538b..f32b3e0 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -192,6 +192,7 @@ H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
H5_DLL herr_t H5Funmount(hid_t loc, const char *name);
H5_DLL hssize_t H5Fget_freespace(hid_t file_id);
H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size);
+H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void * buf_ptr, size_t buf_len);
H5_DLL herr_t H5Fget_mdc_config(hid_t file_id,
H5AC_cache_config_t * config_ptr);
H5_DLL herr_t H5Fset_mdc_config(hid_t file_id,
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 62875dc..576d866 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -782,7 +782,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5G_name_replace_cb
*
- * Purpose: H5I_search callback function to replace group entry names
+ * Purpose: H5I_iterate callback function to replace group entry names
*
* Return: Success: 0, Failure: -1
*
@@ -1166,15 +1166,18 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file,
/* Search through group IDs */
if(search_group)
- H5I_search(H5I_GROUP, H5G_name_replace_cb, &names, FALSE);
+ if(H5I_iterate(H5I_GROUP, H5G_name_replace_cb, &names, FALSE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over groups")
/* Search through dataset IDs */
if(search_dataset)
- H5I_search(H5I_DATASET, H5G_name_replace_cb, &names, FALSE);
+ if(H5I_iterate(H5I_DATASET, H5G_name_replace_cb, &names, FALSE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datasets")
/* Search through datatype IDs */
if(search_datatype)
- H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE);
+ if(H5I_iterate(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datatypes")
} /* end if */
} /* end if */
diff --git a/src/H5Goh.c b/src/H5Goh.c
index 194e3ec..c6115db 100644
--- a/src/H5Goh.c
+++ b/src/H5Goh.c
@@ -81,7 +81,8 @@ const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{
H5O_group_open, /* open an object of this class */
H5O_group_create, /* create an object of this class */
H5O_group_get_oloc, /* get an object header location for an object */
- H5O_group_bh_info /* get the index & heap info for an object */
+ H5O_group_bh_info, /* get the index & heap info for an object */
+ NULL /* flush an opened object of this class */
}};
/* Declare the external free list to manage the H5O_ginfo_t struct */
diff --git a/src/H5HF.c b/src/H5HF.c
index 9c911fd..a9750c9 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -156,9 +156,6 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
H5HF_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
-#endif /* QAK */
/*
* Check arguments.
@@ -234,14 +231,8 @@ H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(H5F_addr_defined(fh_addr));
/* Load the heap header into memory */
-#ifdef QAK
-HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
-#endif /* QAK */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, fh_addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap header")
-#ifdef QAK
-HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fspace);
-#endif /* QAK */
/* Check for pending heap deletion */
if(hdr->pending_delete)
@@ -361,9 +352,6 @@ H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj,
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
-#ifdef QAK
-HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size);
-#endif /* QAK */
/* Sanity check */
HDassert(fh);
@@ -406,9 +394,6 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not su
} /* end else */
done:
-#ifdef QAK
-HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
-#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_insert() */
@@ -580,9 +565,6 @@ H5HF_write(H5HF_t *fh, hid_t dxpl_id, void *_id, hbool_t UNUSED *id_changed,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
-#endif /* QAK */
/*
* Check arguments.
@@ -720,9 +702,6 @@ H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *_id)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", FUNC);
-#endif /* QAK */
/*
* Check arguments.
@@ -814,17 +793,9 @@ H5HF_close(H5HF_t *fh, hid_t dxpl_id)
* a reference loop and the objects couldn't be removed from
* the metadata cache - QAK)
*/
-#ifdef QAK
-HDfprintf(stderr, "%s; fh->hdr->man_iter_off = %Hu\n", FUNC, fh->hdr->man_iter_off);
-HDfprintf(stderr, "%s; fh->hdr->man_size = %Hu\n", FUNC, fh->hdr->man_size);
-HDfprintf(stderr, "%s; fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc);
-#endif /* QAK */
if(H5HF_man_iter_ready(&fh->hdr->next_block))
if(H5HF_man_iter_reset(&fh->hdr->next_block) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator")
-#ifdef QAK
-HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc);
-#endif /* QAK */
/* Shut down the huge object information */
/* (Can't put this in header "destroy" routine, because it has
@@ -900,9 +871,6 @@ H5HF_delete(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(H5F_addr_defined(fh_addr));
/* Lock the heap header into memory */
-#ifdef QAK
-HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
-#endif /* QAK */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, fh_addr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c
index 023344c..34b74d7 100644
--- a/src/H5HFbtree2.c
+++ b/src/H5HFbtree2.c
@@ -352,7 +352,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_indir_found",
herr_t
H5HF_huge_bt2_indir_remove(const void *nrecord, void *_udata)
{
- H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
+ H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -570,7 +570,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_bt2_filt
herr_t
H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *_udata)
{
- H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
+ H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -759,7 +759,7 @@ H5HF_huge_bt2_filt_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED
herr_t
H5HF_huge_bt2_dir_remove(const void *nrecord, void *_udata)
{
- H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
+ H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -984,7 +984,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_bt2_filt_dir_
herr_t
H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *_udata)
{
- H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
+ H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 4289c02..caaedc7 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -172,39 +172,31 @@ H5HF_dtable_debug(H5HF_dtable_t *dtable, FILE *stream, int indent, int fwidth)
/*-------------------------------------------------------------------------
- * Function: H5HF_hdr_debug
+ * Function: H5HF_hdr_print
*
- * Purpose: Prints debugging info about a fractal heap header.
+ * Purpose: Prints info about a fractal heap header.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 24 2006
+ * koziol@hdfgroup.org
+ * Feb 23 2012
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+void
+H5HF_hdr_print(const H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t dump_internal, FILE *stream, int indent, int fwidth)
{
- H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
+ HDassert(hdr);
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
- /* Load the fractal heap header */
- if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, addr, H5AC_READ)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
-
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Header...\n", indent, "");
@@ -277,10 +269,66 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
"Filter mask for root direct block:",
hdr->pline_root_direct_filter_mask);
} /* end if */
- H5O_debug_id(H5O_PLINE_ID, f, dxpl_id, &(hdr->pline), stream,
+ H5O_debug_id(H5O_PLINE_ID, hdr->f, dxpl_id, &(hdr->pline), stream,
indent + 3, MAX(0, fwidth - 3));
} /* end if */
+ /* Print internal (runtime) information, if requested */
+ if(dump_internal) {
+ HDfprintf(stream, "%*sFractal Heap Header Internal Information:\n", indent, "");
+
+ /* Dump root iblock, if there is one */
+ HDfprintf(stream, "%*s%-*s %x\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Root indirect block flags:",
+ hdr->root_iblock_flags);
+ HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Root indirect block pointer:",
+ hdr->root_iblock);
+ if(hdr->root_iblock)
+ H5HF_iblock_print(hdr->root_iblock, dump_internal, stream, indent + 3, fwidth);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5HF_hdr_print() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_debug
+ *
+ * Purpose: Prints debugging info about a fractal heap header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 24 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+{
+ H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ /* Load the fractal heap header */
+ if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
+
+ /* Print the information about the heap's header */
+ H5HF_hdr_print(hdr, dxpl_id, FALSE, stream, indent, fwidth);
+
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
@@ -303,9 +351,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_dblock_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
+H5HF_dblock_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
- const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_debug_iter_ud1_t *udata = (H5HF_debug_iter_ud1_t *)_udata; /* User data for callbacks */
haddr_t sect_start, sect_end; /* Section's beginning and ending offsets */
haddr_t dblock_start, dblock_end; /* Direct block's beginning and ending offsets */
@@ -501,51 +549,39 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_iblock_debug
+ * Function: H5HF_iblock_print
*
* Purpose: Prints debugging info about a fractal heap indirect block.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 7 2006
+ * koziol@hdfgroup.org
+ * Feb 23 2012
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
- int indent, int fwidth, haddr_t hdr_addr, unsigned nrows)
+void
+H5HF_iblock_print(const H5HF_indirect_t *iblock,
+ hbool_t dump_internal, FILE *stream, int indent, int fwidth)
{
- H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
- H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
- hbool_t did_protect; /* Whether we protected the indirect block or not */
+ const H5HF_hdr_t *hdr; /* Pointer to heap's header */
char temp_str[64]; /* Temporary string, for formatting */
size_t u, v; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
+ HDassert(iblock);
+ HDassert(iblock->hdr);
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
- HDassert(H5F_addr_defined(hdr_addr));
- HDassert(nrows > 0);
- /* Load the fractal heap header */
- if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, hdr_addr, H5AC_READ)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
-
- /*
- * Load the heap indirect block
- */
- if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, FALSE, H5AC_READ, &did_protect)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
+ /* Set up convenience variables */
+ hdr = iblock->hdr;
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, "");
@@ -623,6 +659,75 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
"<none>");
+ /* Print internal (runtime) information, if requested */
+ if(dump_internal) {
+ HDfprintf(stream, "%*sFractal Indirect Block Internal Information:\n", indent, "");
+
+ /* Print general information */
+ HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Reference count:",
+ iblock->rc);
+
+ /* Print parent's information */
+ HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Parent indirect block address:",
+ iblock->parent);
+ if(iblock->parent)
+ H5HF_iblock_print(iblock->parent, TRUE, stream, indent + 6, fwidth);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5HF_iblock_print() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_iblock_debug
+ *
+ * Purpose: Prints debugging info about a fractal heap indirect block.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 7 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
+ int indent, int fwidth, haddr_t hdr_addr, unsigned nrows)
+{
+ H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
+ H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
+ hbool_t did_protect; /* Whether we protected the indirect block or not */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+ HDassert(H5F_addr_defined(hdr_addr));
+ HDassert(nrows > 0);
+
+ /* Load the fractal heap header */
+ if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, hdr_addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
+
+ /*
+ * Load the heap indirect block
+ */
+ if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, FALSE, H5AC_READ, &did_protect)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
+
+ /* Print the information about the heap's indirect block */
+ H5HF_iblock_print(iblock, FALSE, stream, indent, fwidth);
+
done:
if(iblock && H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block")
@@ -647,9 +752,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
+H5HF_sects_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
- const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_debug_iter_ud2_t *udata = (H5HF_debug_iter_ud2_t *)_udata; /* User data for callbacks */
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index 3bbd137..6f0b48e 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -899,7 +899,7 @@ done:
herr_t
H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
{
- H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */
+ H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1072,7 +1072,7 @@ done:
herr_t
H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
- H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */
+ H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
H5B2_remove_t op; /* Callback for v2 B-tree removal */
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 6c19b4f..342e228 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -140,8 +140,17 @@ H5HF_iblock_pin(H5HF_indirect_t *iblock)
else {
/* Check for pinning the root indirect block */
if(iblock->block_off == 0) {
- HDassert(iblock->hdr->root_iblock == NULL);
- iblock->hdr->root_iblock = iblock;
+ /* Sanity check - shouldn't be recursively pinning root indirect block */
+ HDassert(0 == (iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PINNED));
+
+ /* Check if we should set the root iblock pointer */
+ if(0 == iblock->hdr->root_iblock_flags) {
+ HDassert(NULL == iblock->hdr->root_iblock);
+ iblock->hdr->root_iblock = iblock;
+ } /* end if */
+
+ /* Indicate that the root indirect block is pinned */
+ iblock->hdr->root_iblock_flags |= H5HF_ROOT_IBLOCK_PINNED;
} /* end if */
} /* end if */
@@ -192,12 +201,21 @@ H5HF_iblock_unpin(H5HF_indirect_t *iblock)
par_iblock->child_iblocks[indir_idx] = NULL;
} /* end if */
else {
- /* Check for unpinning the root indirect block */
+ /* Check for root indirect block */
if(iblock->block_off == 0) {
- HDassert(iblock->hdr->root_iblock);
- iblock->hdr->root_iblock = NULL;
+ /* Sanity check - shouldn't be recursively unpinning root indirect block */
+ HDassert(iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PINNED);
+
+ /* Check if we should reset the root iblock pointer */
+ if(H5HF_ROOT_IBLOCK_PINNED == iblock->hdr->root_iblock_flags) {
+ HDassert(NULL != iblock->hdr->root_iblock);
+ iblock->hdr->root_iblock = NULL;
+ } /* end if */
+
+ /* Indicate that the root indirect block is unpinned */
+ iblock->hdr->root_iblock_flags &= ~(H5HF_ROOT_IBLOCK_PINNED);
} /* end if */
- } /* end if */
+ } /* end else */
/* Mark block as evictable again */
if(H5AC_unpin_entry(iblock) < 0)
@@ -273,18 +291,23 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock)
/* Mark block as evictable again when no child blocks depend on it */
if(iblock->rc == 0) {
- if(H5HF_iblock_unpin(iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
+ H5HF_hdr_t *hdr; /* Fractal heap header */
+ haddr_t iblock_addr; /* Address of fractal heap */
+ hbool_t expunge_iblock = FALSE; /* Whether to expunge indirect block from heap */
+
+ /* Set up convenience variables */
+ hdr = iblock->hdr;
+ iblock_addr = iblock->addr;
if(iblock->nchildren == 0) {
/* Check for deleting root indirect block (and no root direct block) */
- if(iblock->block_off == 0 && iblock->hdr->man_dtable.curr_root_rows > 0) {
+ if(iblock->block_off == 0 && hdr->man_dtable.curr_root_rows > 0) {
/* Reset root pointer information */
- iblock->hdr->man_dtable.curr_root_rows = 0;
- iblock->hdr->man_dtable.table_addr = HADDR_UNDEF;
+ hdr->man_dtable.curr_root_rows = 0;
+ hdr->man_dtable.table_addr = HADDR_UNDEF;
/* Reset header information back to "empty heap" state */
- if(H5HF_hdr_empty(iblock->hdr) < 0)
+ if(H5HF_hdr_empty(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty")
} /* end if */
@@ -297,8 +320,18 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock)
iblock->par_entry = 0;
} /* end if */
+ /* Mark indirect block for removal from the metadata cache */
+ expunge_iblock = TRUE;
+ } /* end if */
+
+ /* Unpin the indirect block */
+ if(H5HF_iblock_unpin(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
+
+ /* Check for expunging the indirect block from the metadata cache */
+ if(expunge_iblock) {
/* Evict the indirect block from the metadata cache */
- if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ if(H5AC_expunge_entry(hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove indirect block from cache")
} /* end if */
} /* end if */
@@ -420,6 +453,10 @@ H5HF_man_iblock_root_create(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
hdr->pline_root_direct_filter_mask = 0;
} /* end if */
+ /* Scan free space sections to set any 'parent' pointers to new indirect block */
+ if(H5HF_space_create_root(hdr, dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, FAIL, "can't set free space section info to new root indirect block")
+
/* Unlock first (previously the root) direct block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
@@ -859,6 +896,11 @@ H5HF_man_iblock_root_revert(H5HF_indirect_t *root_iblock, hid_t dxpl_id)
if(H5HF_hdr_adjust_heap(hdr, (hsize_t)hdr->man_dtable.cparam.start_block_size, (hssize_t)hdr->man_dtable.row_tot_dblock_free[0]) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "can't increase space to cover root direct block")
+ /* Scan free space sections to reset any 'parent' pointers */
+ if(H5HF_space_revert_root(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRESET, FAIL, "can't reset free space section info")
+
+
done:
if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
@@ -1126,11 +1168,20 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
else {
/* Check for root indirect block */
if(H5F_addr_eq(iblock_addr, hdr->man_dtable.table_addr)) {
- /* Check for pointer to pinned indirect block in root */
- if(hdr->root_iblock)
+ /* Check for valid pointer to pinned indirect block in root */
+ if(H5HF_ROOT_IBLOCK_PINNED == hdr->root_iblock_flags) {
+ /* Sanity check */
+ HDassert(NULL != hdr->root_iblock);
+
+ /* Return the pointer to the pinned root indirect block */
iblock = hdr->root_iblock;
- else
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(NULL == hdr->root_iblock);
+
should_protect = TRUE;
+ } /* end else */
} /* end if */
else
should_protect = TRUE;
@@ -1158,6 +1209,21 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
/* Set the indirect block's address */
iblock->addr = iblock_addr;
+ /* Check for root indirect block */
+ if(iblock->block_off == 0) {
+ /* Sanity check - shouldn't be recursively protecting root indirect block */
+ HDassert(0 == (hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PROTECTED));
+
+ /* Check if we should set the root iblock pointer */
+ if(0 == hdr->root_iblock_flags) {
+ HDassert(NULL == hdr->root_iblock);
+ hdr->root_iblock = iblock;
+ } /* end if */
+
+ /* Indicate that the root indirect block is protected */
+ hdr->root_iblock_flags |= H5HF_ROOT_IBLOCK_PROTECTED;
+ } /* end if */
+
/* Indicate that the indirect block was protected */
*did_protect = TRUE;
} /* end if */
@@ -1202,6 +1268,21 @@ H5HF_man_iblock_unprotect(H5HF_indirect_t *iblock, hid_t dxpl_id,
/* Check if we previously protected this indirect block */
/* (as opposed to using an existing pointer to a pinned child indirect block) */
if(did_protect) {
+ /* Check for root indirect block */
+ if(iblock->block_off == 0) {
+ /* Sanity check - shouldn't be recursively unprotecting root indirect block */
+ HDassert(iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PROTECTED);
+
+ /* Check if we should reset the root iblock pointer */
+ if(H5HF_ROOT_IBLOCK_PROTECTED == iblock->hdr->root_iblock_flags) {
+ HDassert(NULL != iblock->hdr->root_iblock);
+ iblock->hdr->root_iblock = NULL;
+ } /* end if */
+
+ /* Indicate that the root indirect block is unprotected */
+ iblock->hdr->root_iblock_flags &= ~(H5HF_ROOT_IBLOCK_PROTECTED);
+ } /* end if */
+
/* Unprotect the indirect block */
if(H5AC_unprotect(iblock->hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, cache_flags) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
@@ -1215,7 +1296,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_attach
*
- * Purpose: Attach a block to an indirect block
+ * Purpose: Attach a child block (direct or indirect) to an indirect block
*
* Return: SUCCEED/FAIL
*
@@ -1243,7 +1324,7 @@ H5HF_man_iblock_attach(H5HF_indirect_t *iblock, unsigned entry, haddr_t child_ad
if(H5HF_iblock_incr(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")
- /* Point at the direct block */
+ /* Point at the child block */
iblock->ents[entry].addr = child_addr;
/* Check for I/O filters on this heap */
@@ -1280,7 +1361,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_detach
*
- * Purpose: Detach a block from an indirect block
+ * Purpose: Detach a child block (direct or indirect) from an indirect block
*
* Return: SUCCEED/FAIL
*
@@ -1293,6 +1374,7 @@ done:
herr_t
H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
{
+ unsigned row; /* Row for entry */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1306,16 +1388,14 @@ H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
/* Reset address of entry */
iblock->ents[entry].addr = HADDR_UNDEF;
+ /* Compute row for entry */
+ row = entry / iblock->hdr->man_dtable.cparam.width;
+
/* Check for I/O filters on this heap */
if(iblock->hdr->filter_len > 0) {
- unsigned row; /* Row for entry */
-
/* Sanity check */
HDassert(iblock->filt_ents);
- /* Compute row for entry */
- row = entry / iblock->hdr->man_dtable.cparam.width;
-
/* If this is a direct block, reset its initial size */
if(row < iblock->hdr->man_dtable.max_direct_rows) {
iblock->filt_ents[entry].size = 0;
@@ -1323,6 +1403,24 @@ H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
} /* end if */
} /* end if */
+ /* Check for indirect block being detached */
+ if(row >= iblock->hdr->man_dtable.max_direct_rows) {
+ unsigned indir_idx; /* Index in parent's child iblock pointer array */
+
+ /* Sanity check */
+ HDassert(iblock->child_iblocks);
+
+ /* Compute index in child iblock pointer array */
+ indir_idx = entry - (iblock->hdr->man_dtable.max_direct_rows
+ * iblock->hdr->man_dtable.cparam.width);
+
+ /* Sanity check */
+ HDassert(iblock->child_iblocks[indir_idx]);
+
+ /* Reset pointer to child indirect block in parent */
+ iblock->child_iblocks[indir_idx] = NULL;
+ } /* end if */
+
/* Decrement the # of child blocks */
/* (If the number of children drop to 0, the indirect block will be
* removed from the heap when its ref. count drops to zero and the
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 2746302..498c45e 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -174,6 +174,11 @@
#define H5HF_OP_MODIFY 0x0001 /* Operation will modify object */
#define H5HF_OP_FLAGS (H5HF_OP_MODIFY) /* Bit-wise OR of all op flags */
+/* Flags for 'root_iblock_flags' field in header */
+#define H5HF_ROOT_IBLOCK_PINNED 0x01
+#define H5HF_ROOT_IBLOCK_PROTECTED 0x02
+
+
/****************************/
/* Package Private Typedefs */
/****************************/
@@ -342,7 +347,8 @@ typedef struct H5HF_hdr_t {
hbool_t pending_delete; /* Heap is pending deletion */
uint8_t sizeof_size; /* Size of file sizes */
uint8_t sizeof_addr; /* Size of file addresses */
- struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */
+ struct H5HF_indirect_t *root_iblock; /* Pointer to root indirect block */
+ unsigned root_iblock_flags; /* Flags to indicate whether root indirect block is pinned/protected */
H5FS_t *fspace; /* Free space list for objects in heap */
H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */
H5B2_t *huge_bt2; /* v2 B-tree handle for huge objects */
@@ -457,14 +463,14 @@ typedef struct H5HF_huge_bt2_filt_dir_rec_t {
typedef struct {
H5HF_hdr_t *hdr; /* Fractal heap header */
hid_t dxpl_id; /* DXPL ID for operation */
-} H5HF_sect_add_ud1_t;
+} H5HF_sect_add_ud_t;
/* User data for v2 B-tree 'remove' callback on 'huge' objects */
typedef struct {
H5HF_hdr_t *hdr; /* Fractal heap header (in) */
hid_t dxpl_id; /* DXPL ID for operation (in) */
hsize_t obj_len; /* Length of object removed (out) */
-} H5HF_huge_remove_ud1_t;
+} H5HF_huge_remove_ud_t;
/* User data for fractal heap header cache client callback */
typedef struct H5HF_hdr_cache_ud_t {
@@ -701,10 +707,14 @@ H5_DLL herr_t H5HF_tiny_op(H5HF_hdr_t *hdr, const uint8_t *id,
H5_DLL herr_t H5HF_tiny_remove(H5HF_hdr_t *fh, const uint8_t *id);
/* Debugging routines for dumping file structures */
+H5_DLL void H5HF_hdr_print(const H5HF_hdr_t *hdr, hid_t dxpl_id,
+ hbool_t dump_internal, FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, haddr_t hdr_addr, size_t nrec);
+H5_DLL void H5HF_iblock_print(const H5HF_indirect_t *iblock, hbool_t dump_internal,
+ FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, haddr_t hdr_addr, unsigned nrows);
@@ -733,6 +743,9 @@ H5_DLL herr_t H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node, unsigned flags);
H5_DLL htri_t H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request,
H5HF_free_section_t **node);
+H5_DLL herr_t H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL herr_t H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_indirect_t *root_iblock);
H5_DLL herr_t H5HF_space_size(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t *fs_size);
H5_DLL herr_t H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node);
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 38d9381..87fa069 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -665,42 +665,6 @@ H5HF_sect_single_dblock_info(H5HF_hdr_t *hdr, hid_t dxpl_id,
HDassert(dblock_addr);
HDassert(dblock_size);
- /* Check for section in first direct block of heap */
- if(sect->sect_info.addr < hdr->man_dtable.cparam.start_block_size) {
- /* Check for heap changing from direct <-> indirect root (or vice versa)
- * while section was live.
- */
- if(sect->u.single.parent) {
- /* Check for heap converting from indirect root to direct root while section was live */
- if(hdr->man_dtable.curr_root_rows == 0) {
- /* Release hold on parent indirect block */
- if(H5HF_iblock_decr(sect->u.single.parent) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
-
- /* Reset parent information */
- sect->u.single.parent = NULL;
- sect->u.single.par_entry = 0;
- } /* end if */
- else {
- /* Check for heap converting from indirect to direct and back
- * to indirect again, which would indicate a different
- * indirect root block would be used for the parent of
- * this section and the actual root indirect block.
- */
- if(H5HF_sect_single_locate_parent(hdr, dxpl_id, TRUE, sect) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
- } /* end else */
- } /* end if */
- else {
- /* Check for heap converting from direct root to indirect root while section was live */
- if(hdr->man_dtable.curr_root_rows != 0) {
- /* Look up indirect block information for section */
- if(H5HF_sect_single_locate_parent(hdr, dxpl_id, FALSE, sect) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
- } /* end if */
- } /* end else */
- } /* end if */
-
/* Check for root direct block */
if(hdr->man_dtable.curr_root_rows == 0) {
/* Retrieve direct block info from heap header */
@@ -860,7 +824,7 @@ H5HF_sect_single_add(H5FS_section_info_t *_sect, unsigned *flags, void *_udata)
*/
if(!(*flags & H5FS_ADD_DESERIALIZING)) {
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
@@ -992,7 +956,7 @@ H5HF_sect_single_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
{
H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1050,7 +1014,7 @@ static htri_t
H5HF_sect_single_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
htri_t ret_value = FALSE; /* Return value */
@@ -1105,7 +1069,7 @@ static herr_t
H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
{
H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
H5HF_direct_t *dblock; /* Pointer to direct block for section */
@@ -1814,7 +1778,7 @@ H5HF_sect_row_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
{
H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1881,7 +1845,7 @@ static htri_t
H5HF_sect_row_can_shrink(const H5FS_section_info_t *_sect, void UNUSED *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Fractal heap free section */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
htri_t ret_value = FALSE; /* Return value */
@@ -1919,7 +1883,7 @@ H5HF_sect_row_shrink(H5FS_section_info_t **_sect, void *_udata)
{
H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
H5HF_free_section_t *top_indir_sect; /* Top indirect section for row */
- H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
+ H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2161,7 +2125,7 @@ H5HF_sect_indirect_iblock_off(const H5HF_free_section_t *sect)
*
* Purpose: Get the "top" indirect section
*
- * Return: Pointer to the top indirect sectin (can't fail)
+ * Return: Pointer to the top indirect section (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index cec9b3a..01330d3 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -168,7 +168,7 @@ herr_t
H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
unsigned flags)
{
- H5HF_sect_add_ud1_t udata; /* User data for free space manager 'add' */
+ H5HF_sect_add_ud_t udata; /* User data for free space manager 'add' */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -246,6 +246,185 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_space_revert_root_cb
+ *
+ * Purpose: Callback routine from iterator, to reset 'parent' pointers in
+ * sections, when the heap is changing from having a root indirect
+ * block to a direct block.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 24 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_space_revert_root_cb(H5FS_section_info_t *_sect, void UNUSED *_udata)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(sect);
+
+ /* Only modify "live" single blocks... */
+ if(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE && sect->sect_info.state == H5FS_SECT_LIVE) {
+ /* Release hold on previous indirect block (we must have one) */
+ HDassert(sect->u.single.parent);
+ if(H5HF_iblock_decr(sect->u.single.parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
+
+ /* Reset parent information */
+ sect->u.single.parent = NULL;
+ sect->u.single.par_entry = 0;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_space_revert_root_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_space_revert_root
+ *
+ * Purpose: Reset 'parent' pointers in sections, when the heap is
+ * changing from having a root indirect block to a direct block.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 23 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+
+ /* Only need to scan the sections if the free space has been initialized */
+ if(hdr->fspace) {
+ /* Iterate over all sections, reseting the parent pointers in 'single' sections */
+ if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_revert_root_cb, NULL) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to reset parent pointers")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_space_revert_root() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_space_create_root_cb
+ *
+ * Purpose: Callback routine from iterator, to set 'parent' pointers in
+ * sections to newly created root indirect block, when the heap
+ * is changing from having a root direct block to an indirect block.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 24 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_space_create_root_cb(H5FS_section_info_t *_sect, void *_udata)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
+ H5HF_indirect_t *root_iblock = (H5HF_indirect_t *)_udata; /* User data for callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(sect);
+ HDassert(root_iblock);
+
+ /* Sanity check sections */
+ /* (If we are switching from a direct block for the root block of the heap, */
+ /* there should only be 'single' type sections. -QAK) */
+ HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
+
+ /* Increment ref. count on new root indirect block */
+ if(H5HF_iblock_incr(root_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on section's indirect block")
+
+ /* Set parent info ("live" section must _NOT_ have a parent right now) */
+ if(sect->sect_info.state == H5FS_SECT_SERIALIZED)
+ sect->sect_info.state = H5FS_SECT_LIVE; /* Mark "live" now */
+ else
+ HDassert(!sect->u.single.parent);
+ sect->u.single.parent = root_iblock;
+ sect->u.single.par_entry = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_space_create_root_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_space_create_root
+ *
+ * Purpose: Set 'parent' pointers in sections to new indirect block, when
+ * the heap is changing from having a root direct block to a
+ * indirect block.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 24 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *root_iblock)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(root_iblock);
+
+ /* Only need to scan the sections if the free space has been initialized */
+ if(hdr->fspace) {
+ /* Iterate over all sections, seting the parent pointers in 'single' sections to the new indirect block */
+ if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_create_root_cb, root_iblock) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to set parent pointers")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_space_create_root() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_space_size
*
* Purpose: Query the size of the heap's free space info on disk
diff --git a/src/H5I.c b/src/H5I.c
index 617b7a4..7b33533 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -109,6 +109,11 @@ typedef struct {
H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */
} H5I_id_type_t;
+typedef struct {
+ H5I_search_func_t app_cb; /* Application's callback routine */
+ void *app_key; /* Application's "key" (user data) */
+ void *ret_obj; /* Object to return */
+} H5I_search_ud_t;
/*-------------------- Locally scoped variables -----------------------------*/
@@ -128,6 +133,7 @@ H5FL_DEFINE_STATIC(H5I_id_info_t);
/*--------------------- Local function prototypes ---------------------------*/
static H5I_id_info_t *H5I_find_id(hid_t id);
+static int H5I_search_cb(void *obj, hid_t id, void *udata);
#ifdef H5I_DEBUG_OUTPUT
static herr_t H5I_debug(H5I_type_t type);
#endif /* H5I_DEBUG_OUTPUT */
@@ -1921,6 +1927,40 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5I_search_cb
+ *
+ * Purpose: Callback routine for H5Isearch, when it calls H5I_iterate.
+ * Calls "user" callback search function, and then sets return
+ * value, based on the result of that callback.
+ *
+ * Return: Success: The first object in the type for which FUNC
+ * returns non-zero. NULL if FUNC returned zero
+ * for every object in the type.
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 30, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5I_search_cb(void *obj, hid_t id, void *_udata)
+{
+ H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */
+ int ret_value; /* Callback return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ ret_value = (*udata->app_cb)(obj, id, udata->app_key);
+ if(ret_value > 0)
+ udata->ret_obj = obj;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_search_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Isearch
*
* Purpose: Apply function FUNC to each member of type TYPE and return a
@@ -1947,14 +1987,27 @@ done:
void *
H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
{
- void * ret_value; /* Return value */
+ H5I_search_ud_t udata; /* Context for iteration */
+ void *ret_value; /* Return value */
FUNC_ENTER_API(NULL)
+ /* Check arguments */
if(H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
- ret_value = H5I_search(type, func, key, TRUE);
+ /* Set up udata struct */
+ udata.app_cb = func;
+ udata.app_key = key;
+ udata.ret_obj = NULL;
+
+ /* Note that H5I_iterate returns an error code. We ignore it
+ * here, as we can't do anything with it without revising the API.
+ */
+ H5I_iterate(type, H5I_search_cb, &udata, TRUE);
+
+ /* Set return value */
+ ret_value = udata.ret_obj;
done:
FUNC_LEAVE_API(ret_value)
@@ -1962,64 +2015,72 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5I_search
+ * Function: H5I_iterate
*
- * Purpose: Apply function FUNC to each member of type TYPE and return a
- * pointer to the first object for which FUNC returns non-zero.
- * The FUNC should take a pointer to the object and the KEY as
- * arguments and return non-zero to terminate the search (zero
- * to continue).
+ * Purpose: Apply function FUNC to each member of type TYPE (with
+ * non-zero application reference count if app_ref is TRUE).
+ * Stop if FUNC returns a non zero value (i.e. anything
+ * other than H5_ITER_CONT).
*
- * Limitation: Currently there is no way to start searching from where a
- * previous search left off.
+ * If FUNC returns a positive value (i.e. H5_ITER_STOP),
+ * return SUCCEED.
*
- * Return: Success: The first object in the type for which FUNC
- * returns non-zero. NULL if FUNC returned zero
- * for every object in the type.
- * Failure: NULL
+ * If FUNC returns a negative value (i.e. H5_ITER_ERROR),
+ * return FAIL.
+ *
+ * The FUNC should take a pointer to the object and the
+ * udata as arguments and return non-zero to terminate
+ * siteration, and zero to continue.
*
- * Programmer: Robb Matzke
- * Friday, February 19, 1999
+ * Limitation: Currently there is no way to start the iteration from
+ * where a previous iteration left off.
*
- * Modifications: Neil Fortner
- * Wednesday, October 1, 2008
- * Added app_ref parameter. When set to TRUE, the function will only
- * operate on ids that have a nonzero application reference count.
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * Monday, December 6, 2011
*
*-------------------------------------------------------------------------
*/
-void *
-H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
+herr_t
+H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref)
{
- H5I_id_type_t *type_ptr; /*ptr to the type */
- void *ret_value = NULL; /*return value */
+ H5I_id_type_t *type_ptr; /*ptr to the type */
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
- FUNC_ENTER_NOAPI(NULL
-)
/* Check arguments */
if(type <= H5I_BADID || type >= H5I_next_type)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number")
type_ptr = H5I_id_type_list_g[type];
- if(type_ptr == NULL || type_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
-
- /* Only iterate through hash table if there are IDs in group */
- if(type_ptr->ids > 0) {
- H5I_id_info_t *id_ptr; /*ptr to the new ID */
- H5I_id_info_t *next_id; /*ptr to the next ID */
- unsigned i; /*counter */
+ /* Only iterate through hash table if it is initialized and there are IDs in group */
+ if(type_ptr && type_ptr->count > 0 && type_ptr->ids > 0) {
+ unsigned u; /* Counter */
/* Start at the beginning of the array */
- for(i = 0; i < type_ptr->hash_size; i++) {
- id_ptr = type_ptr->id_list[i];
+ for(u = 0; u < type_ptr->hash_size; u++) {
+ H5I_id_info_t *id_ptr; /* Ptr to the new ID */
+
+ id_ptr = type_ptr->id_list[u];
while(id_ptr) {
- next_id = id_ptr->next; /* Protect against ID being deleted in callback */
- /* (Casting away const OK -QAK) */
- if((!app_ref || id_ptr->app_count) && (*func)((void *)id_ptr->obj_ptr, id_ptr->id, key))
- /* (Casting away const OK -QAK) */
- HGOTO_DONE((void *)id_ptr->obj_ptr); /*found the item*/
+ H5I_id_info_t *next_id; /* Ptr to the next ID */
+
+ /* Protect against ID being deleted in callback */
+ next_id = id_ptr->next;
+ if((!app_ref) || (id_ptr->app_count > 0)) {
+ herr_t cb_ret_val; /* Callback return value */
+
+ /* (Casting away const OK) */
+ cb_ret_val = (*func)((void *)id_ptr->obj_ptr, id_ptr->id, udata);
+ if(cb_ret_val > 0)
+ HGOTO_DONE(SUCCEED) /* terminate iteration early */
+ else if(cb_ret_val < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "func failed")
+ } /* end if */
id_ptr = next_id;
} /* end while */
} /* end for */
@@ -2027,7 +2088,7 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5I_search() */
+} /* end H5I_iterate() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 3a9e2db..ee938df 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -70,7 +70,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
H5_DLL void *H5I_remove(hid_t id);
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
-H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref);
+H5_DLL herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref);
H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_dec_ref(hid_t id);
diff --git a/src/H5MF.c b/src/H5MF.c
index fce151e..f9ca256 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -1172,9 +1172,9 @@ HDfprintf(stderr, "%s: Leaving\n", FUNC);
*-------------------------------------------------------------------------
*/
static herr_t
-H5MF_sects_cb(const H5FS_section_info_t *_sect, void *_udata)
+H5MF_sects_cb(H5FS_section_info_t *_sect, void *_udata)
{
- const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect;
+ H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect;
H5MF_sect_iter_ud_t *udata = (H5MF_sect_iter_ud_t *)_udata;
FUNC_ENTER_NOAPI_NOINIT_NOERR
diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c
index bdc811f..d6fc5ce 100644
--- a/src/H5MFdbg.c
+++ b/src/H5MFdbg.c
@@ -99,9 +99,9 @@ typedef struct {
*-------------------------------------------------------------------------
*/
static herr_t
-H5MF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
+H5MF_sects_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
- const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* Section to dump info */
+ H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect; /* Section to dump info */
H5MF_debug_iter_ud_t *udata = (H5MF_debug_iter_ud_t *)_udata; /* User data for callbacks */
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5O.c b/src/H5O.c
index 82d9453..ec4cba9 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -79,12 +79,12 @@ typedef struct {
/********************/
static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
-static const H5O_obj_class_t *H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id);
static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type);
static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id,
hid_t dxpl_id);
static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr);
+static const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh);
/*********************/
@@ -2382,7 +2382,7 @@ H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type)
*
*-------------------------------------------------------------------------
*/
-static const H5O_obj_class_t *
+const H5O_obj_class_t *
H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id)
{
H5O_t *oh = NULL; /* Object header for location */
@@ -2419,7 +2419,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-const H5O_obj_class_t *
+static const H5O_obj_class_t *
H5O_obj_class_real(H5O_t *oh)
{
size_t i; /* Local index variable */
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index ff4cc5d..b207ea2 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -46,11 +46,11 @@ static herr_t H5O_ainfo_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
static herr_t H5O_ainfo_pre_copy_file(H5F_t *file_src, const void *mesg_src,
hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
- hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc,
- const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
- H5O_copy_t *cpy_info);
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_ainfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -403,7 +403,8 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -468,7 +469,8 @@ done:
*/
static herr_t
H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 8cd243b..510d64f 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -61,6 +61,7 @@ static herr_t H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_COPY_FILE_REAL H5O_attr_copy_file
#define H5O_SHARED_POST_COPY_FILE H5O_attr_shared_post_copy_file
#define H5O_SHARED_POST_COPY_FILE_REAL H5O_attr_post_copy_file
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_attr_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_attr_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index fbfc140..30ec732 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -135,9 +135,6 @@ typedef struct {
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
- hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
- hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr,
const char* name_to_open);
@@ -437,8 +434,10 @@ H5O_attr_open_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence,
if(NULL == (udata->attr = H5A_copy(NULL, (H5A_t *)mesg->native)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy attribute")
- /* Assign [somewhat arbitrary] creation order value, for older versions of the format */
- if(oh->version == H5O_VERSION_1)
+ /* Assign [somewhat arbitrary] creation order value, for older versions
+ * of the format or if creation order is not tracked */
+ if(oh->version == H5O_VERSION_1
+ || !(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED))
udata->attr->shared->crt_idx = sequence;
/* Stop iterating */
@@ -704,18 +703,23 @@ H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_t
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
/* Count all opened attributes */
- num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE);
+ if(H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE, &num_open_attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't count opened attributes")
/* Find out whether the attribute has been opened */
if(num_open_attr) {
+ size_t check_num_attr; /* Number of open attribute IDs */
size_t u; /* Local index variable */
/* Allocate space for the attribute ID list */
if(NULL == (attr_id_list = (hid_t *)H5MM_malloc(num_open_attr * sizeof(hid_t))))
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "unable to allocate memory for attribute ID list")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "unable to allocate memory for attribute ID list")
/* Retrieve the IDs of all opened attributes */
- H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE);
+ if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE, &check_num_attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get IDs of opened attributes")
+ if(check_num_attr != num_open_attr)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "open attribute count mismatch")
/* Iterate over the attributes */
for(u = 0; u < num_open_attr; u++) {
@@ -1260,7 +1264,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data)
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index dd649ff..7b812ec 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -34,10 +34,12 @@
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
#include "H5HGprivate.h" /* Global Heaps */
+#include "H5FOprivate.h" /* File objects */
#include "H5Lprivate.h" /* Links */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
@@ -54,6 +56,20 @@
/* Local Typedefs */
/******************/
+/* Key object for skiplist of committed datatypes */
+typedef struct H5O_copy_search_comm_dt_key_t {
+ H5T_t *dt; /* Datatype */
+ unsigned long fileno; /* File number */
+} H5O_copy_search_comm_dt_key_t;
+
+/* Callback struct for building a list of committed datatypes */
+typedef struct H5O_copy_search_comm_dt_ud_t {
+ H5SL_t *dst_dt_list; /* Skip list of committed datatypes */
+ H5G_loc_t *dst_root_loc; /* Starting location for iteration */
+ H5O_loc_t obj_oloc; /* Object location (for attribute iteration callback) */
+ hid_t dxpl_id; /* Dataset transfer property list id */
+} H5O_copy_search_comm_dt_ud_t;
+
/********************/
/* Package Typedefs */
@@ -65,14 +81,23 @@
/********************/
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
-static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
+static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata);
-static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option);
+static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
+ hid_t dxpl_id, hid_t ocpypl_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, hid_t dxpl_id,
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,
+ const H5L_info_t *linfo, void *udata);
+static htri_t H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst/*in, out*/, hid_t dxpl_id, H5O_copy_t *cpy_info);
+static herr_t H5O_copy_insert_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+
/*********************/
/* Package Variables */
@@ -81,6 +106,12 @@ static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id,
/* Declare a free list to manage the H5O_addr_map_t struct */
H5FL_DEFINE(H5O_addr_map_t);
+/* Declare a free list to manage the H5O_copy_search_comm_dt_key_t struct */
+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 */
@@ -281,11 +312,19 @@ done:
* Programmer: Peter Cao
* May 30, 2005
*
+ * Modifications:
+ * Vailin Choi; Feb 2012
+ * Bug fix for HDFFV-7853
+ * When the object is opened, call the object's flush class action
+ * to ensure that cached data is flushed so that H5Ocopy will get
+ * the correct data.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata)
+H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
+ hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type,
+ void **udata /*out*/)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5O_t *oh_src = NULL; /* Object header for source object */
@@ -316,19 +355,85 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(oloc_dst->file);
HDassert(cpy_info);
+ /* Get pointer to object class for this object */
+ if((obj_class = H5O_obj_class(oloc_src, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
+
+ /* Check if the object at the address is already open in the file */
+ if(H5FO_opened(oloc_src->file, oloc_src->addr) != NULL) {
+
+ H5G_loc_t tmp_loc; /* Location of object */
+ H5O_loc_t tmp_oloc; /* Location of object */
+ H5G_name_t tmp_path; /* Object's path */
+
+ tmp_loc.oloc = &tmp_oloc;
+ tmp_loc.path = &tmp_path;
+ tmp_oloc.file = oloc_src->file;
+ tmp_oloc.addr = oloc_src->addr;
+ tmp_oloc.holding_file = oloc_src->holding_file;
+ H5G_name_reset(tmp_loc.path);
+
+ /* Flush the object of this class */
+ if(obj_class->flush && obj_class->flush(&tmp_loc, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object")
+ }
+
/* Get source object header */
if(NULL == (oh_src = H5O_protect(oloc_src, dxpl_id, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
- /* Get pointer to object class for this object */
- if(NULL == (obj_class = H5O_obj_class_real(oh_src)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type")
-
/* Retrieve user data for particular type of object to copy */
if(obj_class->get_copy_file_udata &&
(NULL == (cpy_udata = (obj_class->get_copy_file_udata)())))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to retrieve copy user data")
+ /* If we are merging committed datatypes, check for a match in the destination
+ * file now */
+ if(cpy_info->merge_comm_dt && obj_class->type == H5O_TYPE_NAMED_DATATYPE) {
+ unsigned long fileno_src; /* fileno for source file */
+ unsigned long fileno_dst; /* fileno for destination file */
+ htri_t merge; /* Whether we found a match in the destination file */
+
+ /* Check if the source and dest file are the same. If so, just return
+ * the source object address */
+ H5F_GET_FILENO(oloc_src->file, fileno_src);
+ H5F_GET_FILENO(oloc_dst->file, fileno_dst);
+ if(fileno_src == fileno_dst) {
+ merge = TRUE;
+ oloc_dst->addr = oloc_src->addr;
+ } /* end if */
+ else
+ /* Search for a matching committed datatype, building the list if
+ * necessary */
+ if((merge = H5O_copy_search_comm_dt(oloc_src->file, oh_src, oloc_dst, dxpl_id, cpy_info)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't search for matching committed datatype")
+
+ if(merge) {
+ /* Found a match, add to skip list and exit */
+ /* Allocate space for the address mapping of the object copied */
+ if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Insert the address mapping for the found object into the copied
+ * list */
+ addr_map->src_obj_pos.fileno = fileno_src;
+ addr_map->src_obj_pos.addr = oloc_src->addr;
+ addr_map->dst_addr = oloc_dst->addr;
+ addr_map->is_locked = TRUE; /* We've locked the object currently */
+ addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
+ addr_map->obj_class = obj_class;
+ addr_map->udata = cpy_udata;
+
+ /* Insert into skip list */
+ if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0) {
+ addr_map = H5FL_FREE(H5O_addr_map_t, addr_map);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ } /* end if */
+
+ HGOTO_DONE(SUCCEED)
+ } /* end if */
+ } /* end if */
+
/* Flush any dirty messages in source object header to update the header chunks */
if(H5O_flush_msgs(oloc_src->file, oh_src) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages")
@@ -470,38 +575,33 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* copy this message into destination file */
if(copy_type->copy_file) {
- htri_t is_shared; /* Whether message is shared */
hbool_t recompute_size; /* Whether copy_file callback created a shared message */
+ unsigned mesg_flags; /* Message flags */
/* Decode the message if necessary. */
H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL)
+ /* Get destination message flags, and unset shared and shareable
+ * flags. mesg_dst->flags will contain the original flags for now.
+ */
+ mesg_flags = (unsigned)mesg_dst->flags & ~H5O_MSG_FLAG_SHARED
+ & ~H5O_MSG_FLAG_SHAREABLE;
+
/* Copy the source message */
recompute_size = FALSE;
- if((mesg_dst->native = H5O_msg_copy_file(copy_type,
- oloc_src->file, mesg_src->native, oloc_dst->file,
- &recompute_size, cpy_info, cpy_udata, dxpl_id)) == NULL)
+ if((mesg_dst->native = H5O_msg_copy_file(copy_type, oloc_src->file,
+ mesg_src->native, oloc_dst->file, &recompute_size,
+ &mesg_flags, cpy_info, cpy_udata, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
- /* Check if new message is shared */
- if((is_shared = H5O_msg_is_shared(copy_type->id, mesg_dst->native)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to query message's shared status")
-
- /* In being copied, the message may have become shared or stopped
- * being shared, set/unset its sharing flag.
+ /* Check if the sharing state changed, and recompute the size if so
*/
- if(is_shared && !(mesg_dst->flags & H5O_MSG_FLAG_SHARED)) {
- mesg_dst->flags |= H5O_MSG_FLAG_SHARED;
-
- /* Recompute message size (mesg_dst->native is really shared) */
- recompute_size = TRUE;
- } /* end if */
- else if(!is_shared && (mesg_dst->flags & H5O_MSG_FLAG_SHARED)) {
- mesg_dst->flags &= ~H5O_MSG_FLAG_SHARED;
-
- /* Recompute message size (msg_dest->native is no longer shared) */
+ if(!(mesg_flags & H5O_MSG_FLAG_SHARED)
+ != !(mesg_dst->flags & H5O_MSG_FLAG_SHARED))
recompute_size = TRUE;
- } /* end if */
+
+ /* Set destination message flags */
+ mesg_dst->flags = (uint8_t)mesg_flags;
/* Recompute message's size */
/* (its sharing status or one of its components (for attributes)
@@ -671,6 +771,13 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
oloc_dst->addr = addr_new;
+ /* If we are merging committed datatypes and this is a committed datatype, insert
+ * the copied datatype into the list of committed datatypes in the target file.
+ */
+ if(cpy_info->merge_comm_dt && obj_class->type == H5O_TYPE_NAMED_DATATYPE)
+ if(H5O_copy_insert_comm_dt(oloc_src->file, oh_src, oloc_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't insert committed datatype into destination list")
+
/* Allocate space for the address mapping of the object copied */
if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
@@ -686,8 +793,10 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
addr_map->udata = cpy_udata;
/* Insert into skip list */
- if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0)
+ if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0) {
+ addr_map = H5FL_FREE(H5O_addr_map_t, addr_map);
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ } /* end if */
/* "post copy" loop over messages, to fix up any messages which require a complete
* object header for destination object
@@ -716,17 +825,26 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(copy_type);
if(copy_type->post_copy_file && mesg_src->native) {
+ unsigned mesg_flags; /* Message flags */
+
/* Sanity check destination message */
HDassert(mesg_dst->type == mesg_src->type);
HDassert(mesg_dst->native);
+ /* Get destination message flags. mesg_dst->flags will contain the
+ * original flags for now. */
+ mesg_flags = (unsigned)mesg_dst->flags;
+
/* the object header is needed in the post copy for shared message */
cpy_info->oh_dst = oh_dst;
/* Perform "post copy" operation on message */
if((copy_type->post_copy_file)(oloc_src, mesg_src->native, oloc_dst,
- mesg_dst->native, dxpl_id, cpy_info) < 0)
+ mesg_dst->native, &mesg_flags, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+
+ /* Verify that the flags did not change */
+ HDassert(mesg_flags == (unsigned) mesg_dst->flags);
} /* end if */
} /* end for */
@@ -797,9 +915,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
+H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth,
- H5O_type_t *obj_type, void **udata)
+ H5O_type_t *obj_type, void **udata /*out*/)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5_obj_t src_obj_pos; /* Position of source object */
@@ -937,9 +1055,13 @@ H5O_copy_free_addrmap_cb(void *_item, void UNUSED *key, void UNUSED *op_data)
*/
static herr_t
H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option)
+ hid_t dxpl_id, hid_t ocpypl_id)
{
H5O_copy_t cpy_info; /* Information for copying object */
+ H5P_genplist_t *ocpy_plist; /* Object copy property list created */
+ H5O_copy_dtype_merge_list_t *dt_list = NULL; /* List of datatype merge suggestions */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ unsigned cpy_option = 0; /* Copy options */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
@@ -949,6 +1071,22 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(H5F_addr_defined(oloc_src->addr));
HDassert(oloc_dst->file);
+ /* Get the copy property list */
+ if(NULL == (ocpy_plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Retrieve the copy parameters */
+ if(H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
+
+ /* Retrieve the marge committed datatype list */
+ if(H5P_get(ocpy_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed datatype list")
+
+ /* Get callback info */
+ if(H5P_get(ocpy_plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
+
/* Convert copy flags into copy struct */
HDmemset(&cpy_info, 0, sizeof(H5O_copy_t));
if((cpy_option & H5O_COPY_SHALLOW_HIERARCHY_FLAG) > 0) {
@@ -968,9 +1106,18 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
cpy_info.copy_without_attr = TRUE;
if((cpy_option & H5O_COPY_PRESERVE_NULL_FLAG) > 0)
cpy_info.preserve_null = TRUE;
+ if((cpy_option & H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) > 0)
+ cpy_info.merge_comm_dt = TRUE;
+
+ /* Add dt_list to copy struct */
+ cpy_info.dst_dt_suggestion_list = dt_list;
+
+ /* Add set callback information */
+ cpy_info.mcdt_cb = cb_info.func;
+ cpy_info.mcdt_ud = cb_info.user_data;
/* Create a skip list to keep track of which objects are copied */
- if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ, NULL)) == NULL)
+ if(NULL == (cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ, NULL)))
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
@@ -980,6 +1127,8 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
done:
if(cpy_info.map_list)
H5SL_destroy(cpy_info.map_list, H5O_copy_free_addrmap_cb, NULL);
+ if(cpy_info.dst_dt_list)
+ H5SL_destroy(cpy_info.dst_dt_list, H5O_copy_free_comm_dt_cb, NULL);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_copy_header() */
@@ -1001,14 +1150,12 @@ 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)
{
- H5P_genplist_t *ocpy_plist=NULL; /* Object copy property list created */
- hid_t dxpl_id=H5AC_dxpl_id;
H5G_name_t new_path; /* Copied object group hier. path */
H5O_loc_t new_oloc; /* Copied object object location */
H5G_loc_t new_loc; /* Group location of object copied */
H5F_t *cached_dst_file; /* Cached destination file */
- hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */
- unsigned cpy_option = 0; /* Copy options */
+ hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */
+ hid_t dxpl_id = H5AC_dxpl_id; /* DXPL for operation */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -1019,14 +1166,6 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
HDassert(dst_loc->oloc->file);
HDassert(dst_name);
- /* Get the copy property list */
- if(NULL == (ocpy_plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
-
- /* Retrieve the copy parameters */
- if(H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
-
/* Set up copied object location to fill in */
new_loc.oloc = &new_oloc;
new_loc.path = &new_path;
@@ -1039,7 +1178,7 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
cached_dst_file = dst_loc->oloc->file;
/* Copy the object from the source file to the destination file */
- if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id, cpy_option) < 0)
+ if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id, ocpypl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Patch dst_loc. Again, this can be removed once oloc's point to shared
@@ -1255,3 +1394,579 @@ 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.
+ *
+ * Return: SUCCEED (never fails)
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_free_comm_dt_cb(void *item, void *_key, void UNUSED *op_data)
+{
+ haddr_t *addr = (haddr_t *)item;
+ H5O_copy_search_comm_dt_key_t *key = (H5O_copy_search_comm_dt_key_t *)_key;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(addr);
+ HDassert(key);
+ HDassert(key->dt);
+
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ addr = H5FL_FREE(haddr_t, addr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_copy_free_comm_dt_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_comm_dt_cmp
+ *
+ * Purpose: Skiplist callback used to compare 2 keys for the merge
+ * committed dt list. Mostly a wrapper for H5T_cmp.
+ *
+ * Return: 0 if key1 and key2 are equal.
+ * <0 if key1 is less than key2.
+ * >0 if key1 is greater than key2.
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5O_copy_comm_dt_cmp(const void *_key1, const void *_key2)
+{
+ const H5O_copy_search_comm_dt_key_t *key1 = (const H5O_copy_search_comm_dt_key_t *)_key1;
+ const H5O_copy_search_comm_dt_key_t *key2 = (const H5O_copy_search_comm_dt_key_t *)_key2;
+ int ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check fileno. It is unlikely to be different so check if they are equal
+ * first so only one comparison needs to be made. */
+ if(key1->fileno != key2->fileno) {
+ if(key1->fileno < key2->fileno)
+ HGOTO_DONE(-1)
+ if(key1->fileno > key2->fileno)
+ HGOTO_DONE(1)
+ } /* end if */
+
+ ret_value = H5T_cmp(key1->dt, key2->dt, FALSE);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_comm_dt_cmp */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_attr_cb
+ *
+ * Purpose: Callback for H5O_attr_iterate_real from
+ * H5O_copy_search_comm_dt_check. Checks if the attribute's
+ * datatype is committed. If it is, adds it to the merge
+ * committed dt skiplist present in udata if it does not match
+ * any already present.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Nov 3 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_attr_cb(const H5A_t *attr, void *_udata)
+{
+ H5O_copy_search_comm_dt_ud_t *udata = (H5O_copy_search_comm_dt_ud_t *)_udata;
+ H5T_t *dt = NULL; /* Datatype */
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination address */
+ hbool_t obj_inserted = FALSE; /* Object inserted into skip list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(attr);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(H5F_addr_defined(udata->obj_oloc.addr));
+
+ /* Get attribute datatype */
+ if(NULL == (dt = H5A_type(attr)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get attribute datatype")
+
+ /* Check if the datatype is committed and search the skip list if so */
+ if(H5T_committed(dt)) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy datatype into key */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_copy(H5O_DTYPE_ID, dt, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy datatype message")
+
+ /* Get datatype object fileno */
+ H5F_GET_FILENO(udata->obj_oloc.file, key->fileno);
+
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = ((H5O_shared_t *)(key->dt))->u.loc.oh_addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(!obj_inserted) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr) {
+ HDassert(ret_value < 0);
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_attr_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_check
+ *
+ * Purpose: Check if the object at obj_oloc is or contains a reference
+ * to a committed datatype. If it does, adds it to the merge
+ * committed dt skiplist present in udata if it does not match
+ * any already present.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Nov 3 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc,
+ H5O_copy_search_comm_dt_ud_t *udata)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination address */
+ hbool_t obj_inserted = FALSE; /* Object inserted into skip list */
+ H5O_info_t oinfo; /* Object info */
+ H5A_attr_iter_op_t attr_op; /* Attribute iteration operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(obj_oloc);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(udata->dst_root_loc);
+
+ /* Get the object's info */
+ if(H5O_get_info(obj_oloc, udata->dxpl_id, TRUE, &oinfo) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info")
+
+ /* Check if the object is a datatype, a dataset using a committed
+ * datatype, or contains an attribute using a committed datatype */
+ if(oinfo.type == H5O_TYPE_NAMED_DATATYPE) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the destination datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read(obj_oloc, H5O_DTYPE_ID, NULL, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(obj_oloc->file, key->fileno);
+
+ /* Check if the datatype is already present in the skip list */
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = obj_oloc->addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+ else if(oinfo.type == H5O_TYPE_DATASET) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the destination datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read(obj_oloc, H5O_DTYPE_ID, NULL, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Check if the datatype is committed and search the skip list if so
+ */
+ if(H5T_committed(key->dt)) {
+ /* Get datatype object fileno */
+ H5F_GET_FILENO(obj_oloc->file, key->fileno);
+
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = ((H5O_shared_t *)(key->dt))->u.loc.oh_addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+ } /* end else */
+
+ /* Search within attributes */
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5O_copy_search_comm_dt_attr_cb;
+ udata->obj_oloc.file = obj_oloc->file;
+ udata->obj_oloc.addr = obj_oloc->addr;
+ if(H5O_attr_iterate_real((hid_t)-1, obj_oloc, udata->dxpl_id, H5_INDEX_NAME, H5_ITER_NATIVE, 0, NULL, &attr_op, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "error iterating over attributes");
+
+done:
+ /* Release resources */
+ if(!obj_inserted) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr) {
+ HDassert(ret_value < 0);
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_check */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_cb
+ *
+ * Purpose: H5G_visit callback to add committed datatypes to the merge
+ * committed dt skiplist. Mostly a wrapper for
+ * H5O_copy_search_comm_dt_check.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_cb(hid_t UNUSED group, const char *name,
+ const H5L_info_t *linfo, void *_udata)
+{
+ H5O_copy_search_comm_dt_ud_t *udata = (H5O_copy_search_comm_dt_ud_t *)_udata; /* Skip list of dtypes in dest file */
+ H5G_loc_t obj_loc; /* Location of object */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ H5G_name_t obj_path; /* Object's group hier. path */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(name);
+ HDassert(linfo);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(udata->dst_root_loc);
+
+ /* Check if this is a hard link */
+ if(linfo->type == H5L_TYPE_HARD) {
+ /* 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(udata->dst_root_loc, name, &obj_loc/*out*/, H5P_LINK_ACCESS_DEFAULT, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, H5_ITER_ERROR, "object not found")
+ obj_found = TRUE;
+
+ /* Check object and add to skip list if appropriate */
+ if(H5O_copy_search_comm_dt_check(&obj_oloc, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "can't check object")
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(obj_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt
+ *
+ * Purpose: Checks if the committed datatype present in oh_src matches any
+ * in the destination file, building the destination file
+ * skiplist as necessary.
+ *
+ * Return: TRUE if a match is found in the destination file
+ * - oloc_dst will contain the address
+ * FALSE if a match is not found
+ * Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Sep 27 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst/*in, out*/, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *dst_addr; /* Destination datatype address */
+ H5G_loc_t dst_root_loc = {NULL, NULL}; /* Destination root group location */
+ H5O_copy_search_comm_dt_ud_t udata; /* Group iteration user data */
+ herr_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(oh_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
+ HDassert(H5F_FILE_ID(oloc_dst->file) >= 0);
+ HDassert(cpy_info);
+
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the source datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read_oh(file_src, dxpl_id, oh_src, H5O_DTYPE_ID, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(oloc_dst->file, key->fileno);
+
+ /* Check if the destination dtype list exists, create it if it does not */
+ if(!cpy_info->dst_dt_list) {
+ /* Create the skip list */
+ if(NULL == (cpy_info->dst_dt_list = H5SL_create(H5SL_TYPE_GENERIC, H5O_copy_comm_dt_cmp)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for committed datatypes")
+
+ /* Add suggested types to list, if they are present */
+ if(cpy_info->dst_dt_suggestion_list) {
+ H5O_copy_dtype_merge_list_t *suggestion = cpy_info->dst_dt_suggestion_list;
+ H5G_loc_t obj_loc; /* Location of object */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ H5G_name_t obj_path; /* Object's group hier. path */
+
+ /* Set up the root group in the destination file */
+ if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(oloc_dst->file))))
+ 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(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Build udata */
+ udata.dst_dt_list = cpy_info->dst_dt_list;
+ udata.dst_root_loc = &dst_root_loc;
+ udata.obj_oloc.file = NULL;
+ udata.obj_oloc.addr = HADDR_UNDEF;
+ udata.dxpl_id = dxpl_id;
+
+ /* Walk through the list of datatype suggestions */
+ while(suggestion) {
+ /* Find the object */
+ if(H5G_loc_find(&dst_root_loc, suggestion->path, &obj_loc/*out*/, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ /* Ignore errors - i.e. suggestions not present in
+ * destination file */
+ H5E_clear_stack(NULL);
+ else
+ /* Check object and add to skip list if appropriate */
+ if(H5O_copy_search_comm_dt_check(&obj_oloc, &udata) < 0) {
+ if(H5G_loc_free(&obj_loc) < 0)
+ HERROR(H5E_OHDR, H5E_CANTRELEASE, "can't free location");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't check object")
+ } /* end if */
+
+ /* Free location */
+ if(H5G_loc_free(&obj_loc) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location");
+
+ /* Advance the suggestion pointer */
+ suggestion = suggestion->next;
+ } /* end while */
+ } /* end if */
+ }
+
+ if(!cpy_info->dst_dt_list_complete) {
+ /* Search for the type in the destination file, and return its address
+ * if found, but only if the list is populated with and only with
+ * suggested types. We will search complete lists later. */
+ if(cpy_info->dst_dt_suggestion_list
+ && NULL != (dst_addr = (haddr_t *)H5SL_search(
+ cpy_info->dst_dt_list, key))) {
+ oloc_dst->addr = *dst_addr;
+ ret_value = TRUE;
+ } /* end if */
+ else {
+ H5O_mcdt_search_ret_t search_cb_ret = H5O_MCDT_SEARCH_CONT;
+
+ /* Make callback to see if we should search destination file */
+ if(cpy_info->mcdt_cb)
+ if((search_cb_ret = cpy_info->mcdt_cb(cpy_info->mcdt_ud)) == H5O_MCDT_SEARCH_ERROR)
+ HGOTO_ERROR(H5E_OHDR, H5E_CALLBACK, FAIL, "callback returned error")
+
+ if(search_cb_ret == H5O_MCDT_SEARCH_CONT) {
+ /* Build the complete dst dt list */
+ /* Set up the root group in the destination file, if necessary */
+ if(!dst_root_loc.oloc) {
+ HDassert(!dst_root_loc.path);
+ if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(oloc_dst->file))))
+ 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(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group")
+ } /* end if */
+ else
+ HDassert(dst_root_loc.path);
+
+ /* Build udata. Note that this may be done twice in some cases, but
+ * it should be rare and should be cheaper on average than trying to
+ * keep track of whether it was done before. */
+ udata.dst_dt_list = cpy_info->dst_dt_list;
+ udata.dst_root_loc = &dst_root_loc;
+ udata.obj_oloc.file = NULL;
+ udata.obj_oloc.addr = HADDR_UNDEF;
+ udata.dxpl_id = dxpl_id;
+
+ /* Traverse the destination file, adding committed datatypes to the skip
+ * list */
+ if(H5G_visit(H5F_FILE_ID(oloc_dst->file), "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5O_copy_search_comm_dt_cb, &udata, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed")
+ cpy_info->dst_dt_list_complete = TRUE;
+ } /* end if */
+ else
+ if(search_cb_ret != H5O_MCDT_SEARCH_STOP)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown return value for callback")
+ } /* end if */
+ } /* end if */
+
+ /* Search for the type in the destination file, and return its address if
+ * found, but only if the list is complete */
+ if(cpy_info->dst_dt_list_complete) {
+ if(NULL != (dst_addr = (haddr_t *)H5SL_search(cpy_info->dst_dt_list, key))) {
+ oloc_dst->addr = *dst_addr;
+ ret_value = TRUE;
+ } /* end if */
+ } /* end if */
+
+done:
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_insert_comm_dt
+ *
+ * Purpose: Insert the committed datatype at oloc_dst into the merge committed
+ * dt skiplist. The datatype must not be present already.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_insert_comm_dt(H5F_t *file_src, H5O_t *oh_src, H5O_loc_t *oloc_dst,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination object address */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(oh_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
+ HDassert(oloc_dst->addr != HADDR_UNDEF);
+ HDassert(cpy_info);
+ HDassert(cpy_info->dst_dt_list);
+
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the datatype. Read from the source file because the destination
+ * object could be changed in the post-copy. */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read_oh(file_src, dxpl_id, oh_src, H5O_DTYPE_ID, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(oloc_dst->file, key->fileno);
+
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = oloc_dst->addr;
+ if(H5SL_insert(cpy_info->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+
+done:
+ if(ret_value < 0) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr)
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_insert_comm_dt */
+
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 9ccb51b..1b602c7 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -43,6 +43,9 @@ static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
static void *H5O_dtype_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_dtype_shared_post_copy_upd(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -63,6 +66,7 @@ static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_COPY_FILE_REAL H5O_dtype_copy_file
#define H5O_SHARED_POST_COPY_FILE H5O_dtype_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#define H5O_SHARED_POST_COPY_FILE_UPD H5O_dtype_shared_post_copy_upd
#define H5O_SHARED_DEBUG H5O_dtype_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_dtype_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
@@ -1575,6 +1579,40 @@ done:
} /* end H5O_dtype_copy_file() */
+/*-------------------------------------------------------------------------
+ * Function: H5O_dtype_shared_post_copy_upd
+ *
+ * Purpose: Update a message after the shared message operations
+ * during the post-copy loop
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * November 8, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_dtype_shared_post_copy_upd(const H5O_loc_t UNUSED *src_oloc,
+ const void UNUSED *mesg_src, H5O_loc_t UNUSED *dst_oloc, void *mesg_dst,
+ hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info)
+{
+ H5T_t *dt_dst = (H5T_t *)mesg_dst; /* Destination datatype */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(dt_dst->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
+ HDassert(H5T_committed(dt_dst));
+ dt_dst->oloc.file = dt_dst->sh_loc.file;
+ dt_dst->oloc.addr = dt_dst->sh_loc.u.loc.oh_addr;
+ } /* end if */
+ else
+ HDassert(!H5T_committed(dt_dst));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_dtype_shared_post_copy_upd */
+
+
/*--------------------------------------------------------------------------
NAME
H5O_dtype_debug
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index e4b21f0..3630cf4 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -36,8 +36,8 @@ static void *H5O_efl_copy(const void *_mesg, void *_dest);
static size_t H5O_efl_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
static herr_t H5O_efl_reset(void *_mesg);
static void *H5O_efl_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -455,8 +455,8 @@ done:
*/
static void *
H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info,
- void UNUSED *_udata, hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void UNUSED *_udata, hid_t dxpl_id)
{
H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src;
H5O_efl_t *efl_dst = NULL;
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 9fa6108..f5569dc 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -63,6 +63,7 @@ static herr_t H5O_fill_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *s
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_fill_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_fill_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_fill_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
@@ -95,6 +96,7 @@ static herr_t H5O_fill_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *s
#undef H5O_SHARED_POST_COPY_FILE
#define H5O_SHARED_POST_COPY_FILE H5O_fill_new_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#undef H5O_SHARED_DEBUG
#define H5O_SHARED_DEBUG H5O_fill_new_shared_debug
#undef H5O_SHARED_DEBUG_REAL
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 1b17bff..e912d8c 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -46,8 +46,8 @@ static herr_t H5O_layout_free(void *_mesg);
static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
void *_mesg);
static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -587,8 +587,8 @@ done:
*/
static void *
H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id)
{
H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src;
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index acdd1e1..e96483a 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -46,10 +46,11 @@ static herr_t H5O_linfo_free(void *_mesg);
static herr_t H5O_linfo_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
void *_mesg);
static void *H5O_linfo_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
-static herr_t H5O_linfo_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_linfo_post_copy_file(const H5O_loc_t *parent_src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_linfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -379,8 +380,8 @@ done:
*/
static void *
H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id)
{
H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src;
H5O_linfo_t *linfo_dst = NULL;
@@ -501,7 +502,8 @@ done:
*/
static herr_t
H5O_linfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_linfo_t *linfo_src = (const H5O_linfo_t *)mesg_src;
H5O_linfo_t *linfo_dst = (H5O_linfo_t *)mesg_dst;
diff --git a/src/H5Olink.c b/src/H5Olink.c
index a374807..12171b2 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -49,10 +49,11 @@ static herr_t H5O_link_free(void *_mesg);
static herr_t H5O_link_pre_copy_file(H5F_t *file_src, const void *mesg_src,
hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_link_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
- hid_t dxpl_id);
-static herr_t H5O_link_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_link_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_link_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -717,8 +718,8 @@ H5O_link_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata,
- hid_t UNUSED dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, hid_t UNUSED dxpl_id)
{
H5O_link_t *link_src = (H5O_link_t *)native_src;
void *ret_value; /* Return value */
@@ -758,7 +759,8 @@ done:
*/
static herr_t
H5O_link_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_link_t *link_src = (const H5O_link_t *)mesg_src;
H5O_link_t *link_dst = (H5O_link_t *)mesg_dst;
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index f12c835..c9a0997 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -1855,7 +1855,7 @@ done:
void *
H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
- H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
+ unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
{
void *ret_value;
@@ -1873,7 +1873,7 @@ H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
/* The copy_file callback will return an H5O_shared_t only if the message
* to be copied is a committed datatype.
*/
- if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, recompute_size, cpy_info, udata, dxpl_id)))
+ if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, recompute_size, mesg_flags, cpy_info, udata, dxpl_id)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object header message to file")
done:
@@ -1986,7 +1986,7 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header")
/* Update the message flags */
- idx_msg->flags = mesg_flags;
+ idx_msg->flags = (uint8_t)mesg_flags;
/* Mark the message as modified */
idx_msg->dirty = TRUE;
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index a5d01bd..d4cc3fb 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -234,8 +234,8 @@ struct H5O_msg_class_t {
herr_t (*set_share)(void*, const H5O_shared_t*); /* Set shared information */
htri_t (*can_share)(const void *); /* Is message allowed to be shared? */
herr_t (*pre_copy_file)(H5F_t *, const void *, hbool_t *, const H5O_copy_t *, void *); /*"pre copy" action when copying native value to file */
- void *(*copy_file)(H5F_t *, void *, H5F_t *, hbool_t *, H5O_copy_t *, void *, hid_t); /*copy native value to file */
- herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
+ void *(*copy_file)(H5F_t *, void *, H5F_t *, hbool_t *, unsigned *, H5O_copy_t *, void *, hid_t); /*copy native value to file */
+ herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, unsigned *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
herr_t (*get_crt_index)(const void *, H5O_msg_crt_idx_t *); /* Get message's creation index */
herr_t (*set_crt_index)(void *, H5O_msg_crt_idx_t); /* Set message's creation index */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
@@ -325,6 +325,7 @@ typedef struct H5O_obj_class_t {
void *(*create)(H5F_t *, void *, H5G_loc_t *, hid_t ); /*create an object of this class */
H5O_loc_t *(*get_oloc)(hid_t ); /*get the object header location for an object */
herr_t (*bh_info)(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); /*get the index & heap info for an object */
+ herr_t (*flush)(H5G_loc_t *loc, hid_t dxpl_id); /*flush an opened object of this class */
} H5O_obj_class_t;
/* Node in skip list to map addresses from one file to another during object header copy */
@@ -527,7 +528,7 @@ H5_DLL herr_t H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg);
H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh);
H5_DLL hid_t H5O_open_by_loc(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref);
H5_DLL herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_mesg_t *mesg);
-H5_DLL const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh);
+H5_DLL const H5O_obj_class_t * H5O_obj_class(const H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, hbool_t *deleted);
H5_DLL herr_t H5O_inc_rc(H5O_t *oh);
H5_DLL herr_t H5O_dec_rc(H5O_t *oh);
@@ -549,7 +550,7 @@ H5_DLL herr_t H5O_msg_remove_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *ty
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
H5_DLL void *H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hbool_t *recompute_size,
- H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+ unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
@@ -586,10 +587,12 @@ H5_DLL herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
const H5O_msg_class_t *mesg_type, H5O_shared_t *sh_mesg);
H5_DLL herr_t H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+ hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void *udata, hid_t dxpl_id);
H5_DLL herr_t H5O_shared_post_copy_file (H5F_t *f,
const H5O_msg_class_t *mesg_type, const H5O_shared_t *shared_src,
- H5O_shared_t *shared_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5O_shared_t *shared_dst, unsigned *mesg_flags, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
H5_DLL herr_t H5O_shared_debug(const H5O_shared_t *mesg, FILE *stream,
int indent, int fwidth);
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 89ce865..f626106 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -61,6 +61,7 @@ static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_pline_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_pline_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_pline_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 97bd9a7..8e2dfa4 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -99,7 +99,9 @@ typedef struct H5O_t H5O_t;
#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* ========= Object Copy properties ============ */
-#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
+#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
+#define H5O_CPY_MERGE_COMM_DT_LIST_NAME "merge committed dtype list" /* List of datatype paths to search in the dest file for merging */
+#define H5O_CPY_MCDT_SEARCH_CB_NAME "committed dtype list search" /* Callback function when the search for a matching committed datatype is complete */
/* If the module using this macro is allowed access to the private variables, access them directly */
#ifdef H5O_PACKAGE
@@ -133,6 +135,18 @@ typedef struct H5O_loc_t {
* its file's count of open objects. */
} H5O_loc_t;
+/* Typedef for linked list of datatype merge suggestions */
+typedef struct H5O_copy_dtype_merge_list_t {
+ char *path; /* Path to datatype in destination file */
+ struct H5O_copy_dtype_merge_list_t *next; /* Next object in list */
+} H5O_copy_dtype_merge_list_t;
+
+/* Structure for callback property before searching the global list of committed datatypes at destination */
+typedef struct H5O_mcdt_cb_info_t {
+ H5O_mcdt_search_cb_t func;
+ void *user_data;
+} H5O_mcdt_cb_info_t;
+
/* Settings/flags for copying an object */
typedef struct H5O_copy_t {
hbool_t copy_shallow; /* Flag to perform shallow hierarchy copy */
@@ -141,10 +155,16 @@ typedef struct H5O_copy_t {
hbool_t expand_ref; /* Flag to expand object references */
hbool_t copy_without_attr; /* Flag to not copy attributes */
hbool_t preserve_null; /* Flag to not delete NULL messages */
+ hbool_t merge_comm_dt; /* Flag to merge committed datatypes in dest file */
+ H5O_copy_dtype_merge_list_t *dst_dt_suggestion_list; /* Suggestions for merging committed datatypes */
int curr_depth; /* Current depth in hierarchy copied */
int max_depth; /* Maximum depth in hierarchy to copy */
H5SL_t *map_list; /* Skip list to hold address mappings */
+ H5SL_t *dst_dt_list; /* Skip list to hold committed datatypes in dest file */
+ hbool_t dst_dt_list_complete; /* Whether the destination datatype list is complete (i.e. not only populated with "suggestions" from H5Padd_merge_committed_dtype_path) */
H5O_t *oh_dst; /* The destination object header */
+ H5O_mcdt_search_cb_t mcdt_cb; /* The callback to invoke before searching the global list of committed datatypes at destination */
+ void *mcdt_ud; /* User data passed to callback */
} H5O_copy_t;
/* Header message IDs */
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index 2379d6b..a7d386a 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -43,7 +43,8 @@
#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */
#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */
#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /* Copy NULL messages (empty space) */
-#define H5O_COPY_ALL (0x003Fu) /* All object copying flags (for internal checking) */
+#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /* Merge committed datatypes in dest file */
+#define H5O_COPY_ALL (0x007Fu) /* All object copying flags (for internal checking) */
/* Flags for shared message indexes.
* Pass these flags in using the mesg_type_flags parameter in
@@ -131,6 +132,14 @@ typedef uint32_t H5O_msg_crt_idx_t;
typedef herr_t (*H5O_iterate_t)(hid_t obj, const char *name, const H5O_info_t *info,
void *op_data);
+typedef enum H5O_mcdt_search_ret_t {
+ H5O_MCDT_SEARCH_ERROR = -1, /* Abort H5Ocopy */
+ H5O_MCDT_SEARCH_CONT, /* Continue the global search of all committed datatypes in the destination file */
+ H5O_MCDT_SEARCH_STOP /* Stop the search, but continue copying. The committed datatype will be copied but not merged. */
+} H5O_mcdt_search_ret_t;
+
+/* Callback to invoke when completing the search for a matching committed datatype from the committed dtype list */
+typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data);
/********************/
/* Public Variables */
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 8ae73f7..905c4e9 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -55,6 +55,7 @@ static herr_t H5O_sdspace_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_sdspace_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_sdspace_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_sdspace_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 4cc30e8..c29e2c7 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -589,8 +589,8 @@ done:
herr_t
H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void UNUSED *udata, hid_t dxpl_id)
{
const H5O_shared_t *shared_src = (const H5O_shared_t *)_native_src; /* Alias to shared info in native source */
H5O_shared_t *shared_dst = (H5O_shared_t *)_native_dst; /* Alias to shared info in native destination message */
@@ -621,16 +621,18 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
/* Set copied metadata tag */
H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, FAIL);
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5SM_DEFER, mesg_type->id, _native_dst, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5SM_DEFER, mesg_type->id, _native_dst, mesg_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
/* Reset metadata tag */
H5_END_TAG(FAIL);
} /* end if */
- else
+ else {
/* Mark the message as committed - as it will be committed in post copy
*/
H5O_UPDATE_SHARED(shared_dst, H5O_SHARE_TYPE_COMMITTED, file_dst, mesg_type->id, 0, HADDR_UNDEF)
+ *mesg_flags |= H5O_MSG_FLAG_SHARED;
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -657,8 +659,8 @@ done:
*/
herr_t
H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
- const H5O_shared_t *shared_src, H5O_shared_t *shared_dst, hid_t dxpl_id,
- H5O_copy_t *cpy_info)
+ const H5O_shared_t *shared_src, H5O_shared_t *shared_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -675,6 +677,7 @@ H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
H5O_loc_t src_oloc;
/* Copy the shared object from source to destination */
+ H5O_loc_reset(&dst_oloc);
dst_oloc.file = f;
src_oloc.file = shared_src->file;
src_oloc.addr = shared_src->u.loc.oh_addr;
@@ -688,7 +691,7 @@ H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
else
/* Share the message */
if(H5SM_try_share(f, dxpl_id, NULL, H5SM_WAS_DEFERRED, mesg_type->id,
- shared_dst, NULL) < 0)
+ shared_dst, mesg_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't share message")
done:
diff --git a/src/H5Oshared.h b/src/H5Oshared.h
index ddacc25..3ec5709 100644
--- a/src/H5Oshared.h
+++ b/src/H5Oshared.h
@@ -320,7 +320,8 @@ done:
*/
static H5_inline void *
H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
+ hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void *udata, hid_t dxpl_id)
{
void *dst_mesg = NULL; /* Destination message */
void *ret_value; /* Return value */
@@ -348,8 +349,8 @@ H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst,
HDmemset(dst_mesg, 0, sizeof(H5O_shared_t));
/* Handle sharing destination message */
- if(H5O_shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE,
- _native_src, dst_mesg, recompute_size, cpy_info, udata, dxpl_id) < 0)
+ if(H5O_shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE, _native_src,
+ dst_mesg, recompute_size, mesg_flags, cpy_info, udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "unable to determine if message should be shared")
/* Set return value */
@@ -383,7 +384,8 @@ done:
*/
static H5_inline herr_t
H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
- H5O_loc_t *oloc_dst, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *oloc_dst, void *mesg_dst, unsigned *mesg_flags, hid_t dxpl_id,
+ H5O_copy_t *cpy_info)
{
const H5O_shared_t *shared_src = (const H5O_shared_t *)mesg_src; /* Alias to shared info in native source */
H5O_shared_t *shared_dst = (H5O_shared_t *)mesg_dst; /* Alias to shared info in native destination */
@@ -405,7 +407,7 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
#endif /* H5O_SHARED_POST_COPY_FILE */
#ifdef H5O_SHARED_POST_COPY_FILE_REAL
- /* Call native message's copy file callback to copy the message */
+ /* Call native message's post copy file callback to copy the message */
if(H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) <0 )
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file")
#endif /* H5O_SHARED_POST_COPY_FILE_REAL */
@@ -414,9 +416,16 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
* production if the DEFER pass determined it will not be shared; debug mode
* verifies that it is indeed the case */
if(H5O_shared_post_copy_file(oloc_dst->file, H5O_SHARED_TYPE,
- shared_src, shared_dst, dxpl_id, cpy_info) < 0)
+ shared_src, shared_dst, mesg_flags, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to fix shared message in post copy")
+#ifdef H5O_SHARED_POST_COPY_FILE_UPD
+ /* Call native message's post copy file update callback to update the
+ * message */
+ if(H5O_SHARED_POST_COPY_FILE_UPD(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to update native message")
+#endif /* H5O_SHARED_POST_COPY_FILE_UPD */
+
/* Make sure that if the the source or destination is committed, both are
* committed */
HDassert((shared_src->type == H5O_SHARE_TYPE_COMMITTED)
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 42cd92c..d5f5f86 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -44,10 +44,11 @@ static size_t H5O_stab_size(const H5F_t *f, hbool_t disable_shared, const void *
static herr_t H5O_stab_free(void *_mesg);
static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg);
static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id);
-static herr_t H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id);
+static herr_t H5O_stab_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_stab_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -307,8 +308,8 @@ done:
*/
static void *
H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void *_udata, hid_t dxpl_id)
{
H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
H5O_stab_t *stab_dst = NULL;
@@ -370,8 +371,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src;
H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst;
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index f07aa87..0a41371 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -410,7 +410,7 @@ H5P_dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED si
/* Sanity check */
HDassert(layout1);
- HDassert(layout1);
+ HDassert(layout2);
HDassert(size == sizeof(H5O_layout_t));
/* Check for different layout type */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index c75cf61..2d46ec7 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -40,6 +40,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5VLprivate.h" /* VOL plugins */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory Management */
#include "H5Ppkg.h" /* Property lists */
/* Includes needed to set as default file driver */
@@ -125,10 +126,18 @@
/* Definition for external file cache size */
#define H5F_ACS_EFC_SIZE_SIZE sizeof(unsigned)
#define H5F_ACS_EFC_SIZE_DEF 0
+
/* Definition for VOL plugin */
#define H5F_ACS_VOL_SIZE sizeof(void *)
#define H5F_ACS_VOL_DEF H5VL_NATIVE
+/* Definition of pointer to initial file image info */
+#define H5F_ACS_FILE_IMAGE_INFO_SIZE sizeof(H5FD_file_image_info_t)
+#define H5F_ACS_FILE_IMAGE_INFO_DEF H5FD_DEFAULT_FILE_IMAGE_INFO
+#define H5F_ACS_FILE_IMAGE_INFO_DEL H5P_file_image_info_del
+#define H5F_ACS_FILE_IMAGE_INFO_COPY H5P_file_image_info_copy
+#define H5F_ACS_FILE_IMAGE_INFO_CLOSE H5P_file_image_info_close
+
/******************/
/* Local Typedefs */
/******************/
@@ -154,6 +163,10 @@ static herr_t H5P_facc_reg_prop(H5P_genclass_t *pclass);
static herr_t H5P_facc_create(hid_t fapl_id, void *copy_data);
static herr_t H5P_facc_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_data);
+/* File image info property callbacks */
+static herr_t H5P_file_image_info_del(hid_t prop_id, const char *name, size_t size, void *value);
+static herr_t H5P_file_image_info_copy(const char *name, size_t size, void *value);
+static herr_t H5P_file_image_info_close(const char *name, size_t size, void *value);
/*********************/
/* Package Variables */
@@ -221,6 +234,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */
unsigned efc_size = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */
H5VL_class_t *vol_cls = H5F_ACS_VOL_DEF; /* Default VOL plugin */
+ H5FD_file_image_info_t file_image_info = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -310,6 +324,10 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
if(H5P_register_real(pclass, H5F_ACS_VOL_NAME, H5F_ACS_VOL_SIZE, &vol_cls, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the initial file image info */
+ if(H5P_register_real(pclass, H5F_ACS_FILE_IMAGE_INFO_NAME, H5F_ACS_FILE_IMAGE_INFO_SIZE, &file_image_info, NULL, NULL, NULL, H5F_ACS_FILE_IMAGE_INFO_DEL, H5F_ACS_FILE_IMAGE_INFO_COPY, NULL, H5F_ACS_FILE_IMAGE_INFO_CLOSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_facc_reg_prop() */
@@ -2140,7 +2158,6 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_elink_file_cache_size() */
-/* MSC Begin update */
/*-------------------------------------------------------------------------
* Function: H5P_set_vol
@@ -2184,3 +2201,484 @@ H5P_set_vol(H5P_genplist_t *plist, H5VL_class_t *vol_cls)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_set_vol() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_file_image
+ *
+ * Purpose: Sets the initial file image. Some file drivers can initialize
+ * the starting data in a file from a buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len)
+{
+ H5P_genplist_t *fapl; /* Property list pointer */
+ H5FD_file_image_info_t image_info; /* File image info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*xz", fapl_id, buf_ptr, buf_len);
+
+ /* validate parameters */
+ if(!(((buf_ptr == NULL) && (buf_len == 0)) || ((buf_ptr != NULL) && (buf_len > 0))))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "inconsistant buf_ptr and buf_len");
+
+ /* Get the plist structure */
+ if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get old image info */
+ if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get old file image pointer")
+
+ /* Release previous buffer, if it exists */
+ if(image_info.buffer != NULL) {
+ if(image_info.callbacks.image_free) {
+ if(SUCCEED != image_info.callbacks.image_free(image_info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, image_info.callbacks.udata))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
+ } /* end if */
+ else
+ H5MM_xfree(image_info.buffer);
+ } /* end if */
+
+ /* Update struct */
+ if(buf_ptr) {
+ /* Allocate memory */
+ if(image_info.callbacks.image_malloc) {
+ if(NULL == (image_info.buffer = image_info.callbacks.image_malloc(buf_len,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, image_info.callbacks.udata)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
+ } /* end if */
+ else
+ if(NULL == (image_info.buffer = H5MM_malloc(buf_len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
+
+ /* Copy data */
+ if(image_info.callbacks.image_memcpy) {
+ if(image_info.buffer != image_info.callbacks.image_memcpy(image_info.buffer,
+ buf_ptr, buf_len, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET,
+ image_info.callbacks.udata))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
+ } /* end if */
+ else
+ HDmemcpy(image_info.buffer, buf_ptr, buf_len);
+ } /* end if */
+ else
+ image_info.buffer = NULL;
+
+ image_info.size = buf_len;
+
+ /* Set values */
+ if(H5P_set(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file image info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_file_image() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_file_image
+ *
+ * Purpose: If the file image exists and buf_ptr_ptr is not NULL,
+ * allocate a buffer of the correct size, copy the image into
+ * the new buffer, and return the buffer to the caller in
+ * *buf_ptr_ptr. Do this using the file image callbacks
+ * if defined.
+ *
+ * NB: It is the responsibility of the caller to free the
+ * buffer whose address is returned in *buf_ptr_ptr. Do
+ * this using free if the file image callbacks are not
+ * defined, or with whatever method is appropriate if
+ * the callbacks are defined.
+ *
+ * If buf_ptr_ptr is not NULL, and no image exists, set
+ * *buf_ptr_ptr to NULL.
+ *
+ * If buf_len_ptr is not NULL, set *buf_len_ptr equal
+ * to the length of the file image if it exists, and
+ * to 0 if it does not.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr)
+{
+ H5P_genplist_t *fapl; /* Property list pointer */
+ H5FD_file_image_info_t image_info; /* File image info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i**x*z", fapl_id, buf_ptr_ptr, buf_len_ptr);
+
+ /* Get the plist structure */
+ if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get values */
+ if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &image_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file image info")
+
+ /* verify file image field consistancy */
+ HDassert(((image_info.buffer != NULL) && (image_info.size > 0)) ||
+ ((image_info.buffer == NULL) && (image_info.size == 0)));
+
+ /* Set output size */
+ if(buf_len_ptr != NULL)
+ *buf_len_ptr = image_info.size;
+
+ /* Duplicate the image if desired, using callbacks if available */
+ if(buf_ptr_ptr != NULL) {
+ void * copy_ptr = NULL; /* Copy of memory image */
+
+ if(image_info.buffer != NULL) {
+ /* Allocate memory */
+ if(image_info.callbacks.image_malloc) {
+ if(NULL == (copy_ptr = image_info.callbacks.image_malloc(image_info.size,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET, image_info.callbacks.udata)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
+ } /* end if */
+ else
+ if(NULL == (copy_ptr = H5MM_malloc(image_info.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate copy")
+
+ /* Copy data */
+ if(image_info.callbacks.image_memcpy) {
+ if(copy_ptr != image_info.callbacks.image_memcpy(copy_ptr, image_info.buffer,
+ image_info.size, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET,
+ image_info.callbacks.udata))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
+ } /* end if */
+ else
+ HDmemcpy(copy_ptr, image_info.buffer, image_info.size);
+ } /* end if */
+
+ *buf_ptr_ptr = copy_ptr;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_file_image */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_file_image_callbacks
+ *
+ * Purpose: Sets the callbacks for file images. Some file drivers allow
+ * the use of user-defined callbacks for allocating, freeing and
+ * copying the drivers internal buffer, potentially allowing a
+ * clever user to do optimizations such as avoiding large mallocs
+ * and memcpys or to perform detailed logging.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr)
+{
+ H5P_genplist_t *fapl; /* Property list pointer */
+ H5FD_file_image_info_t info; /* File image info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*x", fapl_id, callbacks_ptr);
+
+ /* Get the plist structure */
+ if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get old info */
+ if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get old file image info")
+
+ /* verify file image field consistancy */
+ HDassert(((info.buffer != NULL) && (info.size > 0)) ||
+ ((info.buffer == NULL) && (info.size == 0)));
+
+ /* Make sure a file image hasn't already been set */
+ if(info.buffer != NULL || info.size > 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_SETDISALLOWED, FAIL, "setting callbacks when an image is already set is forbidden. It could cause memory leaks.")
+
+ /* verify that callbacks_ptr is not NULL */
+ if(NULL == callbacks_ptr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL callbacks_ptr")
+
+ /* Make sure udata callbacks are going to be set if udata is going to be set */
+ if(callbacks_ptr->udata)
+ if(callbacks_ptr->udata_copy == NULL || callbacks_ptr->udata_free == NULL)
+ HGOTO_ERROR(H5E_PLIST, H5E_SETDISALLOWED, FAIL, "udata callbacks must be set if udata is set")
+
+ /* Release old udata if it exists */
+ if(info.callbacks.udata != NULL) {
+ HDassert(info.callbacks.udata_free);
+ if(info.callbacks.udata_free(info.callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
+ } /* end if */
+
+ /* Update struct */
+ info.callbacks = *callbacks_ptr;
+
+ if(callbacks_ptr->udata) {
+ HDassert(callbacks_ptr->udata_copy);
+ HDassert(callbacks_ptr->udata_free);
+ if((info.callbacks.udata = callbacks_ptr->udata_copy(callbacks_ptr->udata)) == NULL)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy the suppplied udata")
+ } /* end if */
+
+ /* Set values */
+ if(H5P_set(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file image info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_file_image_callbacks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_file_image_callbacks
+ *
+ * Purpose: Sets the callbacks for file images. Some file drivers allow
+ * the use of user-defined callbacks for allocating, freeing and
+ * copying the drivers internal buffer, potentially allowing a
+ * clever user to do optimizations such as avoiding large mallocs
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr)
+{
+ H5P_genplist_t *fapl; /* Property list pointer */
+ H5FD_file_image_info_t info; /* File image info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*x", fapl_id, callbacks_ptr);
+
+ /* Get the plist structure */
+ if(NULL == (fapl = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get old info */
+ if(H5P_get(fapl, H5F_ACS_FILE_IMAGE_INFO_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file image info")
+
+ /* verify file image field consistancy */
+ HDassert(((info.buffer != NULL) && (info.size > 0)) ||
+ ((info.buffer == NULL) && (info.size == 0)));
+
+ /* verify that callbacks_ptr is not NULL */
+ if(NULL == callbacks_ptr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL callbacks_ptr")
+
+ /* Transfer values to parameters */
+ *callbacks_ptr = info.callbacks;
+
+ /* Copy udata if it exists */
+ if(info.callbacks.udata != NULL) {
+ HDassert(info.callbacks.udata_copy);
+ if((callbacks_ptr->udata = info.callbacks.udata_copy(info.callbacks.udata)) == 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't copy udata")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_file_image_callbacks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_file_image_info_del
+ *
+ * Purpose: Delete callback for the file image info property, called
+ * when the property is deleted from the plist. The buffer
+ * and udata may need to be freed, possibly using their
+ * respective callbacks so the default free won't work.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_file_image_info_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ H5FD_file_image_info_t info; /* Image info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(value) {
+ info = *(H5FD_file_image_info_t *)value;
+
+ /* verify file image field consistancy */
+ HDassert(((info.buffer != NULL) && (info.size > 0)) ||
+ ((info.buffer == NULL) && (info.size == 0)));
+
+ if(info.buffer && info.size > 0) {
+ /* Free buffer */
+ if(info.callbacks.image_free) {
+ if(info.callbacks.image_free(info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, info.callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
+ } /* end if */
+ else
+ free(info.buffer);
+ } /* end if */
+
+ /* Free udata if it exists */
+ if(info.callbacks.udata) {
+ if(NULL == info.callbacks.udata_free)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined")
+
+ if(info.callbacks.udata_free(info.callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_file_image_info_del() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_file_image_info_copy
+ *
+ * Purpose: Copy callback for the file image info property. The buffer
+ * and udata may need to be copied, possibly using their
+ * respective callbacks so the default copy won't work.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_file_image_info_copy(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ H5FD_file_image_info_t *info; /* Image info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(value) {
+ info = (H5FD_file_image_info_t *)value;
+
+ /* verify file image field consistancy */
+ HDassert(((info->buffer != NULL) && (info->size > 0)) ||
+ ((info->buffer == NULL) && (info->size == 0)));
+
+ if(info->buffer && info->size > 0) {
+ void *old_buffer; /* Pointer to old image buffer */
+
+ /* Store the old buffer */
+ old_buffer = info->buffer;
+
+ /* Allocate new buffer */
+ if(info->callbacks.image_malloc) {
+ if(NULL == (info->buffer = info->callbacks.image_malloc(info->size,
+ H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY, info->callbacks.udata)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "image malloc callback failed")
+ } /* end if */
+ else {
+ if(NULL == (info->buffer = H5MM_malloc(info->size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
+ } /* end else */
+
+ /* Copy data to new buffer */
+ if(info->callbacks.image_memcpy) {
+ if(info->buffer != info->callbacks.image_memcpy(info->buffer, old_buffer,
+ info->size, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY,
+ info->callbacks.udata))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed")
+ } /* end if */
+ else
+ HDmemcpy(info->buffer, old_buffer, info->size);
+ } /* end if */
+ } /* end if */
+
+ /* Copy udata if it exists */
+ if(info->callbacks.udata) {
+ void *old_udata = info->callbacks.udata;
+
+ if(NULL == info->callbacks.udata_copy)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_copy not defined")
+
+ info->callbacks.udata = info->callbacks.udata_copy(old_udata);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_file_image_info_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_file_image_info_close
+ *
+ * Purpose: Close callback for the file image info property. The buffer
+ * and udata may need to be freed, possibly using their
+ * respective callbacks so the standard free won't work.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Jacob Gruber
+ * Thurday, August 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_file_image_info_close(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ H5FD_file_image_info_t info; /* Image info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(value) {
+ info = *(H5FD_file_image_info_t *)value;
+
+ if(info.buffer != NULL && info.size > 0) {
+ /* Free buffer */
+ if(info.callbacks.image_free) {
+ if(info.callbacks.image_free(info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE,
+ info.callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed")
+ } /* end if */
+ else
+ H5MM_xfree(info.buffer);
+ } /* end if */
+ } /* end if */
+
+ /* Free udata if it exists */
+ if(info.callbacks.udata) {
+ if(NULL == info.callbacks.udata_free)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined")
+ if(info.callbacks.udata_free(info.callbacks.udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_file_image_info_close() */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 08b8af6..46a06a0 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -51,6 +51,7 @@
typedef struct {
const H5P_genclass_t *parent; /* Pointer to parent class */
const char *name; /* Pointer to name to check */
+ H5P_genclass_t *new_class; /* Pointer to class during path traversal */
} H5P_check_class_t;
@@ -1358,11 +1359,11 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
/*--------------------------------------------------------------------------
NAME
- H5P_check_class
+ H5P_open_class_path_cb
PURPOSE
Internal callback routine to check for duplicated names in parent class.
USAGE
- int H5P_check_class(obj, id, key)
+ int H5P_open_class_path_cb(obj, id, key)
H5P_genclass_t *obj; IN: Pointer to class
hid_t id; IN: ID of object being looked at
const void *key; IN: Pointer to information used to compare
@@ -1378,27 +1379,29 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod)
REVISION LOG
--------------------------------------------------------------------------*/
static int
-H5P_check_class(void *_obj, hid_t UNUSED id, void *_key)
+H5P_open_class_path_cb(void *_obj, hid_t UNUSED id, void *_key)
{
- H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
- const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */
- int ret_value=0; /* Return value */
+ H5P_genclass_t *obj = (H5P_genclass_t *)_obj; /* Pointer to the class for this ID */
+ H5P_check_class_t *key = (H5P_check_class_t *)_key; /* Pointer to key information for comparison */
+ int ret_value = 0; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(obj);
- HDassert(H5I_GENPROP_CLS==H5I_get_type(id));
+ HDassert(H5I_GENPROP_CLS == H5I_get_type(id));
HDassert(key);
/* Check if the class object has the same parent as the new class */
- if(obj->parent==key->parent) {
+ if(obj->parent == key->parent) {
/* Check if they have the same name */
- if(HDstrcmp(obj->name,key->name)==0)
- ret_value=1; /* Indicate a match */
+ if(HDstrcmp(obj->name, key->name) == 0) {
+ key->new_class = obj;
+ ret_value = 1; /* Indicate a match */
+ } /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5P_check_class() */
+} /* end H5P_open_class_path_cb() */
/*--------------------------------------------------------------------------
@@ -4555,8 +4558,8 @@ H5P_open_class_path(const char *path)
char *curr_name; /* Pointer to current component of path name */
char *delimit; /* Pointer to path delimiter during traversal */
H5P_genclass_t *curr_class; /* Pointer to class during path traversal */
- H5P_genclass_t *ret_value; /* Return value */
H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */
+ H5P_genclass_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -4569,20 +4572,24 @@ H5P_open_class_path(const char *path)
/* Find the generic property class with this full path */
curr_name = tmp_path;
curr_class = NULL;
- while((delimit=HDstrchr(curr_name,'/'))!=NULL) {
+ while(NULL != (delimit = HDstrchr(curr_name, '/'))) {
/* Change the delimiter to terminate the string */
- *delimit='\0';
+ *delimit = '\0';
/* Set up the search structure */
- check_info.parent=curr_class;
- check_info.name=curr_name;
+ check_info.parent = curr_class;
+ check_info.name = curr_name;
+ check_info.new_class = NULL;
/* Find the class with this name & parent by iterating over the open classes */
- if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
- HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
+ if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
+ else if(NULL == check_info.new_class)
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
/* Advance the pointer in the path to the start of the next component */
- curr_name=delimit+1;
+ curr_class = check_info.new_class;
+ curr_name = delimit + 1;
} /* end while */
/* Should be pointing to the last component in the path name now... */
@@ -4590,13 +4597,16 @@ H5P_open_class_path(const char *path)
/* Set up the search structure */
check_info.parent = curr_class;
check_info.name = curr_name;
+ check_info.new_class = NULL;
/* Find the class with this name & parent by iterating over the open classes */
- if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
+ if(H5I_iterate(H5I_GENPROP_CLS, H5P_open_class_path_cb, &check_info, FALSE) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADITER, NULL, "can't iterate over classes")
+ else if(NULL == check_info.new_class)
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
/* Copy it */
- if(NULL == (ret_value = H5P_copy_pclass(curr_class)))
+ if(NULL == (ret_value = H5P_copy_pclass(check_info.new_class)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class")
done:
@@ -4604,7 +4614,7 @@ done:
H5MM_xfree(tmp_path);
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5P_open_class_path() */
+} /* H5P_open_class_path() */
/*--------------------------------------------------------------------------
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index 217d0ba..217d0ba 100755..100644
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
diff --git a/src/H5Pocpypl.c b/src/H5Pocpypl.c
index af50d80..23f8e4b 100755..100644
--- a/src/H5Pocpypl.c
+++ b/src/H5Pocpypl.c
@@ -35,7 +35,9 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
@@ -47,7 +49,13 @@
/* Definitions for copy options */
#define H5O_CPY_OPTION_SIZE sizeof(unsigned)
#define H5O_CPY_OPTION_DEF 0
-
+/* Definitions for merge committed dtype list */
+#define H5O_CPY_MERGE_COMM_DT_LIST_SIZE sizeof(char *)
+#define H5O_CPY_MERGE_COMM_DT_LIST_DEF NULL
+#define H5O_CPY_MERGE_COMM_DT_LIST_CMP H5P_ocpy_merge_comm_dt_list_cmp
+/* Definitions for callback function when completing the search for a matching committed datatype from the committed dtype list */
+#define H5O_CPY_MCDT_SEARCH_CB_SIZE sizeof(H5O_mcdt_cb_info_t)
+#define H5O_CPY_MCDT_SEARCH_CB_DEF {NULL,NULL}
/******************/
/* Local Typedefs */
@@ -63,8 +71,17 @@
/* Local Prototypes */
/********************/
+/* General routines */
+static H5O_copy_dtype_merge_list_t *H5P_free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list);
+
/* Property class callbacks */
static herr_t H5P_ocpy_reg_prop(H5P_genclass_t *pclass);
+static herr_t H5P_ocpy_copy(hid_t dst_plist_id, hid_t src_plist_id,
+ void *copy_data);
+static herr_t H5P_ocpy_close(hid_t ocpypl_id, void *close_data);
+
+/* Property callbacks */
+static int H5P_ocpy_merge_comm_dt_list_cmp(const void *value1, const void *value2, size_t size);
/*********************/
@@ -80,9 +97,9 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
H5P_ocpy_reg_prop, /* Default property registration routine */
NULL, /* Class creation callback */
NULL, /* Class creation callback info */
- NULL, /* Class copy callback */
+ H5P_ocpy_copy, /* Class copy callback */
NULL, /* Class copy callback info */
- NULL, /* Class close callback */
+ H5P_ocpy_close, /* Class close callback */
NULL /* Class close callback info */
}};
@@ -96,6 +113,9 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5O_copy_dtype_merge_list_t struct */
+H5FL_DEFINE(H5O_copy_dtype_merge_list_t);
+
/*-------------------------------------------------------------------------
@@ -109,10 +129,12 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
* October 31, 2006
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5P_ocpy_reg_prop(H5P_genclass_t *pclass)
{
unsigned ocpy_option = H5O_CPY_OPTION_DEF; /* Default object copy flags */
+ H5O_copy_dtype_merge_list_t *merge_comm_dtype_list = H5O_CPY_MERGE_COMM_DT_LIST_DEF; /* Default merge committed dtype list */
+ H5O_mcdt_cb_info_t mcdt_cb = H5O_CPY_MCDT_SEARCH_CB_DEF; /* Default callback before searching the global list of committed datatypes at destination */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -121,12 +143,222 @@ H5P_ocpy_reg_prop(H5P_genclass_t *pclass)
if(H5P_register_real(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, &ocpy_option, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register merge named dtype list property */
+ if(H5P_register_real(pclass, H5O_CPY_MERGE_COMM_DT_LIST_NAME, H5O_CPY_MERGE_COMM_DT_LIST_SIZE, &merge_comm_dtype_list, NULL, NULL, NULL, NULL, NULL, H5O_CPY_MERGE_COMM_DT_LIST_CMP, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register property for callback when completing the search for a matching named datatype from the named dtype list */
+ if(H5P_register_real(pclass, H5O_CPY_MCDT_SEARCH_CB_NAME, H5O_CPY_MCDT_SEARCH_CB_SIZE, &mcdt_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_ocpy_reg_prop() */
/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_copy
+ *
+ * Purpose: Callback routine which is called whenever any object
+ * copy property list is copied. This routine copies
+ * the properties from the old list to the new list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocpy_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data)
+{
+ H5O_copy_dtype_merge_list_t *src_dt_list, *dst_dt_list = NULL; /* Source & destination merge named datatype lists */
+ H5O_copy_dtype_merge_list_t *dst_dt_list_tail = NULL, *tmp_dt_list = NULL; /* temporary merge named datatype lists */
+ H5P_genplist_t *src_plist; /* Pointer to source property list */
+ H5P_genplist_t *dst_plist; /* Pointer to destination property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Verify property list IDs */
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+
+ /* Get the merge committed dtype list property from the old property list */
+ if(H5P_get(src_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &src_dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Make copy of merge committed dtype list */
+ while(src_dt_list) {
+ /* Copy src_dt_list */
+ if(NULL == (tmp_dt_list = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (tmp_dt_list->path = H5MM_strdup(src_dt_list->path)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add copied node to dest dtype list */
+ if(dst_dt_list_tail) {
+ dst_dt_list_tail->next = tmp_dt_list;
+ dst_dt_list_tail = tmp_dt_list;
+ } /* end if */
+ else {
+ dst_dt_list = tmp_dt_list;
+ dst_dt_list_tail = tmp_dt_list;
+ } /* end else */
+ tmp_dt_list = NULL;
+
+ /* Advance src_dt_list pointer */
+ src_dt_list = src_dt_list->next;
+ } /* end while */
+
+ /* Set the merge named dtype list property for the destination property list
+ */
+ if(H5P_set(dst_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dst_dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge committed dtype list")
+
+done:
+ if(ret_value < 0) {
+ dst_dt_list = H5P_free_merge_comm_dtype_list(dst_dt_list);
+ if(tmp_dt_list) {
+ tmp_dt_list->path = (char *)H5MM_xfree(tmp_dt_list->path);
+ tmp_dt_list = H5FL_FREE(H5O_copy_dtype_merge_list_t, tmp_dt_list);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_close
+ *
+ * Purpose: Callback routine which is called whenever any object copy
+ * property list is closed. This routine performs any generic
+ * cleanup needed on the properties the library put into the
+ * list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocpy_close(hid_t ocpypl_id, void UNUSED *close_data)
+{
+ H5O_copy_dtype_merge_list_t *dt_list; /* Merge named datatype list */
+ H5P_genplist_t *plist; /* Property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check arguments */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+
+ /* Get the merge named dtype list property from the old property list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Free the merge named dtype list */
+ dt_list = H5P_free_merge_comm_dtype_list(dt_list);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_merge_comm_dt_list_cmp
+ *
+ * Purpose: Callback routine which is called whenever the merge
+ * named dtype property in the object copy property list
+ * is compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P_ocpy_merge_comm_dt_list_cmp(const void *_dt_list1, const void *_dt_list2,
+ size_t UNUSED size)
+{
+ const H5O_copy_dtype_merge_list_t *dt_list1 = *(H5O_copy_dtype_merge_list_t * const *)_dt_list1, /* Create local aliases for values */
+ *dt_list2 = *(H5O_copy_dtype_merge_list_t * const *)_dt_list2;
+ herr_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert(_dt_list1);
+ HDassert(_dt_list2);
+ HDassert(size == sizeof(H5O_copy_dtype_merge_list_t *));
+
+ /* Walk through the lists, comparing each path. For the lists to be the
+ * same, the paths must be in the same order. */
+ while(dt_list1 && dt_list2) {
+ /* Compare paths */
+ ret_value = HDstrcmp(dt_list1->path, dt_list2->path);
+ if(ret_value != 0) HGOTO_DONE(ret_value)
+
+ /* Advance to next node */
+ dt_list1 = dt_list1->next;
+ dt_list2 = dt_list2->next;
+ } /* end while */
+
+ /* Check if one list is longer than the other */
+ if(dt_list1) HGOTO_DONE(1)
+ if(dt_list2) HGOTO_DONE(-1)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_merge_comm_dt_list_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_free_merge_comm_dtype_list
+ *
+ * Purpose: Frees the provided merge named dtype list
+ *
+ * Return: NULL
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+static H5O_copy_dtype_merge_list_t *
+H5P_free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list)
+{
+ H5O_copy_dtype_merge_list_t *tmp_node;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Free the list */
+ while(dt_list) {
+ tmp_node = dt_list->next;
+ (void)H5MM_xfree(dt_list->path);
+ (void)H5FL_FREE(H5O_copy_dtype_merge_list_t, dt_list);
+ dt_list = tmp_node;
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(NULL);
+} /* H5P_free_merge_comm_dtype_list */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_copy_object
*
* Purpose: Set properties when copying an object (group, dataset, and datatype)
@@ -207,3 +439,210 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_copy_object() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Padd_merge_committed_dtype_path
+ *
+ * Purpose: Adds path to the list of paths to search first in the
+ * target file when merging committed datatypes during H5Ocopy
+ * (i.e. when using the H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG flag
+ * as set by H5Pset_copy_object). If the source named
+ * dataype is not found in the list of paths created by this
+ * function, the entire file will be searched.
+ *
+ * Usage: H5Padd_merge_committed_dtype_path(plist_id, path)
+ * hid_t plist_id; IN: Property list to copy object
+ * const char *path; IN: Path to add to list
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_copy_dtype_merge_list_t *old_list; /* Merge committed dtype list currently present */
+ H5O_copy_dtype_merge_list_t *new_obj = NULL; /* New object to add to list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*s", plist_id, path);
+
+ /* Check parameters */
+ if(!path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no path specified")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get dtype list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &old_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Add the new path to the list */
+ if(NULL == (new_obj = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (new_obj->path = H5MM_strdup(path)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ new_obj->next = old_list;
+
+ /* Update the list stored in the property list */
+ if(H5P_set(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &new_obj) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge named dtype list")
+
+done:
+ if(ret_value < 0)
+ if(new_obj) {
+ new_obj->path = (char *)H5MM_xfree(new_obj->path);
+ new_obj = H5FL_FREE(H5O_copy_dtype_merge_list_t, new_obj);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Padd_merge_committed_dtype_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pfree_merge_committed_dtype_paths
+ *
+ * Purpose: Frees and clears the list of paths created by
+ * H5Padd_merge_committed_dtype_path. A new list may then be
+ * created by calling H5Padd_merge_committed_dtype_path again.
+ *
+ * Usage: H5Pfree_merge_committed_dtype_paths(plist_id)
+ * hid_t plist_id; IN: Property list to copy object
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pfree_merge_committed_dtype_paths(hid_t plist_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_copy_dtype_merge_list_t *dt_list; /* Merge committed dtype list currently present */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", plist_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get dtype list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed dtype list")
+
+ /* Free dtype list */
+ dt_list = H5P_free_merge_comm_dtype_list(dt_list);
+
+ /* Update the list stored in the property list (to NULL) */
+ if(H5P_set(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge committed dtype list")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pfree_merge_committed_dtype_paths() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_mcdt_search_cb
+ *
+ * Purpose: Set the callback function when a matching committed datatype is not found
+ * from the list of paths stored in the object copy property list.
+ * H5Ocopy will invoke this callback before searching all committed datatypes
+ * at destination.
+ *
+ * Usage: H5Pset_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t func, void *op_data)
+ * hid_t plist_id; IN: Property list to copy object
+ * H5O_mcdt_search_cb_t func; IN: The callback function
+ * void *op_data; IN: The user data
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; November 28, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ix*x", plist_id, func, op_data);
+
+ /* Check if the callback function is NULL and the user data is non-NULL.
+ * This is almost certainly an error as the user data will not be used. */
+ if(!func && op_data)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Populate the callback info struct */
+ cb_info.func = func;
+ cb_info.user_data = op_data;
+
+ /* Set callback info */
+ if(H5P_set(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_mcdt_search_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_mcdt_search_cb
+ *
+ * Purpose: Retrieves the callback function and user data from the specified
+ * object copy property list.
+ *
+ * Usage: H5Pget_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
+ * hid_t plist_id; IN: Property list to copy object
+ * H5O_mcdt_search_cb_t *func; OUT: The callback function
+ * void **op_data; OUT: The user data
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; November 29, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x**x", plist_id, func, op_data);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get callback info */
+ if(H5P_get(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
+
+ if(func)
+ *func = cb_info.func;
+
+ if(op_data)
+ *op_data = cb_info.user_data;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_mcdt_search_cb() */
+
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 4c812cc..6cba897 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -30,6 +30,7 @@
#include "H5FDpublic.h"
#include "H5Ipublic.h"
#include "H5Lpublic.h"
+#include "H5Opublic.h"
#include "H5MMpublic.h"
#include "H5Tpublic.h"
#include "H5Zpublic.h"
@@ -326,6 +327,12 @@ H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low,
H5F_libver_t *high);
H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size);
H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size);
+H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len);
+H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr);
+H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id,
+ H5FD_file_image_callbacks_t *callbacks_ptr);
+H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id,
+ H5FD_file_image_callbacks_t *callbacks_ptr);
/* Dataset creation property list (DCPL) routines */
H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
@@ -432,6 +439,10 @@ H5_DLL herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **
/* Object copy property list (OCPYPL) routines */
H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd);
H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/);
+H5_DLL herr_t H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path);
+H5_DLL herr_t H5Pfree_merge_committed_dtype_paths(hid_t plist_id);
+H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data);
+H5_DLL herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
diff --git a/src/H5SM.c b/src/H5SM.c
index 8c00d34..62efb50 100755..100644
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -1099,7 +1099,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned defer_flags,
/* Set flags if this message was "written" without error and wasn't a
* 'defer' attempt; it is now either fully shared or "shareable".
*/
- if(mesg_flags && !(defer_flags & H5SM_DEFER)) {
+ if(mesg_flags) {
if(((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE)
*mesg_flags |= H5O_MSG_FLAG_SHAREABLE;
else {
@@ -1109,7 +1109,8 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned defer_flags,
} /* end if */
done:
- HDassert(!ret_value || ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE
+ HDassert((ret_value != TRUE)
+ || ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE
|| ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_SOHM);
#ifndef NDEBUG
/* If we previously deferred this operation, make sure the saved message
diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c
index daa1e4f..daa1e4f 100755..100644
--- a/src/H5SMbtree2.c
+++ b/src/H5SMbtree2.c
diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h
index 68dc484..68dc484 100755..100644
--- a/src/H5SMpkg.h
+++ b/src/H5SMpkg.h
diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h
index d072434..d072434 100755..100644
--- a/src/H5SMprivate.h
+++ b/src/H5SMprivate.h
diff --git a/src/H5T.c b/src/H5T.c
index 392228b..b27b152 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1450,7 +1450,8 @@ H5T_term_interface(void)
H5T_g.asoft = 0;
/* Unlock all datatypes, then free them */
- H5I_search(H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
+ /* note that we are ignoring the return value from H5I_iterate() */
+ H5I_iterate(H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
H5I_dec_type_ref(H5I_DATATYPE);
/* Reset all the datatype IDs */
diff --git a/src/H5Toh.c b/src/H5Toh.c
index 5878075..be853f1 100644
--- a/src/H5Toh.c
+++ b/src/H5Toh.c
@@ -77,7 +77,8 @@ const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{
H5O_dtype_open, /* open an object of this class */
H5O_dtype_create, /* create an object of this class */
H5O_dtype_get_oloc, /* get an object header location for an object */
- NULL /* get the index & heap info for an object */
+ NULL, /* get the index & heap info for an object */
+ NULL /* flush an opened object of this class */
}};
diff --git a/src/H5VL.c b/src/H5VL.c
index 293711f..f821463 100644
--- a/src/H5VL.c
+++ b/src/H5VL.c
@@ -1920,8 +1920,7 @@ H5VL_attr_create(hid_t uid, const char *name, hid_t acpl_id, hid_t aapl_id)
id_type = H5I_get_type(uid);
/* Check id */
if(H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type &&
- H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type &&
- H5I_ATTR_PUBLIC != id_type)
+ H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID")
/* get the ID struct */
diff --git a/src/H5err.txt b/src/H5err.txt
index 71d27a6..b4cb28b 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -220,6 +220,7 @@ MINOR, DSPACE, H5E_CANTCOMPARE, Can't compare objects
MINOR, PLIST, H5E_CANTGET, Can't get value
MINOR, PLIST, H5E_CANTSET, Can't set value
MINOR, PLIST, H5E_DUPCLASS, Duplicate class name in parent class
+MINOR, PLIST, H5E_SETDISALLOWED, Disallowed operation
# Link errors
MINOR, LINK, H5E_TRAVERSE, Link traversal failure
diff --git a/src/H5private.h b/src/H5private.h
index 77ceaca..0bb8e3e 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -151,7 +151,9 @@
#ifdef H5_HAVE_WIN32_API
+/* The following two defines must be before any windows headers are included */
#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
+#define NOGDI /* Exclude Graphic Display Interface macros */
#ifdef H5_HAVE_WINSOCK_H
#include <winsock2.h>
diff --git a/src/H5public.h b/src/H5public.h
index 1f44ff3..e36c0eb 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -75,10 +75,10 @@ extern "C" {
/* Version numbers */
#define H5_VERS_MAJOR 1 /* For major interface/format changes */
#define H5_VERS_MINOR 9 /* For minor interface/format changes */
-#define H5_VERS_RELEASE 112 /* For tweaks, bug-fixes, or development */
+#define H5_VERS_RELEASE 114 /* For tweaks, bug-fixes, or development */
#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
/* Empty string for real releases. */
-#define H5_VERS_INFO "HDF5 library version: 1.9.112" /* Full version string */
+#define H5_VERS_INFO "HDF5 library version: 1.9.114" /* Full version string */
#define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \
H5_VERS_RELEASE)
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 5f886d1..e9b87625 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -33,9 +33,7 @@ typedef __int64 h5_stat_size_t;
#define HDdup(F) _dup(F)
#define HDfdopen(N,S) _fdopen(N,S)
#define HDfileno(F) _fileno(F)
-#define HDfseek(F,O,W) _fseeki64(F,O,W)
#define HDfstat(F,B) _fstati64(F,B)
-#define HDftruncate(F,L) _chsize_s(F,L)
#define HDisatty(F) _isatty(F)
#define HDgetcwd(S,Z) _getcwd(S,Z)
#define HDgetdcwd(D,S,Z) _getdcwd(D,S,Z)
@@ -91,4 +89,8 @@ struct timezone {
* type cannot be cast as a ulong like other systems. */
#define HDpthread_self_ulong() ((unsigned long)GetCurrentThreadId())
+#ifndef H5_HAVE_MINGW
+#define HDftruncate(F,L) _chsize_s(F,L)
+#define HDfseek(F,O,W) _fseeki64(F,O,W)
+#endif
#endif /* H5_HAVE_WIN32_API */
diff --git a/src/Makefile.am b/src/Makefile.am
index fad0241..fad0241 100755..100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
diff --git a/src/Makefile.in b/src/Makefile.in
index c9c1089..6efe7c4 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -485,7 +485,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 102
+LT_VERS_REVISION = 104
LT_VERS_AGE = 0
H5detect_CFLAGS = -g $(AM_CFLAGS)
diff --git a/src/hdf5.lnt b/src/hdf5.lnt
index 1d02039..1d02039 100755..100644
--- a/src/hdf5.lnt
+++ b/src/hdf5.lnt
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a2577b9..a6ff10b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -87,6 +87,7 @@ SET (HDF5_REFERENCE_TEST_FILES
family_v16_00003.h5
filespace_1_6.h5
filespace_1_8.h5
+ file_image_core_test.h5
fill_old.h5
filter_error.h5
group_old.h5
@@ -307,6 +308,7 @@ SET (H5_TESTS
tcheck_version
testmeta
#links_env
+ file_image
)
FOREACH (test ${H5_TESTS})
@@ -630,6 +632,7 @@ IF (HDF5_BUILD_GENERATORS AND NOT BUILD_SHARED_LIBS)
gen_filespace
gen_specmetaread
gen_sizes_lheap
+ gen_file_image
)
FOREACH (gen ${H5_GENERATORS})
diff --git a/test/Makefile.am b/test/Makefile.am
index afc1b37..50ca89c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -42,7 +42,7 @@ TEST_PROG= testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
big mtime fillval mount flush1 flush2 app_ref enum \
set_extent ttsafe \
getname vfd ntypes dangle dtransform reserved cross_read \
- freespace mf farray earray btree2 fheap
+ freespace mf farray earray btree2 fheap file_image
# List programs to be built when testing here. error_test and err_compat are
# built at the same time as the other tests, but executed by testerror.sh.
@@ -63,7 +63,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version testmeta links_
BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \
gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \
gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \
- gen_sizes_lheap
+ gen_sizes_lheap gen_file_image
if BUILD_ALL_CONDITIONAL
noinst_PROGRAMS=$(BUILD_ALL_PROGS)
diff --git a/test/Makefile.in b/test/Makefile.in
index 6e716bc..626a029 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -92,7 +92,8 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
ttsafe$(EXEEXT) getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) \
dangle$(EXEEXT) dtransform$(EXEEXT) reserved$(EXEEXT) \
cross_read$(EXEEXT) freespace$(EXEEXT) mf$(EXEEXT) \
- farray$(EXEEXT) earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT)
+ farray$(EXEEXT) earray$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT) \
+ file_image$(EXEEXT)
am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \
gen_cross$(EXEEXT) gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \
gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \
@@ -100,7 +101,8 @@ am__EXEEXT_2 = gen_bad_ohdr$(EXEEXT) gen_bogus$(EXEEXT) \
gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \
gen_nullspace$(EXEEXT) gen_udlinks$(EXEEXT) \
space_overflow$(EXEEXT) gen_filespace$(EXEEXT) \
- gen_specmetaread$(EXEEXT) gen_sizes_lheap$(EXEEXT)
+ gen_specmetaread$(EXEEXT) gen_sizes_lheap$(EXEEXT) \
+ gen_file_image$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
accum_SOURCES = accum.c
accum_OBJECTS = accum.$(OBJEXT)
@@ -198,6 +200,10 @@ fheap_SOURCES = fheap.c
fheap_OBJECTS = fheap.$(OBJEXT)
fheap_LDADD = $(LDADD)
fheap_DEPENDENCIES = libh5test.la $(LIBHDF5)
+file_image_SOURCES = file_image.c
+file_image_OBJECTS = file_image.$(OBJEXT)
+file_image_LDADD = $(LDADD)
+file_image_DEPENDENCIES = libh5test.la $(LIBHDF5)
fillval_SOURCES = fillval.c
fillval_OBJECTS = fillval.$(OBJEXT)
fillval_LDADD = $(LDADD)
@@ -234,6 +240,10 @@ gen_deflate_SOURCES = gen_deflate.c
gen_deflate_OBJECTS = gen_deflate.$(OBJEXT)
gen_deflate_LDADD = $(LDADD)
gen_deflate_DEPENDENCIES = libh5test.la $(LIBHDF5)
+gen_file_image_SOURCES = gen_file_image.c
+gen_file_image_OBJECTS = gen_file_image.$(OBJEXT)
+gen_file_image_LDADD = $(LDADD)
+gen_file_image_DEPENDENCIES = libh5test.la $(LIBHDF5)
gen_filespace_SOURCES = gen_filespace.c
gen_filespace_OBJECTS = gen_filespace.$(OBJEXT)
gen_filespace_LDADD = $(LDADD)
@@ -418,10 +428,11 @@ SOURCES = $(libh5test_la_SOURCES) accum.c app_ref.c big.c bittests.c \
btree2.c cache.c cache_api.c cache_tagging.c cmpd_dset.c \
cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c \
earray.c efc.c enum.c err_compat.c error_test.c extend.c \
- external.c farray.c fheap.c fillval.c filter_fail.c flush1.c \
- flush2.c freespace.c gen_bad_ohdr.c gen_bogus.c gen_cross.c \
- gen_deflate.c gen_filespace.c gen_filters.c gen_new_array.c \
- gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c \
+ external.c farray.c fheap.c file_image.c fillval.c \
+ filter_fail.c flush1.c flush2.c freespace.c gen_bad_ohdr.c \
+ gen_bogus.c gen_cross.c gen_deflate.c gen_file_image.c \
+ gen_filespace.c gen_filters.c gen_new_array.c gen_new_fill.c \
+ gen_new_group.c gen_new_mtime.c gen_new_super.c \
gen_noencoder.c gen_nullspace.c gen_sizes_lheap.c \
gen_specmetaread.c gen_udlinks.c getname.c gheap.c hyperslab.c \
istore.c lheap.c links.c links_env.c mf.c mount.c mtime.c \
@@ -432,17 +443,17 @@ DIST_SOURCES = $(libh5test_la_SOURCES) accum.c app_ref.c big.c \
bittests.c btree2.c cache.c cache_api.c cache_tagging.c \
cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c \
dtransform.c dtypes.c earray.c efc.c enum.c err_compat.c \
- error_test.c extend.c external.c farray.c fheap.c fillval.c \
- filter_fail.c flush1.c flush2.c freespace.c gen_bad_ohdr.c \
- gen_bogus.c gen_cross.c gen_deflate.c gen_filespace.c \
- gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c \
- gen_new_mtime.c gen_new_super.c gen_noencoder.c \
- gen_nullspace.c gen_sizes_lheap.c gen_specmetaread.c \
- gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c \
- links.c links_env.c mf.c mount.c mtime.c ntypes.c objcopy.c \
- ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c \
- tcheck_version.c $(testhdf5_SOURCES) testmeta.c \
- $(ttsafe_SOURCES) unlink.c vfd.c
+ error_test.c extend.c external.c farray.c fheap.c file_image.c \
+ fillval.c filter_fail.c flush1.c flush2.c freespace.c \
+ gen_bad_ohdr.c gen_bogus.c gen_cross.c gen_deflate.c \
+ gen_file_image.c gen_filespace.c gen_filters.c gen_new_array.c \
+ gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c \
+ gen_noencoder.c gen_nullspace.c gen_sizes_lheap.c \
+ gen_specmetaread.c gen_udlinks.c getname.c gheap.c hyperslab.c \
+ istore.c lheap.c links.c links_env.c mf.c mount.c mtime.c \
+ ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
+ space_overflow.c stab.c tcheck_version.c $(testhdf5_SOURCES) \
+ testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
ETAGS = etags
CTAGS = ctags
am__tty_colors = \
@@ -778,7 +789,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
big mtime fillval mount flush1 flush2 app_ref enum \
set_extent ttsafe \
getname vfd ntypes dangle dtransform reserved cross_read \
- freespace mf farray earray btree2 fheap
+ freespace mf farray earray btree2 fheap file_image
# These programs generate test files for the tests. They don't need to be
@@ -791,7 +802,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \
BUILD_ALL_PROGS = gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \
gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \
gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \
- gen_sizes_lheap
+ gen_sizes_lheap gen_file_image
# The libh5test library provides common support code for the tests.
@@ -978,6 +989,9 @@ farray$(EXEEXT): $(farray_OBJECTS) $(farray_DEPENDENCIES)
fheap$(EXEEXT): $(fheap_OBJECTS) $(fheap_DEPENDENCIES)
@rm -f fheap$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fheap_OBJECTS) $(fheap_LDADD) $(LIBS)
+file_image$(EXEEXT): $(file_image_OBJECTS) $(file_image_DEPENDENCIES)
+ @rm -f file_image$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(file_image_OBJECTS) $(file_image_LDADD) $(LIBS)
fillval$(EXEEXT): $(fillval_OBJECTS) $(fillval_DEPENDENCIES)
@rm -f fillval$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fillval_OBJECTS) $(fillval_LDADD) $(LIBS)
@@ -1005,6 +1019,9 @@ gen_cross$(EXEEXT): $(gen_cross_OBJECTS) $(gen_cross_DEPENDENCIES)
gen_deflate$(EXEEXT): $(gen_deflate_OBJECTS) $(gen_deflate_DEPENDENCIES)
@rm -f gen_deflate$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gen_deflate_OBJECTS) $(gen_deflate_LDADD) $(LIBS)
+gen_file_image$(EXEEXT): $(gen_file_image_OBJECTS) $(gen_file_image_DEPENDENCIES)
+ @rm -f gen_file_image$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gen_file_image_OBJECTS) $(gen_file_image_LDADD) $(LIBS)
gen_filespace$(EXEEXT): $(gen_filespace_OBJECTS) $(gen_filespace_DEPENDENCIES)
@rm -f gen_filespace$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gen_filespace_OBJECTS) $(gen_filespace_LDADD) $(LIBS)
@@ -1145,6 +1162,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/farray.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fheap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter_fail.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@
@@ -1154,6 +1172,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_bogus.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_cross.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_deflate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_file_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_filespace.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_filters.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_array.Po@am__quote@
diff --git a/test/fheap.c b/test/fheap.c
index b55c60b..25827f4 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -508,6 +508,7 @@ get_fill_size(const fheap_test_param_t *tparam)
case FHEAP_TEST_FILL_SINGLE:
return((size_t)0);
+ case FHEAP_TEST_FILL_N:
default:
HDassert(0 && "Unknown bulk fill type?!?");
} /* end switch */
@@ -6453,7 +6454,7 @@ test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
/* seed = (unsigned long)1155438845; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
- HDsrandom(seed);
+ HDsrandom((unsigned)seed);
/* Set heap ID to random (non-null) value */
heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN;
@@ -7594,6 +7595,117 @@ error:
} H5E_END_TRY;
return(1);
} /* test_man_remove_three_larger() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_man_incr_insert_remove
+ *
+ * Purpose: Test incremental insert & removal of objects in heap
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, April 1, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+test_man_incr_insert_remove(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ H5HF_t *fh = NULL; /* Fractal heap wrapper */
+ haddr_t fh_addr; /* Address of fractal heap */
+ unsigned char heap_id[100][MAX_HEAP_ID_LEN]; /* Heap ID for object inserted */
+ struct a_type_t1 {
+ char a[10];
+ char b[29];
+ } obj1, obj2; /* Objects to insert/remove */
+ size_t id_len; /* Size of fractal heap IDs */
+ fheap_heap_state_t state; /* State of fractal heap */
+ int i, j;
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = (H5F_t *)H5I_object_verify(file, H5I_FILE)))
+ STACK_ERROR
+
+ /* Ignore metadata tags in the file's cache */
+ if(H5AC_ignore_tags(f) < 0)
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(NULL == (fh = H5HF_create(f, dxpl, cparam)))
+ FAIL_STACK_ERROR
+ if(H5HF_get_id_len(fh, &id_len) < 0)
+ FAIL_STACK_ERROR
+ if(id_len > HEAP_ID_LEN)
+ FAIL_STACK_ERROR
+ if(H5HF_get_heap_addr(fh, &fh_addr) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+ HDmemset(&state, 0, sizeof(fheap_heap_state_t));
+ if(check_stats(fh, &state))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test incremental insert and removal
+ */
+ TESTING("incremental object insertion and removal")
+
+ for(i = 0; i < 100; i++) {
+ sprintf(obj1.b, "%s%d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i);
+
+ for(j = 0; j < i; j++) {
+ sprintf(obj2.b, "%s%d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", j);
+
+ if(H5HF_remove(fh, dxpl, heap_id[j]) < 0)
+ FAIL_STACK_ERROR
+ if(H5HF_insert(fh, dxpl, (sizeof(obj2)), &obj2, heap_id[j]) < 0)
+ FAIL_STACK_ERROR
+ } /* end for */
+
+ /* Check for closing & re-opening the heap */
+ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0)
+ TEST_ERROR
+
+ /* Insert object */
+ HDmemset(heap_id[i], 0, id_len);
+ if(H5HF_insert(fh, dxpl, (sizeof(obj1)), &obj1, heap_id[i]) < 0)
+ FAIL_STACK_ERROR
+ } /* end for */
+
+ /* Close the fractal heap */
+ if(H5HF_close(fh, dxpl) < 0)
+ TEST_ERROR
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ PASSED()
+
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ if(fh)
+ H5HF_close(fh, dxpl);
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_man_incr_insert_remove() */
#endif /* QAK */
#ifndef QAK
@@ -15420,7 +15532,7 @@ test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_pa
/* seed = (unsigned long)1156158635; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
- HDsrandom(seed);
+ HDsrandom((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
@@ -15624,7 +15736,7 @@ test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_te
/* seed = (unsigned long)1155181717; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
- HDsrandom(seed);
+ HDsrandom((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
@@ -15838,7 +15950,7 @@ test_write(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
filter_class.set_local = NULL;
filter_class.filter = test_write_filter;
if(H5Zregister(&filter_class) < 0) TEST_ERROR
- if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_RESERVED + 43, 0, 0, NULL) < 0)
+ if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_RESERVED + 43, 0, (size_t)0, NULL) < 0)
FAIL_STACK_ERROR
test_write_filter_called = FALSE;
} /* end if */
@@ -16292,6 +16404,7 @@ curr_test = FHEAP_TEST_NORMAL;
break;
/* An unknown test? */
+ case FHEAP_TEST_NTESTS:
default:
goto error;
} /* end switch */
@@ -16340,6 +16453,7 @@ fill = FHEAP_TEST_FILL_LARGE;
break;
/* An unknown test? */
+ case FHEAP_TEST_FILL_N:
default:
goto error;
} /* end switch */
@@ -16348,8 +16462,12 @@ fill = FHEAP_TEST_FILL_LARGE;
* Test fractal heap managed object insertion
*/
+#ifndef QAK
/* "Weird" sized objects */
nerrors += test_man_insert_weird(fapl, &small_cparam, &tparam);
+#else /* QAK */
+HDfprintf(stderr, "Uncomment tests!\n");
+#endif /* QAK */
#ifdef ALL_INSERT_TESTS
/* "Standard" sized objects, building from simple to complex heaps */
@@ -16411,6 +16529,10 @@ HDfprintf(stderr, "Uncomment tests!\n");
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_REVERSE;
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
+
+ /* Incremental insert & removal */
+ tparam.del_dir = FHEAP_DEL_FORWARD;
+ nerrors += test_man_incr_insert_remove(fapl, &small_cparam, &tparam);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
@@ -16452,6 +16574,8 @@ tparam.drain_half = FHEAP_DEL_DRAIN_ALL;
nerrors += test_man_remove_2nd_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_3rd_indirect(fapl, &small_cparam, &tparam);
} /* end else */
+#else /* QAK */
+HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
#ifndef QAK
diff --git a/test/file_image.c b/test/file_image.c
new file mode 100644
index 0000000..a846a3c
--- /dev/null
+++ b/test/file_image.c
@@ -0,0 +1,1335 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/***********************************************************
+*
+* Test program: file_image
+*
+* Test setting file images
+*
+*************************************************************/
+
+#include "h5test.h"
+#include "H5srcdir.h"
+#include "H5Fprivate.h" /* required to test property removals */
+#define VERIFY(condition, string) do { if (!(condition)) FAIL_PUTS_ERROR(string) } while(0)
+
+/* Values for callback bit field */
+#define MALLOC 0x01
+#define MEMCPY 0x02
+#define REALLOC 0x04
+#define FREE 0x08
+#define UDATA_COPY 0x10
+#define UDATA_FREE 0x20
+
+#define RANK 2
+#define DIM0 1024
+#define DIM1 32
+#define DSET_NAME "test_dset"
+
+#define FAMILY_SIZE (2 * 1024)
+
+const char *FILENAME[] = {
+ "file_image_core_test",
+ NULL
+};
+
+/* need a second file name array, as the first file name array contains
+ * files we don't want to delete on cleanup.
+ */
+const char *FILENAME2[] = {
+ "sec2_get_file_image_test",
+ "stdio_get_file_image_test",
+ "core_get_file_image_test",
+ "family_get_file_image_test",
+ "multi_get_file_image_test",
+ "split_get_file_image_test",
+ "get_file_image_error_rejection_test",
+ NULL
+};
+
+typedef struct {
+ unsigned char used_callbacks; /* Bitfield for tracking callbacks */
+ H5FD_file_image_op_t malloc_src; /* Source of file image callbacks */
+ H5FD_file_image_op_t memcpy_src;
+ H5FD_file_image_op_t realloc_src;
+ H5FD_file_image_op_t free_src;
+} udata_t;
+
+
+/******************************************************************************
+ * Function: test_properties
+ *
+ * Purpose: Tests that the file image properties (buffer pointer and length)
+ * are set properly. Image callbacks are not set in this test.
+ *
+ * Returns: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static int
+test_properties(void)
+{
+ hid_t fapl_1;
+ hid_t fapl_2;
+ char *buffer;
+ int count = 10;
+ void *temp;
+ char *temp2;
+ int i;
+ size_t size;
+ size_t temp_size;
+
+ TESTING("File image property list functions");
+
+ /* Initialize file image buffer
+ *
+ * Note: this image will not contain a valid HDF5 file, as it complicates testing
+ * property list functions. In the file driver tests further down, this will
+ * not be the case.
+ */
+ size = (size_t)count * sizeof(char);
+ buffer = (char *)HDmalloc(size);
+ for(i = 0; i < count - 1; i++)
+ buffer[i] = (char)(65 + i);
+ buffer[count - 1] = '\0';
+
+ /* Create fapl */
+ if((fapl_1 = H5Pcreate(H5P_FILE_ACCESS)) < 0) FAIL_STACK_ERROR
+
+ /* Get file image stuff */
+ if(H5Pget_file_image(fapl_1, (void **)&temp, &temp_size) < 0) FAIL_STACK_ERROR
+
+ /* Check default values */
+ VERIFY(temp == NULL, "Default pointer is wrong");
+ VERIFY(temp_size == 0, "Default size is wrong");
+
+ /* Set file image stuff */
+ if(H5Pset_file_image(fapl_1, (void *)buffer, size) < 0) FAIL_STACK_ERROR
+
+ /* Get the same */
+ if(H5Pget_file_image(fapl_1, (void **)&temp, &temp_size) < 0) FAIL_STACK_ERROR
+
+ /* Check that sizes are the same, and that the buffers are identical but separate */
+ VERIFY(temp != NULL, "temp is null!");
+ VERIFY(temp_size == size, "Sizes of buffers don't match");
+ VERIFY(temp != buffer, "Retrieved buffer is the same as original");
+ VERIFY(0 == HDmemcmp(temp, buffer, size), "Buffers contain different data");
+
+ /* Copy the fapl */
+ if((fapl_2 = H5Pcopy(fapl_1)) < 0) FAIL_STACK_ERROR
+
+ /* Get values from the new fapl */
+ if(H5Pget_file_image(fapl_2, (void **)&temp2, &temp_size) < 0) FAIL_STACK_ERROR
+
+ /* Check that sizes are the same, and that the buffers are identical but separate */
+ VERIFY(temp_size == size,"Sizes of buffers don't match");
+ VERIFY(temp2 != NULL,"Recieved buffer not set");
+ VERIFY(temp2 != buffer, "Retrieved buffer is the same as original");
+ VERIFY(temp2 != temp, "Retrieved buffer is the same as previously retrieved buffer");
+ VERIFY(0 == HDmemcmp(temp2, buffer, size),"Buffers contain different data");
+
+ /* Close everything */
+ if(H5Pclose(fapl_1) < 0) FAIL_STACK_ERROR
+ if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR
+ HDfree(buffer);
+ HDfree(temp);
+ HDfree(temp2);
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+} /* end test_properties() */
+
+/******************************************************************************
+ * Function: malloc_cb
+ *
+ * Purpose: This function allows calls to the malloc callback to be tracked.
+ *
+ * Returns: The result of a standard malloc
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static void *
+malloc_cb(size_t size, H5FD_file_image_op_t op, void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= MALLOC;
+ u->malloc_src = op;
+ return HDmalloc(size);
+}
+
+/******************************************************************************
+ * Function: memcpy_cb
+ *
+ * Purpose: This function allows calls to the memcpy callback to be tracked.
+ *
+ * Returns: The result of a standard memcpy
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static void *
+memcpy_cb(void *dest, const void *src, size_t size, H5FD_file_image_op_t op, void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= MEMCPY;
+ u->memcpy_src = op;
+ return HDmemcpy(dest, src, size);
+}
+
+/******************************************************************************
+ * Function: realloc_cb
+ *
+ * Purpose: This function allows calls to the realloc callback to be tracked.
+ *
+ * Returns: The result of a standard realloc
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static void *
+realloc_cb(void *ptr, size_t size, H5FD_file_image_op_t op, void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= REALLOC;
+ u->realloc_src = op;
+ return HDrealloc(ptr,size);
+}
+
+/******************************************************************************
+ * Function: free_cb
+ *
+ * Purpose: This function allows calls to the free callback to be tracked.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static herr_t
+free_cb(void *ptr, H5FD_file_image_op_t op, void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= FREE;
+ u->free_src = op;
+ HDfree(ptr);
+ return(SUCCEED);
+}
+
+/******************************************************************************
+ * Function: udata_copy_cb
+ *
+ * Purpose: This function allows calls to the udata_copy callback to be tracked.
+ * No copying actualy takes place; it is easier to deal with only one
+ * instance of the udata.
+ *
+ * Returns: A pointer to the same udata that was passed in.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static void *
+udata_copy_cb(void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= UDATA_COPY;
+ return udata;
+}
+
+/******************************************************************************
+ * Function: udata_free_cb
+ *
+ * Purpose: This function allows calls to the udata_free callback to be tracked.
+ *
+ * Note: this callback doesn't actually do anything. Since the
+ * udata_copy callback doesn't copy, only one instance of the udata
+ * is kept alive and such it must be freed explicitly at the end of the tests.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static herr_t
+udata_free_cb(void *udata)
+{
+ udata_t *u = (udata_t *)udata;
+
+ u->used_callbacks |= UDATA_FREE;
+ return(SUCCEED);
+}
+
+/******************************************************************************
+ * Function: reset_udata
+ *
+ * Purpose: Resets the udata to default values. This facilitates storing only
+ * the results of a single operation in the udata.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static void
+reset_udata(udata_t *u)
+{
+ u->used_callbacks = 0;
+ u->malloc_src = u->memcpy_src = u->realloc_src = u->free_src = H5FD_FILE_IMAGE_OP_NO_OP;
+}
+
+/******************************************************************************
+ * Function: test_callbacks
+ *
+ * Purpose: Tests that callbacks are called properly in property list functions.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static int
+test_callbacks(void)
+{
+ H5FD_file_image_callbacks_t real_callbacks = {&malloc_cb, &memcpy_cb, &realloc_cb,
+ &free_cb, &udata_copy_cb, &udata_free_cb, NULL};
+ H5FD_file_image_callbacks_t null_callbacks = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+ H5FD_file_image_callbacks_t callbacks;
+ hid_t fapl_1;
+ hid_t fapl_2;
+ udata_t *udata;
+ char *file_image;
+ char *temp_file_image;
+ int count = 10;
+ int i;
+ size_t size;
+ size_t temp_size;
+
+ TESTING("Callback use in property list operations");
+
+ /* Allocate and initialize udata */
+ udata = (udata_t *)HDmalloc(sizeof(udata_t));
+ reset_udata(udata);
+
+ /* copy the address of the user data into read_callbacks */
+ real_callbacks.udata = (void *)udata;
+
+ /* Allocate and initialize file image buffer */
+ size = (size_t)count * sizeof(char);
+ file_image = (char *)HDmalloc(size);
+ for(i = 0; i < count - 1; i++)
+ file_image[i] = (char)(65 + i);
+ file_image[count - 1] = '\0';
+
+ /* Create fapl */
+ if((fapl_1 = H5Pcreate(H5P_FILE_ACCESS)) < 0) FAIL_STACK_ERROR
+
+ /* Get file image stuff */
+ callbacks = real_callbacks;
+ if(H5Pget_file_image_callbacks(fapl_1, &callbacks) < 0) FAIL_STACK_ERROR
+
+ /* Check default values */
+ VERIFY(callbacks.image_malloc == NULL, "Default malloc callback is wrong");
+ VERIFY(callbacks.image_memcpy == NULL, "Default memcpy callback is wrong");
+ VERIFY(callbacks.image_realloc == NULL, "Default realloc callback is wrong");
+ VERIFY(callbacks.image_free == NULL, "Default free callback is wrong");
+ VERIFY(callbacks.udata_copy == NULL, "Default udata copy callback is wrong");
+ VERIFY(callbacks.udata_free == NULL, "Default udata free callback is wrong");
+ VERIFY(callbacks.udata == NULL, "Default udata is wrong");
+
+
+ /* Set file image callbacks */
+ callbacks = real_callbacks;
+ if(H5Pset_file_image_callbacks(fapl_1, &callbacks) < 0) FAIL_STACK_ERROR
+
+ /* Get file image callbacks */
+ callbacks = null_callbacks;
+ if(H5Pget_file_image_callbacks(fapl_1, &callbacks) < 0) FAIL_STACK_ERROR
+
+ /* Verify values */
+ VERIFY(callbacks.image_malloc == &malloc_cb, "malloc callback was not set or retrieved properly");
+ VERIFY(callbacks.image_memcpy == &memcpy_cb, "memcpy callback was not set or retrieved properly");
+ VERIFY(callbacks.image_realloc == &realloc_cb, "realloc callback was not set or retrieved properly");
+ VERIFY(callbacks.image_free == &free_cb, "free callback was not set or retrieved properly");
+ VERIFY(callbacks.udata_copy == &udata_copy_cb, "udata copy callback was not set or retrieved properly");
+ VERIFY(callbacks.udata_free == &udata_free_cb, "udata free callback was not set or retrieved properly");
+ VERIFY(callbacks.udata == udata, "udata was not set or retrieved properly");
+
+
+ /*
+ * Check callbacks in internal function without a previously set file image
+ */
+
+ /* Copy fapl */
+ reset_udata(udata);
+ if((fapl_2 = H5Pcopy(fapl_1)) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the property's copy callback used the correct image callbacks */
+ VERIFY(udata->used_callbacks == (UDATA_COPY), "Copying a fapl with no image used incorrect callbacks");
+
+ /* Close fapl */
+ reset_udata(udata);
+ if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the udata free callback was used */
+ VERIFY(udata->used_callbacks == (UDATA_FREE), "Closing a fapl with no image used incorrect callbacks");
+
+ /* Copy again */
+ if((fapl_2 = H5Pcopy(fapl_1)) < 0) FAIL_STACK_ERROR
+
+ /* Remove property from fapl */
+ reset_udata(udata);
+ if(H5Premove(fapl_2, H5F_ACS_FILE_IMAGE_INFO_NAME) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the property's delete callback was called using the correct image callbacks */
+ VERIFY(udata->used_callbacks == (UDATA_FREE), "Removing a property from a fapl with no image used incorrect callbacks");
+
+ /* Close it again */
+ if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR
+
+ /* Get file image */
+ reset_udata(udata);
+ if(H5Pget_file_image(fapl_1, (void **)&temp_file_image, &temp_size) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the correct callbacks were used */
+ VERIFY(udata->used_callbacks == 0, "attempting to retrieve the image from a fapl without an image has an unexpected callback");
+
+ /* Set file image */
+ reset_udata(udata);
+ if(H5Pset_file_image(fapl_1, (void *)file_image, size) < 0) FAIL_STACK_ERROR
+
+ VERIFY(udata->used_callbacks == (MALLOC | MEMCPY), "Setting a file image (first time) used incorrect callbacks");
+
+ /*
+ * Check callbacks in internal functions with a previously set file image
+ */
+
+ /* Copy fapl */
+ reset_udata(udata);
+ if((fapl_2 = H5Pcopy(fapl_1)) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the property's copy callback used the correct image callbacks */
+ VERIFY(udata->used_callbacks == (MALLOC | MEMCPY | UDATA_COPY), "Copying a fapl with an image used incorrect callbacks");
+ VERIFY(udata->malloc_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY, "malloc callback has wrong source");
+ VERIFY(udata->memcpy_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY, "memcpy callback has wrong source");
+
+ /* Close fapl */
+ reset_udata(udata);
+ if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the udata free callback was used */
+ VERIFY(udata->used_callbacks == (FREE | UDATA_FREE), "Closing a fapl with an image used incorrect callbacks");
+ VERIFY(udata->free_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, "free callback has wrong source");
+
+ /* Copy again */
+ if((fapl_2 = H5Pcopy(fapl_1)) < 0) FAIL_STACK_ERROR
+
+ /* Remove property from fapl */
+ reset_udata(udata);
+ if(H5Premove(fapl_2, H5F_ACS_FILE_IMAGE_INFO_NAME) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the property's delete callback was called using the correct image callbacks */
+ VERIFY(udata->used_callbacks == (FREE | UDATA_FREE), "Removing a property from a fapl with an image used incorrect callbacks");
+ VERIFY(udata->free_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, "free callback has wrong source");
+
+ /* Close it again */
+ if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR
+
+ /* Get file image */
+ reset_udata(udata);
+ if(H5Pget_file_image(fapl_1, (void **)&temp_file_image, &temp_size) < 0) FAIL_STACK_ERROR
+
+ /* Verify that the correct callbacks were used */
+ VERIFY(udata->used_callbacks == (MALLOC | MEMCPY), "attempting to retrieve the image from a fapl with an image has an unexpected callback");
+ VERIFY(udata->malloc_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET, "malloc callback has wrong source");
+ VERIFY(udata->memcpy_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET, "memcpy callback has wrong source");
+
+ /* Set file image */
+ reset_udata(udata);
+ if(H5Pset_file_image(fapl_1, (void *)file_image, size) < 0) FAIL_STACK_ERROR
+
+ VERIFY(udata->used_callbacks == (FREE | MALLOC | MEMCPY), "Setting a file image (second time) used incorrect callbacks");
+ VERIFY(udata->malloc_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, "malloc callback has wrong source");
+ VERIFY(udata->memcpy_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, "memcpy callback has wrong source");
+ VERIFY(udata->free_src == H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET, "freec callback has wrong source");
+
+ /* Close stuff */
+ if(H5Pclose(fapl_1) < 0) FAIL_STACK_ERROR
+ HDfree(file_image);
+ HDfree(temp_file_image);
+ HDfree(udata);
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+} /* test_callbacks() */
+
+/******************************************************************************
+ * Function: test_core
+ *
+ * Purpose: Tests that callbacks are called properly in the core VFD and
+ * that the initial file image works properly.
+ *
+ * Programmer: Jacob Gruber
+ * Monday, August 22, 2011
+ *
+ ******************************************************************************
+ */
+static int
+test_core(void)
+{
+ hid_t fapl;
+ hid_t file;
+ hid_t dset;
+ hid_t space;
+ udata_t *udata;
+ unsigned char *file_image;
+ char filename[1024];
+ char src_dir_filename[1024];
+ const char *tmp = NULL;
+ size_t size;
+ hsize_t dims[2];
+ int fd;
+ h5_stat_t sb;
+ herr_t ret;
+ H5FD_file_image_callbacks_t callbacks = {&malloc_cb, &memcpy_cb, &realloc_cb,
+ &free_cb, &udata_copy_cb, &udata_free_cb, NULL};
+
+ TESTING("Initial file image and callbacks in Core VFD");
+
+ /* Create fapl */
+ fapl = h5_fileaccess();
+ VERIFY(fapl >= 0, "fapl creation failed");
+
+ /* Set up the core VFD */
+ ret = H5Pset_fapl_core(fapl, 0, 0);
+ VERIFY(ret >= 0, "setting core driver in fapl failed");
+
+ tmp = h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+ VERIFY(tmp != NULL, "h5_fixname failed");
+
+ /* convert file name to srcdir file name. Make a copy as
+ * H5_get_srcdir_filename() simply sets up the file name in its
+ * own buffer each time it is called -- overwriting the previous
+ * value.
+ */
+ tmp = H5_get_srcdir_filename(filename);
+ VERIFY(tmp != NULL, "H5_get_srcdir_filename failed");
+ VERIFY(strlen(tmp) < 1023, "srcdir file name too long.");
+ HDstrncpy(src_dir_filename, tmp, 1023);
+ src_dir_filename[1023] = '\0';
+
+ /* Allocate and initialize udata */
+ udata = (udata_t *)HDmalloc(sizeof(udata_t));
+ VERIFY(udata != NULL, "udata malloc failed");
+
+ /* copy the address of the udata into the callbacks structure */
+ callbacks.udata = (void *)udata;
+
+ /* Set file image callbacks */
+ ret = H5Pset_file_image_callbacks(fapl, &callbacks);
+ VERIFY(ret >= 0, "set image callbacks failed");
+
+ /* Test open (no file image) */
+ reset_udata(udata);
+ file = H5Fopen(src_dir_filename, H5F_ACC_RDWR, fapl);
+ VERIFY(file >= 0, "H5Fopen failed");
+ VERIFY(udata->used_callbacks == MALLOC, "opening a core file used the wrong callbacks");
+ VERIFY(udata->malloc_src == H5FD_FILE_IMAGE_OP_FILE_OPEN, "Malloc callback came from wrong sourc in core open");
+
+ /* Close file */
+ reset_udata(udata);
+ ret = H5Fclose(file);
+ VERIFY(ret >= 0, "H5Fclose failed");
+ VERIFY(udata->used_callbacks == FREE, "Closing a core file used the wrong callbacks");
+ VERIFY(udata->free_src == H5FD_FILE_IMAGE_OP_FILE_CLOSE, "Free callback came from wrong sourc in core close");
+
+ /* Reopen file */
+ file = H5Fopen(src_dir_filename, H5F_ACC_RDWR, fapl);
+ VERIFY(file >= 0, "H5Fopen failed");
+
+ /* Set up a new dset */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ space = H5Screate_simple(RANK, dims, dims);
+ VERIFY(space >= 0, "H5Screate failed");
+
+ /* Create new dset, invoking H5FD_core_write */
+ reset_udata(udata);
+ dset = H5Dcreate2(file, DSET_NAME, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset >=0, "H5Dcreate failed");
+
+ /* Flush the write and check the realloc callback */
+ ret = H5Fflush(file, H5F_SCOPE_LOCAL);
+ VERIFY(ret >= 0, "H5Fflush failed");
+ VERIFY(udata->used_callbacks == (REALLOC), "core write used the wrong callbacks");
+ VERIFY(udata->realloc_src == H5FD_FILE_IMAGE_OP_FILE_RESIZE, "Realloc callback came from wrong source in core write");
+
+ /* Close dset and space */
+ ret = H5Dclose(dset);
+ VERIFY(ret >= 0, "H5Dclose failed");
+ ret = H5Sclose(space);
+ VERIFY(ret >= 0, "H5Sclose failed");
+
+ /* Test file close */
+ reset_udata(udata);
+ ret = H5Fclose(file);
+ VERIFY(ret >= 0, "H5Fclose failed");
+ VERIFY(udata->used_callbacks == (FREE), "Closing a core file used the wrong callbacks");
+ VERIFY(udata->free_src == H5FD_FILE_IMAGE_OP_FILE_CLOSE, "Free callback came from wrong sourc in core close");
+
+ /* Create file image buffer */
+ fd = HDopen(src_dir_filename, O_RDONLY, 0666);
+ VERIFY(fd > 0, "open failed");
+ ret = HDfstat(fd, &sb);
+ VERIFY(ret == 0, "fstat failed");
+ size = (size_t)sb.st_size;
+ file_image = (unsigned char *)HDmalloc(size);
+ HDread(fd, file_image, size);
+ ret = HDclose(fd);
+ VERIFY(ret == 0, "close failed");
+
+ /* Set file image in plist */
+ if(H5Pset_file_image(fapl, file_image, size) < 0) FAIL_STACK_ERROR
+
+ /* Test open with file image */
+ if((file = H5Fopen("dne.h5", H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR
+ if(H5Fclose(file) < 0) FAIL_STACK_ERROR
+
+ /* Release resources */
+ h5_cleanup(FILENAME, fapl);
+ HDfree(udata);
+ HDfree(file_image);
+
+ PASSED();
+
+ return 0;
+
+error:
+ return 1;
+} /* end test_core() */
+
+/******************************************************************************
+ * Function: test_get_file_image
+ *
+ * Purpose: Test the H5Fget_file_image() call.
+ *
+ * Programmer: John Mainzer
+ * Tuesday, November 15, 2011
+ *
+ ******************************************************************************
+ */
+static int
+test_get_file_image(const char * test_banner,
+ const int file_name_num,
+ hid_t fapl)
+{
+ char file_name[1024] = "\0";
+ void * insertion_ptr = NULL;
+ void * image_ptr = NULL;
+ void * file_image_ptr = NULL;
+ hbool_t is_family_file = FALSE;
+ hbool_t identical;
+ int data[100];
+ int i;
+ int fd = -1;
+ int result;
+ hid_t driver = -1;
+ hid_t file_id = -1;
+ hid_t dset_id = -1;
+ hid_t space_id = -1;
+ hid_t core_fapl_id = -1;
+ hid_t core_file_id = -1;
+ herr_t err;
+ hsize_t dims[2];
+ ssize_t bytes_read;
+ ssize_t image_size;
+ ssize_t file_size;
+ h5_stat_t stat_buf;
+
+ TESTING(test_banner);
+
+ /* set flag if we are dealing with a family file */
+ driver = H5Pget_driver(fapl);
+ VERIFY(driver >= 0, "H5Pget_driver(fapl) failed");
+
+ if(driver == H5FD_FAMILY)
+ is_family_file = TRUE;
+
+ /* setup the file name */
+ h5_fixname(FILENAME2[file_name_num], fapl, file_name, sizeof(file_name));
+ VERIFY(HDstrlen(file_name)>0, "h5_fixname failed");
+
+ /* create the file */
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl);
+ VERIFY(file_id >= 0, "H5Fcreate() failed.");
+
+ /* Set up data space for new new data set */
+ dims[0] = 10;
+ dims[1] = 10;
+ space_id = H5Screate_simple(2, dims, dims);
+ VERIFY(space_id >= 0, "H5Screate() failed");
+
+ /* Create a dataset */
+ dset_id = H5Dcreate2(file_id, "dset 0", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset_id >=0, "H5Dcreate() failed");
+
+ /* write some data to the data set */
+ for (i = 0; i < 100; i++)
+ data[i] = i;
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)data);
+ VERIFY(err >= 0, "H5Dwrite() failed.");
+
+ /* Flush the file */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VERIFY(err >= 0, "H5Fflush failed");
+
+ /* get the size of the file */
+ image_size = H5Fget_file_image(file_id, NULL, (size_t)0);
+ VERIFY(image_size > 0, "H5Fget_file_image(1) failed.");
+
+ /* allocate a buffer of the appropriate size */
+ image_ptr = HDmalloc((size_t)image_size);
+ VERIFY(image_ptr != NULL, "HDmalloc(1) failed.");
+
+ /* load the image of the file into the buffer */
+ bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_size);
+ VERIFY(bytes_read == image_size, "H5Fget_file_image(2) failed.");
+
+ /* Close dset and space */
+ err = H5Dclose(dset_id);
+ VERIFY(err >= 0, "H5Dclose failed");
+ err = H5Sclose(space_id);
+ VERIFY(err >= 0, "H5Sclose failed");
+
+ /* close the test file */
+ err = H5Fclose(file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(file_id) failed.");
+
+ if(is_family_file) {
+ char member_file_name[1024];
+ ssize_t bytes_to_read;
+ ssize_t member_size;
+ ssize_t size_remaining;
+
+ i = 0;
+ file_size = 0;
+
+ do {
+ HDsnprintf(member_file_name, 1024, file_name, i);
+
+ /* get the size of the member file */
+ result = HDstat(member_file_name, &stat_buf);
+ VERIFY(result == 0, "HDstat() failed.");
+
+ member_size = (ssize_t)stat_buf.st_size;
+
+ i++;
+ file_size += member_size;
+ } while(member_size > 0);
+
+ /* Since we use the eoa to calculate the image size, the file size
+ * may be larger. This is OK, as long as (in this specialized instance)
+ * the remainder of the file is all '\0's.
+ */
+ VERIFY(file_size >= image_size, "file size != image size.");
+
+ /* allocate a buffer for the test file image */
+ file_image_ptr = HDmalloc((size_t)file_size);
+ VERIFY(file_image_ptr != NULL, "HDmalloc(2f) failed.");
+
+ size_remaining = image_size;
+ insertion_ptr = file_image_ptr;
+ i = 0;
+
+ while(size_remaining > 0) {
+ /* construct the member file name */
+ HDsnprintf(member_file_name, 1024, file_name, i);
+
+ /* open the test file using standard I/O calls */
+ fd = HDopen(member_file_name, O_RDONLY, 0666);
+ VERIFY(fd >= 0, "HDopen() failed.");
+
+ if(size_remaining >= FAMILY_SIZE ){
+ bytes_to_read = FAMILY_SIZE;
+ size_remaining -= FAMILY_SIZE;
+ } else {
+ bytes_to_read = size_remaining;
+ size_remaining = 0;
+ }
+
+ /* read the member file from disk into the buffer */
+ bytes_read = HDread(fd, insertion_ptr, (size_t)bytes_to_read);
+ VERIFY(bytes_read == bytes_to_read, "HDread() failed.");
+
+ insertion_ptr = (void *)(((char *)insertion_ptr) + bytes_to_read);
+
+ i++;
+
+ /* close the test file */
+ result = HDclose(fd);
+ VERIFY(result == 0, "HDclose() failed.");
+ }
+ } else {
+ /* get the size of the test file */
+ result = HDstat(file_name, &stat_buf);
+ VERIFY(result == 0, "HDstat() failed.");
+
+ /* Since we use the eoa to calculate the image size, the file size
+ * may be larger. This is OK, as long as (in this specialized instance)
+ * the remainder of the file is all '\0's.
+ */
+ file_size = (ssize_t)stat_buf.st_size;
+
+ /* with latest mods to truncate call in core file drive,
+ * file size should match image size
+ */
+ VERIFY(file_size == image_size, "file size != image size.");
+
+ /* allocate a buffer for the test file image */
+ file_image_ptr = HDmalloc((size_t)file_size);
+ VERIFY(file_image_ptr != NULL, "HDmalloc(2) failed.");
+
+ /* open the test file using standard I/O calls */
+ fd = HDopen(file_name, O_RDONLY, 0666);
+ VERIFY(fd >= 0, "HDopen() failed.");
+
+ /* read the test file from disk into the buffer */
+ bytes_read = HDread(fd, file_image_ptr, (size_t)file_size);
+ VERIFY(bytes_read == file_size, "HDread() failed.");
+
+ /* close the test file */
+ result = HDclose(fd);
+ VERIFY(result == 0, "HDclose() failed.");
+ }
+
+ /* verify that the file and the image contain the same data */
+ identical = TRUE;
+ i = 0;
+ while((i < (int)image_size) && identical) {
+ if(((char *)image_ptr)[i] != ((char *)file_image_ptr)[i])
+ identical = FALSE;
+ i++;
+ }
+ VERIFY(identical, "file and image differ.");
+
+
+ /* finally, verify that we can use the core file driver to open the image */
+
+ /* create fapl for core file driver */
+ core_fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VERIFY(core_fapl_id >=0, "H5Pcreate() failed");
+
+ /* setup core_fapl_id to use the core file driver */
+ err = H5Pset_fapl_core(core_fapl_id, (size_t)(64 * 1024), FALSE);
+ VERIFY(err == SUCCEED, "H5Pset_fapl_core() failed.");
+
+ /* Set file image in core fapl */
+ err = H5Pset_file_image(core_fapl_id, image_ptr, (size_t)image_size);
+ VERIFY(err == SUCCEED, "H5Pset_file_image() failed.");
+
+ /* open the file image with the core file driver */
+ core_file_id = H5Fopen("nonesuch", H5F_ACC_RDWR, core_fapl_id);
+ VERIFY(core_file_id >= 0, "H5Fopen() of file image failed.");
+
+ /* close the file image with the core file driver */
+ err = H5Fclose(core_file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(core_file_id) failed.");
+
+ /* dicard core fapl */
+ err = H5Pclose(core_fapl_id);
+ VERIFY(err == SUCCEED, "H5Pclose(core_fapl_id) failed.");
+
+ /* tidy up */
+ result = h5_cleanup(FILENAME2, fapl);
+ VERIFY(result != 0, "h5_cleanup() failed.");
+
+ /* discard the image buffer if it exists */
+ if(image_ptr != NULL)
+ HDfree(image_ptr);
+
+ /* discard the image buffer if it exists */
+ if(file_image_ptr != NULL)
+ HDfree(file_image_ptr);
+
+ PASSED();
+
+ return 0;
+
+error:
+ return 1;
+} /* end test_get_file_image() */
+
+/******************************************************************************
+ * Function: test_get_file_image_error_rejection
+ *
+ * Purpose: Verify that H5Fget_file_image() rejects invalid input.
+ *
+ * Programmer: John Mainzer
+ * Tuesday, November 22, 2011
+ *
+ ******************************************************************************
+ */
+
+#define TYPE_SLICE ((haddr_t)0x10000LL)
+
+static int
+test_get_file_image_error_rejection(void)
+{
+ const char *memb_name[H5FD_MEM_NTYPES];
+ char file_name[1024] = "\0";
+ void * image_ptr = NULL;
+ int data[100];
+ int i;
+ int result;
+ hid_t fapl_id = -1;
+ hid_t file_id = -1;
+ hid_t dset_id = -1;
+ hid_t space_id = -1;
+ herr_t err;
+ hsize_t dims[2];
+ ssize_t bytes_read;
+ ssize_t image_size;
+ hid_t memb_fapl[H5FD_MEM_NTYPES];
+ haddr_t memb_addr[H5FD_MEM_NTYPES];
+ H5FD_mem_t mt;
+ H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
+
+
+ TESTING("H5Fget_file_image() error rejection");
+
+ /************************ Sub-Test #1 ********************************/
+ /* set up a test file, and try to get its image with a buffer that is
+ * too small. Call to H5Fget_file_image() should fail.
+ *
+ * Since we have already done the necessary setup, verify that
+ * H5Fget_file_image() will fail with:
+ *
+ * bad file id, or
+ *
+ * good id, but not a file id
+ */
+
+
+ /* setup fapl -- driver type doesn't matter much, so make it stdio */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VERIFY(fapl_id >= 0, "H5Pcreate(1) failed");
+
+ err = H5Pset_fapl_stdio(fapl_id);
+ VERIFY(err >= 0, "H5Pset_fapl_stdio() failed");
+
+ /* setup the file name */
+ h5_fixname(FILENAME2[6], fapl_id, file_name, sizeof(file_name));
+ VERIFY(HDstrlen(file_name)>0, "h5_fixname failed");
+
+ /* create the file */
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
+ VERIFY(file_id >= 0, "H5Fcreate() failed.");
+
+ /* Set up data space for new new data set */
+ dims[0] = 10;
+ dims[1] = 10;
+ space_id = H5Screate_simple(2, dims, dims);
+ VERIFY(space_id >= 0, "H5Screate() failed");
+
+ /* Create a dataset */
+ dset_id = H5Dcreate2(file_id, "dset 0", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset_id >=0, "H5Dcreate() failed");
+
+ /* write some data to the data set */
+ for (i = 0; i < 100; i++)
+ data[i] = i;
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)data);
+ VERIFY(err >= 0, "H5Dwrite() failed.");
+
+ /* Flush the file */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VERIFY(err >= 0, "H5Fflush failed");
+
+ /* get the size of the file */
+ image_size = H5Fget_file_image(file_id, NULL, (size_t)0);
+ VERIFY(image_size > 0, "H5Fget_file_image(1 -- test 1) failed.");
+
+ /* allocate a buffer of the appropriate size */
+ image_ptr = HDmalloc((size_t)image_size);
+ VERIFY(image_ptr != NULL, "HDmalloc(1) failed.");
+
+ /* load the image of the file into the buffer */
+ H5E_BEGIN_TRY {
+ bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)(image_size - 1));
+ } H5E_END_TRY;
+ VERIFY(bytes_read < 0, "H5Fget_file_image(2 -- test 1) succeeded.");
+
+ /* Call H5Fget_file_image() with good buffer and buffer size,
+ * but non-existant file_id. Should fail.
+ */
+ H5E_BEGIN_TRY {
+ bytes_read = H5Fget_file_image((hid_t)0, image_ptr, (size_t)(image_size));
+ } H5E_END_TRY;
+ VERIFY(bytes_read < 0, "H5Fget_file_image(3 -- test 1) succeeded.");
+
+ /* Call H5Fget_file_image() with good buffer and buffer size,
+ * but a file_id of the wrong type. Should fail.
+ */
+ H5E_BEGIN_TRY {
+ bytes_read = H5Fget_file_image(dset_id, image_ptr, (size_t)(image_size));
+ } H5E_END_TRY;
+ VERIFY(bytes_read < 0, "H5Fget_file_image(4 -- test 1) succeeded.");
+
+ /* Close dset and space */
+ err = H5Dclose(dset_id);
+ VERIFY(err >= 0, "H5Dclose failed");
+ err = H5Sclose(space_id);
+ VERIFY(err >= 0, "H5Sclose failed");
+
+ /* close the test file */
+ err = H5Fclose(file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(file_id) failed.");
+
+ /* tidy up */
+ result = h5_cleanup(FILENAME2, fapl_id);
+ VERIFY(result != 0, "h5_cleanup(1) failed.");
+
+ /* discard the image buffer if it exists */
+ if(image_ptr != NULL)
+ HDfree(image_ptr);
+
+ /************************** Test #2 **********************************/
+ /* set up a multi file driver test file, and try to get its image
+ * with H5Fget_file_image(). Attempt should fail.
+ */
+
+ /* setup parameters for multi file driver */
+ for(mt = (H5FD_mem_t)0; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) {
+ memb_addr[mt] = HADDR_UNDEF;
+ memb_fapl[mt] = H5P_DEFAULT;
+ memb_map[mt] = H5FD_MEM_DRAW;
+ memb_name[mt] = NULL;
+ }
+
+ memb_map[H5FD_MEM_SUPER] = H5FD_MEM_SUPER;
+ memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_SUPER] = "%s-s.h5";
+ memb_addr[H5FD_MEM_SUPER] = 0;
+
+ memb_map[H5FD_MEM_BTREE] = H5FD_MEM_BTREE;
+ memb_fapl[H5FD_MEM_BTREE] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_BTREE] = "%s-b.h5";
+ memb_addr[H5FD_MEM_BTREE] = memb_addr[H5FD_MEM_SUPER] + TYPE_SLICE;
+
+ memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW;
+ memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_DRAW] = "%s-r.h5";
+ memb_addr[H5FD_MEM_DRAW] = memb_addr[H5FD_MEM_BTREE] + TYPE_SLICE;
+
+ memb_map[H5FD_MEM_GHEAP] = H5FD_MEM_GHEAP;
+ memb_fapl[H5FD_MEM_GHEAP] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_GHEAP] = "%s-g.h5";
+ memb_addr[H5FD_MEM_GHEAP] = memb_addr[H5FD_MEM_DRAW] + TYPE_SLICE;
+
+ memb_map[H5FD_MEM_LHEAP] = H5FD_MEM_LHEAP;
+ memb_fapl[H5FD_MEM_LHEAP] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_LHEAP] = "%s-l.h5";
+ memb_addr[H5FD_MEM_LHEAP] = memb_addr[H5FD_MEM_GHEAP] + TYPE_SLICE;
+
+ memb_map[H5FD_MEM_OHDR] = H5FD_MEM_OHDR;
+ memb_fapl[H5FD_MEM_OHDR] = H5P_DEFAULT;
+ memb_name[H5FD_MEM_OHDR] = "%s-o.h5";
+ memb_addr[H5FD_MEM_OHDR] = memb_addr[H5FD_MEM_LHEAP] + TYPE_SLICE;
+
+ /* setup fapl */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VERIFY(fapl_id >= 0, "H5Pcreate(2) failed");
+
+ /* setup the fapl for the multi file driver */
+ err = H5Pset_fapl_multi(fapl_id, memb_map, memb_fapl, memb_name,
+ memb_addr, FALSE);
+ VERIFY(err >= 0, "H5Pset_fapl_multi failed");
+
+ /* setup the file name */
+ h5_fixname(FILENAME2[4], fapl_id, file_name, sizeof(file_name));
+ VERIFY(HDstrlen(file_name)>0, "h5_fixname failed");
+
+ /* create the file */
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
+ VERIFY(file_id >= 0, "H5Fcreate() failed.");
+
+ /* Set up data space for new new data set */
+ dims[0] = 10;
+ dims[1] = 10;
+ space_id = H5Screate_simple(2, dims, dims);
+ VERIFY(space_id >= 0, "H5Screate() failed");
+
+ /* Create a dataset */
+ dset_id = H5Dcreate2(file_id, "dset 0", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset_id >=0, "H5Dcreate() failed");
+
+ /* write some data to the data set */
+ for (i = 0; i < 100; i++)
+ data[i] = i;
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)data);
+ VERIFY(err >= 0, "H5Dwrite() failed.");
+
+ /* Flush the file */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VERIFY(err >= 0, "H5Fflush failed");
+
+ /* attempt to get the size of the file -- should fail */
+ H5E_BEGIN_TRY {
+ image_size = H5Fget_file_image(file_id, NULL, (size_t)0);
+ } H5E_END_TRY;
+ VERIFY(image_size == -1, "H5Fget_file_image(5) succeeded.");
+
+ /* Close dset and space */
+ err = H5Dclose(dset_id);
+ VERIFY(err >= 0, "H5Dclose failed");
+ err = H5Sclose(space_id);
+ VERIFY(err >= 0, "H5Sclose failed");
+
+ /* close the test file */
+ err = H5Fclose(file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(2) failed.");
+
+ /* tidy up */
+ result = h5_cleanup(FILENAME2, fapl_id);
+ VERIFY(result != 0, "h5_cleanup(2 failed.");
+
+ /************************** Test #3 **********************************/
+ /* set up a split file driver test file, and try to get its image
+ * with H5Fget_file_image(). Attempt should fail.
+ */
+
+ /* create fapl */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VERIFY(fapl_id >= 0, "H5Pcreate(3) failed");
+
+ /* setup the fapl for the split file driver */
+ err = H5Pset_fapl_split(fapl_id, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT);
+ VERIFY(err >= 0, "H5Pset_fapl_split failed");
+
+ /* setup the file name */
+ h5_fixname(FILENAME2[5], fapl_id, file_name, sizeof(file_name));
+ VERIFY(HDstrlen(file_name)>0, "h5_fixname failed");
+
+ /* create the file */
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
+ VERIFY(file_id >= 0, "H5Fcreate() failed.");
+
+ /* Set up data space for new new data set */
+ dims[0] = 10;
+ dims[1] = 10;
+ space_id = H5Screate_simple(2, dims, dims);
+ VERIFY(space_id >= 0, "H5Screate() failed");
+
+ /* Create a dataset */
+ dset_id = H5Dcreate2(file_id, "dset 0", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset_id >=0, "H5Dcreate() failed");
+
+ /* write some data to the data set */
+ for (i = 0; i < 100; i++)
+ data[i] = i;
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)data);
+ VERIFY(err >= 0, "H5Dwrite() failed.");
+
+ /* Flush the file */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VERIFY(err >= 0, "H5Fflush failed");
+
+ /* attempt to get the size of the file -- should fail */
+ H5E_BEGIN_TRY {
+ image_size = H5Fget_file_image(file_id, NULL, (size_t)0);
+ } H5E_END_TRY;
+ VERIFY(image_size == -1, "H5Fget_file_image(6) succeeded.");
+
+ /* Close dset and space */
+ err = H5Dclose(dset_id);
+ VERIFY(err >= 0, "H5Dclose failed");
+ err = H5Sclose(space_id);
+ VERIFY(err >= 0, "H5Sclose failed");
+
+ /* close the test file */
+ err = H5Fclose(file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(2) failed.");
+
+
+ /************************** Test #4 **********************************/
+ /* set up a family file driver test file, and try to get its image
+ * with H5Fget_file_image(). Attempt should fail.
+ */
+
+ /* create fapl */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VERIFY(fapl_id >= 0, "H5Pcreate(3) failed");
+
+ err = H5Pset_fapl_family(fapl_id, (hsize_t)FAMILY_SIZE, H5P_DEFAULT);
+ VERIFY(err >= 0, "H5Pset_fapl_family failed");
+
+ h5_fixname(FILENAME2[3], fapl_id, file_name, sizeof(file_name));
+ VERIFY(HDstrlen(file_name)>0, "h5_fixname failed");
+
+ /* create the file */
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
+ VERIFY(file_id >= 0, "H5Fcreate() failed.");
+
+ /* Set up data space for new new data set */
+ dims[0] = 10;
+ dims[1] = 10;
+ space_id = H5Screate_simple(2, dims, dims);
+ VERIFY(space_id >= 0, "H5Screate() failed");
+
+ /* Create a dataset */
+ dset_id = H5Dcreate2(file_id, "dset 0", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VERIFY(dset_id >=0, "H5Dcreate() failed");
+
+ /* write some data to the data set */
+ for (i = 0; i < 100; i++)
+ data[i] = i;
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)data);
+ VERIFY(err >= 0, "H5Dwrite() failed.");
+
+ /* Flush the file */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VERIFY(err >= 0, "H5Fflush failed");
+
+ /* attempt to get the size of the file -- should fail */
+ H5E_BEGIN_TRY {
+ image_size = H5Fget_file_image(file_id, NULL, (size_t)0);
+ } H5E_END_TRY;
+ VERIFY(image_size == -1, "H5Fget_file_image(7) succeeded.");
+
+ /* Close dset and space */
+ err = H5Dclose(dset_id);
+ VERIFY(err >= 0, "H5Dclose failed");
+ err = H5Sclose(space_id);
+ VERIFY(err >= 0, "H5Sclose failed");
+
+ /* close the test file */
+ err = H5Fclose(file_id);
+ VERIFY(err == SUCCEED, "H5Fclose(2) failed.");
+
+ /* tidy up */
+ result = h5_cleanup(FILENAME2, fapl_id);
+ VERIFY(result != 0, "h5_cleanup(2 failed.");
+
+ PASSED();
+
+ return 0;
+
+error:
+ return 1;
+}
+
+int
+main(void)
+{
+ int errors = 0;
+ hid_t fapl;
+
+ h5_reset();
+
+ printf("Testing File Image Functionality.\n");
+
+ errors += test_properties();
+ errors += test_callbacks();
+ errors += test_core();
+
+ /* test H5Fget_file_image() with sec2 driver */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ if(0 > H5Pset_fapl_sec2(fapl))
+ errors++;
+ else
+ errors += test_get_file_image("H5Fget_file_image() with sec2 driver",
+ 0, fapl);
+
+ /* test H5Fget_file_image() with stdio driver */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ if(0 > H5Pset_fapl_stdio(fapl))
+ errors++;
+ else
+ errors += test_get_file_image("H5Fget_file_image() with stdio driver",
+ 1, fapl);
+
+ /* test H5Fget_file_image() with core driver */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ if(0 > H5Pset_fapl_core(fapl, (size_t)(64 *1024), TRUE))
+ errors++;
+ else
+ errors += test_get_file_image("H5Fget_file_image() with core driver",
+ 2, fapl);
+
+#if 0
+ /* at present, H5Fget_file_image() rejects files opened with the
+ * family file driver, due to the addition of a driver info message
+ * in the super block. This message prevents the image being opened
+ * with any driver other than the family file driver, which sort of
+ * defeats the purpose of the get file image operation.
+ *
+ * While this issues is quite fixable, we don't have time or resources
+ * for this right now. Once we do, the following code should be
+ * suitable for testing the fix.
+ */
+ /* test H5Fget_file_image() with family file driver */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE, H5P_DEFAULT) < 0)
+ errors++;
+ else
+ errors += test_get_file_image("H5Fget_file_image() with family driver",
+ 3, fapl);
+#endif
+
+ errors += test_get_file_image_error_rejection();
+
+
+ if(errors) {
+ printf("***** %d File Image TEST%s FAILED! *****\n",
+ errors, errors > 1 ? "S" : "");
+ return 1;
+ }
+
+ printf("All File Image tests passed.\n");
+ return 0;
+}
+
diff --git a/test/file_image_core_test.h5 b/test/file_image_core_test.h5
new file mode 100644
index 0000000..1cc5130
--- /dev/null
+++ b/test/file_image_core_test.h5
Binary files differ
diff --git a/test/gen_file_image.c b/test/gen_file_image.c
new file mode 100644
index 0000000..bc9de29
--- /dev/null
+++ b/test/gen_file_image.c
@@ -0,0 +1,91 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Friday, March 30, 2012
+ *
+ * Purpose: Create a simple file for use with the file image tests.
+ *
+ */
+#include "hdf5.h"
+
+#define TESTFILE "file_image_core_test.h5"
+
+/* 2-D dataset with fixed dimensions */
+#define SPACE_RANK 2
+#define SPACE_DIM1 128
+#define SPACE_DIM2 32
+
+/* Dataset data */
+int data[SPACE_DIM1][SPACE_DIM2];
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose:
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 30, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+ hid_t file, space, dset;
+ hsize_t dims[SPACE_RANK] = {SPACE_DIM1, SPACE_DIM2};
+ size_t i, j; /* Local index variables */
+
+ /* Initialize the data */
+ for(i = 0; i < SPACE_DIM1; i++)
+ for(j = 0; j < SPACE_DIM2; j++)
+ data[i][j] = (int)(j % 5);
+
+ /* Create the file */
+ file = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ if(file < 0)
+ printf("file < 0!\n");
+
+ /* Create the dataspace */
+ space = H5Screate_simple(SPACE_RANK, dims, NULL);
+ if(space < 0)
+ printf("space < 0!\n");
+
+ /* Create the compressed dataset */
+ dset = H5Dcreate2(file, "Dataset1", H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if(dset < 0)
+ printf("dset < 0!\n");
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
+ printf("H5Dwrite() failed!\n");
+
+ /* Close everything */
+ if(H5Dclose(dset) < 0)
+ printf("H5Dclose() failed!\n");
+ if(H5Sclose(space) < 0)
+ printf("H5Sclose() failed!\n");
+ if(H5Fclose(file) < 0)
+ printf("H5Fclose() failed!\n");
+
+ return 0;
+}
+
diff --git a/test/istore.c b/test/istore.c
index 0c970bc..f99e835 100644
--- a/test/istore.c
+++ b/test/istore.c
@@ -467,7 +467,7 @@ error:
*/
static herr_t
test_sparse(hid_t f, const char *prefix, size_t nblocks,
- size_t nx, size_t ny, size_t nz)
+ size_t nx, size_t ny, size_t nz, int skip_test)
{
hid_t dataset; /* Dataset ID */
hid_t fspace; /* Dataset's file dataspace */
@@ -499,6 +499,10 @@ test_sparse(hid_t f, const char *prefix, size_t nblocks,
sprintf(s, "istore sparse: %s", dims);
TESTING(s);
+ if(skip_test){
+ SKIPPED()
+ return SUCCEED;
+ }
buf = (uint8_t *)HDmalloc(nx * ny * nz);
HDmemset(buf, 128, nx * ny * nz);
@@ -601,6 +605,7 @@ main(int argc, char *argv[])
unsigned size_of_test;
unsigned u; /* Local index variable */
char filename[1024];
+ int skip_test = 0;
int has_sparse_support = 0;
/* Parse arguments or assume these tests (`small', `medium' ) */
@@ -683,27 +688,31 @@ main(int argc, char *argv[])
status = test_extend(file, "extend", (size_t)10, (size_t)400, (size_t)10);
nerrors += status < 0 ? 1 : 0;
}
+ skip_test = 0;
if (size_of_test & TEST_SMALL) {
- status = test_sparse(file, "sparse", (size_t)100, (size_t)5, (size_t)0, (size_t)0);
+ status = test_sparse(file, "sparse", (size_t)100, (size_t)5, (size_t)0, (size_t)0, skip_test);
nerrors += status < 0 ? 1 : 0;
- status = test_sparse(file, "sparse", (size_t)100, (size_t)3, (size_t)4, (size_t)0);
+ status = test_sparse(file, "sparse", (size_t)100, (size_t)3, (size_t)4, (size_t)0, skip_test);
nerrors += status < 0 ? 1 : 0;
- status = test_sparse(file, "sparse", (size_t)100, (size_t)2, (size_t)3, (size_t)4);
+ status = test_sparse(file, "sparse", (size_t)100, (size_t)2, (size_t)3, (size_t)4, skip_test);
nerrors += status < 0 ? 1 : 0;
}
if (size_of_test & TEST_MEDIUM) {
- status = test_sparse(file, "sparse", (size_t)1000, (size_t)30, (size_t)0, (size_t)0);
+ status = test_sparse(file, "sparse", (size_t)1000, (size_t)30, (size_t)0, (size_t)0, skip_test);
nerrors += status < 0 ? 1 : 0;
- status = test_sparse(file, "sparse", (size_t)2000, (size_t)7, (size_t)3, (size_t)0);
+ status = test_sparse(file, "sparse", (size_t)2000, (size_t)7, (size_t)3, (size_t)0, skip_test);
nerrors += status < 0 ? 1 : 0;
- status = test_sparse(file, "sparse", (size_t)2000, (size_t)4, (size_t)2, (size_t)3);
+ status = test_sparse(file, "sparse", (size_t)2000, (size_t)4, (size_t)2, (size_t)3, skip_test);
nerrors += status < 0 ? 1 : 0;
}
- if (has_sparse_support && size_of_test & TEST_LARGE) {
+ skip_test = !has_sparse_support;
+ if (size_of_test & TEST_LARGE) {
/* This test is skipped if there is no POSIX-style sparse file support
* e.g.: Windows NTFS filesystems
*/
- status = test_sparse(file, "sparse", (size_t)800, (size_t)50, (size_t)50, (size_t)50);
+ status = test_sparse(file, "sparse", (size_t)800, (size_t)50, (size_t)50, (size_t)50, skip_test);
+ if(skip_test)
+ printf(" The current VFD does not support sparse files on this platform.\n");
nerrors += status < 0 ? 1 : 0;
}
diff --git a/test/objcopy.c b/test/objcopy.c
index 8c8f411..53ccebd 100644
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -47,6 +47,7 @@ const char *FILENAME[] = {
"objcopy_src",
"objcopy_dst",
"objcopy_ext",
+ "objcopy_src2",
NULL
};
@@ -73,6 +74,7 @@ const char *FILENAME[] = {
#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_CHUNKED2 "dataset_chunked2"
@@ -89,6 +91,9 @@ const char *FILENAME[] = {
#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"
@@ -540,12 +545,17 @@ test_copy_attach_attributes(hid_t loc_id, hid_t type_id)
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++) {
sprintf(attr_name, "%u attr", u);
@@ -553,7 +563,16 @@ test_copy_attach_attributes(hid_t loc_id, hid_t type_id)
attr_data[0] = (int)(100 * u);
attr_data[1] = (int)(200 * u);
- if((aid = H5Acreate2(loc_id, attr_name, type_id, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ /* 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)
@@ -572,6 +591,8 @@ done:
H5Sclose(sid);
if(aid > 0)
H5Aclose(aid);
+ if(acpl > 0)
+ H5Pclose(acpl);
return ret_value;
}
@@ -595,11 +616,15 @@ test_copy_attach_paired_attributes(hid_t loc_id, hid_t loc_id2, hid_t type_id)
hid_t aid = -1, sid = -1;
char attr_name[ATTR_NAME_LEN];
int attr_data[2];
+ hid_t acpl = -1;
unsigned u;
hsize_t dim1 = 2;
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++) {
sprintf(attr_name, "%u attr", u);
@@ -607,6 +632,13 @@ test_copy_attach_paired_attributes(hid_t loc_id, hid_t loc_id2, hid_t type_id)
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;
+
/* Add attribute to first object */
if((aid = H5Acreate2(loc_id, attr_name, type_id, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto done;
if(H5Awrite(aid, H5T_NATIVE_INT, attr_data) < 0) goto done;
@@ -619,6 +651,7 @@ test_copy_attach_paired_attributes(hid_t loc_id, hid_t loc_id2, hid_t type_id)
}
if(H5Sclose(sid) < 0) goto done;
+ if(H5Pclose(acpl) < 0) goto done;
return 0;
@@ -627,6 +660,8 @@ done:
H5Sclose(sid);
if(aid > 0)
H5Aclose(aid);
+ if(acpl > 0)
+ H5Pclose(acpl);
return -1;
} /* end test_copy_attach_paired_attributes() */
@@ -652,10 +687,22 @@ compare_attribute(hid_t aid, hid_t aid2, hid_t pid, const void *wbuf, hid_t obj_
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 */
@@ -1271,7 +1318,9 @@ compare_datasets(hid_t did, hid_t did2, hid_t pid, const void *wbuf)
/* Release raw data buffers */
HDfree(rbuf);
+ rbuf = NULL;
HDfree(rbuf2);
+ rbuf2 = NULL;
/* close the source dataspace */
if(H5Sclose(sid) < 0) TEST_ERROR
@@ -8102,6 +8151,3340 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_attr_crt_order
+ *
+ * Purpose: Tests copying attributes with creation order tracked, with
+ * and without creation order being indexed.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Friday, January 20, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_attr_crt_order(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl)
+{
+ hid_t fid1 = -1, fid2 = -1; /* File IDs */
+ hid_t gcplid = -1; /* Group creation property list ID */
+ hid_t gid1 = -1, gid2 = -1; /* Group IDs */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): attributes with creation order");
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* Create source file */
+ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0)
+ TEST_ERROR
+
+ /* Create GCPL */
+ if((gcplid = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR
+
+ /* Create group with creation order tracked */
+ if(H5Pset_attr_creation_order(gcplid, H5P_CRT_ORDER_TRACKED) < 0) TEST_ERROR
+ if((gid1 = H5Gcreate2(fid1, NAME_GROUP_TOP, H5P_DEFAULT, gcplid, H5P_DEFAULT))
+ < 0)
+ TEST_ERROR
+
+ /* Add attributes to group */
+ if(test_copy_attach_attributes(gid1, H5T_NATIVE_INT) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid1) < 0) TEST_ERROR
+
+ /* Create group with creation order tracked and indexed */
+ if(H5Pset_attr_creation_order(gcplid, H5P_CRT_ORDER_TRACKED
+ | H5P_CRT_ORDER_INDEXED) < 0)
+ TEST_ERROR
+ if((gid1 = H5Gcreate2(fid1, NAME_GROUP_TOP2, H5P_DEFAULT, gcplid,
+ H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* Add attributes to group */
+ if(test_copy_attach_attributes(gid1, H5T_NATIVE_INT) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid1) < 0) TEST_ERROR
+
+ /* Close GCPL */
+ if(H5Pclose(gcplid) < 0) TEST_ERROR
+
+
+ /* Create destination file */
+ if((fid2 = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0)
+ TEST_ERROR
+
+ /* Copy the groups to the destination file */
+ if(H5Ocopy(fid1, NAME_GROUP_TOP, fid2, NAME_GROUP_TOP, H5P_DEFAULT,
+ H5P_DEFAULT) < 0)
+ TEST_ERROR
+ if(H5Ocopy(fid1, NAME_GROUP_TOP2, fid2, NAME_GROUP_TOP2, H5P_DEFAULT,
+ H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ /* Open groups with creation order tracked */
+ if((gid1 = H5Gopen2(fid1, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((gid2 = H5Gopen2(fid2, NAME_GROUP_TOP, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Compare the attributes */
+ if(compare_std_attributes(gid1, gid2, H5P_DEFAULT) != TRUE) TEST_ERROR
+
+ /* Close groups */
+ if(H5Gclose(gid1) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Open groups with creation order tracked and indexed */
+ if((gid1 = H5Gopen2(fid1, NAME_GROUP_TOP2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((gid2 = H5Gopen2(fid2, NAME_GROUP_TOP2, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Compare the attributes */
+ if(compare_std_attributes(gid1, gid2, H5P_DEFAULT) != TRUE) TEST_ERROR
+
+ /* Close groups */
+ if(H5Gclose(gid1) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close */
+ if(H5Fclose(fid1) < 0) TEST_ERROR
+ if(H5Fclose(fid2) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid1);
+ H5Gclose(gid2);
+ H5Pclose(gcplid);
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_attr_crt_order */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_datatype_merge
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, October 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src1 = -1, fid_src2 = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src1_filename[NAME_BUF_SIZE];
+ char src2_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen) {
+ TESTING("H5Ocopy(): merging committed datatypes with reopen")
+ } /* end if */
+ else
+ TESTING("H5Ocopy(): merging committed datatypes")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src1_filename, sizeof src1_filename);
+ h5_fixname(FILENAME[3], src_fapl, src2_filename, sizeof src2_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source files */
+ if((fid_src1 = H5Fcreate(src1_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+ if((fid_src2 = H5Fcreate(src2_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file 1
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src1, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src1, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file 1 */
+ if(H5Fclose(fid_src1) < 0) TEST_ERROR
+
+ /*
+ * Populate source file 2
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src2, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src2, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file 1 */
+ if(H5Fclose(fid_src2) < 0) TEST_ERROR
+
+
+ /* open the source files with read-only */
+ if((fid_src1 = H5Fopen(src1_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+ if((fid_src2 = H5Fopen(src2_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge named dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy each entire file to the destination file (each with their own
+ * group), and verify the committed datatypes are merged
+ */
+ /* 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
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid_src1, "/", fid_dst, NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid_src2, "/", fid_dst, NAME_GROUP_TOP2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open SRC1 committed dtype, get address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open SRC1 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open SRC2 committed dtype, check address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open SRC2 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Now copy only the datasets to the destination file, and verify the committed
+ * datatypes are merged
+ */
+ /* recreate 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
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid_src1, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid_src2, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open SRC1 dset dtype, get address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open SRC2 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC files */
+ if(H5Fclose(fid_src1) < 0) TEST_ERROR
+ if(H5Fclose(fid_src2) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src1);
+ H5Fclose(fid_src2);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_datatype_merge */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_datatype_merge_same_file
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy,
+ * while copying to the same file.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, October 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reopen)
+{
+ hid_t fid = -1; /* File ID */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t gid = -1; /* Group ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes to the source file with reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes to the source file")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filename */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create file */
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate first group
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /*
+ * Populate second group
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy each group to the destination group 3 (each with their own
+ * group), and verify the committed datatypes are merged as expected. All
+ * datatypes copied should reference (share an address with) the
+ * corresponding source datatype.
+ */
+ /* Create destination group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* copy group 1 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP, fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy group 2 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP2, fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open group 1 source committed dtype, get address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 1 source dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 1 committed dtype, check address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 1 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 source committed dtype, get address and make sure it is
+ * different from group 1 source committed dtype */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 2 source dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 committed dtype, check address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 2 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Now copy only the datasets to the destination group, and verify the committed
+ * datatypes are merged as expected
+ */
+ /* Create destination group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP4, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open group 1 source dset dtype, get address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 1 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 source dset dtype, get address and make sure it is
+ * different from group 1 source dset dtype */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_datatype_merge_same_file */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_dt_merge_sugg
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy, and
+ * uses the suggestion list feature
+ * (H5Padd_merge_committed_dtype_path).
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Thursday, November 3, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Now free suggestions, copy dataset without any suggestions, and verify
+ * that it uses datatype "a" in the destination file
+ */
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete destination dataset */
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset 2 dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_dt_merge_sugg */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_dt_merge_attr
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy, with
+ * an attribute using an anonymous committed type in the
+ * destination.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Thursday, November 3, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t gid = -1; /* Group ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with attributes and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with attributes")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* create anonymous committed data type */
+ if((H5Tcommit_anon(fid_dst, tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute at SRC file */
+ if((aid = H5Acreate2(gid, "attr", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Awrite(aid, tid, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * Copy dataset and verify that it uses the same committed datatype as the
+ * already existing attribute in the destination file.
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open attribute dtype, get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_TOP, "attr", H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Aclose(aid);
+ H5Gclose(gid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_dt_merge_attr */
+
+/*
+ * Defines used for the committed datatype tests
+ */
+#define SRC_ROOT_GROUP "src_root"
+#define ROOT_NDT_INT "root_ndt_int"
+#define GROUP_NDT_SHORT "group_ndt_short"
+
+#define SRC_GRP "src_grp"
+#define DST_GRP "dst_grp"
+#define DST_GRP2 "dst_grp2"
+
+#define SRC_NDT_SHORT "src_ndt_short"
+#define SRC_NDT_INT "src_ndt_int"
+#define SRC_NDT_INT2 "src_ndt_int2"
+#define SRC_NDT_FLOAT "src_ndt_float"
+#define SRC_NDT_DOUBLE "src_ndt_double"
+
+#define DST_NDT_SHORT "dst_ndt_short"
+#define DST_NDT_INT "dst_ndt_int"
+#define DST_NDT_FLOAT "dst_ndt_float"
+#define DST_NDT_DOUBLE "dst_ndt_double"
+
+#define SRC_NDT_DSET "src_ndt_dset"
+#define SRC_NDT_DSET2 "src_ndt_dset2"
+#define SRC_NDT_DSET3 "src_ndt_dset3"
+
+#define SRC_DSET "src_dset"
+#define SRC_DSET1 "src_dset1"
+
+#define SRC_ATTR "src_attr"
+
+#define DST_ATTR_ANON_SHORT "dst_attr_anon_short"
+#define DST_ATTR_ANON_INT "dst_attr_anon_int"
+
+#define DST_ATTR "dst_attr"
+#define DST_ATTR2 "dst_attr2"
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_hier_merge
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy:
+ * SRC file:
+ * Create committed datatypes at / and /g0
+ * Create datasets with native type and committed datatypes at /g0
+ * DST file:
+ * Create attributes with anonymous committed datatypes at /uncopied
+ *
+ * Copy / at SRC to DST
+ * Copy /g0 at SRC to DST
+ * Copy the datasets in /g0 at SRC to DST /uncopied
+ * Verify that committed datatypes are copied and merged correctly
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t gid = -1; /* Group IDs */
+ hid_t f_tid = -1; /* Datatype ID for root group */
+ hid_t g_tid = -1; /* Datatype ID for group */
+ hid_t anon_tid = -1; /* Anonymous datatype */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ int i; /* Local index variable */
+ hsize_t dim1d[1]; /* dimension sizes */
+ int buf[DIM_SIZE_1]; /* Buffer for data */
+ haddr_t exp_addr_int, exp_addr_short; /* Expected object addresses */
+ H5O_info_t oinfo; /* Object info */
+ char src_filename[NAME_BUF_SIZE]; /* Source file name */
+ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */
+
+ if(reopen)
+ TESTING("H5Ocopy(): hier. of committed datatypes and merging with reopen")
+ else
+ TESTING("H5Ocopy(): hier. of committed datatypes and merging ")
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ buf[i] = i;
+
+ /* 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();
+
+ /*
+ * Populate source file
+ */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create and commit committed datatype (int) to root group */
+ if((f_tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, ROOT_NDT_INT, f_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Create group /g0 */
+ if((gid = H5Gcreate2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create and commit committed datatype (short) to group /g0 */
+ if((g_tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, GROUP_NDT_SHORT, g_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create dataset of native int in /g0 */
+ if((did = H5Dcreate2(gid, SRC_DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* create dataset of committed datatype (short) in /g0 */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET2, g_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* create dataset of committed datatype (int) in /g0 */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET3, f_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the datatypes */
+ if(H5Tclose(f_tid) < 0) TEST_ERROR
+ if(H5Tclose(g_tid) < 0) TEST_ERROR
+
+ /* close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create group /uncopied */
+ if((gid = H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create and commit anonymous datatype (short) to /uncopied */
+ if((anon_tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(gid, anon_tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute of anon ndt (short) in /uncopied */
+ if((aid = H5Acreate2(gid, DST_ATTR_ANON_SHORT, anon_tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(anon_tid) < 0) TEST_ERROR
+
+ /* create and commit anonymous datatype (int) to /uncopied */
+ if((anon_tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(gid, anon_tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute of anon ndt (int) in /uncopied */
+ if((aid = H5Acreate2(gid, DST_ATTR_ANON_INT, anon_tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(anon_tid) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+ }
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* create ocpl and set merge committed datatype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * Test 1 : copy / in SRC file to DST file
+ */
+ if(H5Ocopy(fid_src, "/", fid_dst, SRC_ROOT_GROUP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* get address of committed datatype at root group */
+ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP "/" ROOT_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr_int = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype at /g0 */
+ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr_short = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test 2: copy /g0 in SRC to DST
+ */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* get address of committed datatype at /g0 */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test 3: copy datsets in /g0 at SRC to DST group /uncopied
+ */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_DSET1, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_DSET1, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET2, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET3, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Open attribute with anon ndt (short), get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_SHORT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* Open attribute with anon ndt (int), get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_INT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 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 property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Tclose(tid);
+ H5Tclose(f_tid);
+ H5Tclose(g_tid);
+ H5Tclose(anon_tid);
+ H5Pclose(ocpypl_id);
+ H5Aclose(aid);
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Gclose(gid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_hier_merge */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_cdt
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy:
+ * SRC file:
+ * Create committed datatype (short)
+ * Create committed datatype (float)
+ * Create committed datatype (int), with attribute of ndt int
+ * Create committed datatype (double), with attribute of anon ndt short
+ * DST file:
+ * Create committed datatype (int)
+ * Create committed datatype (float), with attribute of native int
+ * Create committed datatype (double), with attribute of anon ndt short
+ *
+ * Copy / at SRC to DST
+ * Verify that committed datatypes are copied and merged correctly
+ *
+ * NOTE:
+ * Comparison of attributes are not implemented yet.
+ * Further tests will be added in the future.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_cdt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid1 = -1, tid2 = -1; /* Datatype IDs */
+ hid_t tid3 = -1, tid4 = -1; /* Datatype IDs */
+ hid_t tid5 = -1, tid = -1; /* Datatype IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ int i; /* Local index variable */
+ hsize_t dim1d[1]; /* dimension sizes */
+ int buf[DIM_SIZE_1]; /* Buffer for data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object addresses */
+ char src_filename[NAME_BUF_SIZE]; /* Source file name */
+ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging various committed datatypes with reopen")
+ else
+ TESTING("H5Ocopy(): merging various committed datatypes")
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ buf[i] = i;
+
+ /* 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();
+
+ /*
+ * Populate source file
+ */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype (short) */
+ if((tid1 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_SHORT, tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (float) */
+ if((tid2 = H5Tcopy(H5T_NATIVE_FLOAT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_FLOAT, tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (int) */
+ if((tid3 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if((tid3 = H5Topen2(fid_src, SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create an attribute of committed datatype (int); attach to committed datatype (int) */
+ if((aid = H5Acreate2(tid3, SRC_ATTR, tid3, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* create committed datatype (double) */
+ if((tid4 = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_DOUBLE, tid4, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an anonymous committed datatype (short) */
+ if((tid5 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(fid_src, tid5, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid4) < 0) TEST_ERROR
+ if((tid4 = H5Topen2(fid_src, SRC_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of anon ndt (short); attach to committed datatype (double) */
+ if((aid = H5Acreate2(tid4, SRC_ATTR, tid5, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the committed datatypes */
+ if(H5Tclose(tid1) < 0) TEST_ERROR
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if(H5Tclose(tid4) < 0) TEST_ERROR
+ if(H5Tclose(tid5) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype (integer) */
+ if((tid1 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (float) */
+ if((tid2 = H5Tcopy(H5T_NATIVE_FLOAT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_FLOAT, tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if((tid2 = H5Topen2(fid_dst, DST_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of native integer; attach to committed datatype (float) */
+ if((aid = H5Acreate2(tid2, DST_ATTR, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* create committed datatype (double) */
+ if((tid3 = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_DOUBLE, tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create anonymous committed datatype (short) */
+ if((tid4 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(fid_dst, tid4, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if((tid3 = H5Topen2(fid_dst, DST_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of anon ndt (short); attach to ndt (double) */
+ if((aid = H5Acreate2(tid3, DST_ATTR, tid4, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the committed datatypes */
+ if(H5Tclose(tid1) < 0) TEST_ERROR
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if(H5Tclose(tid4) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy everything in SRC to DST */
+ if(H5Ocopy(fid_src, "/", fid_dst, SRC_ROOT_GROUP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /*
+ * Verification
+ */
+ /* get address of committed datatype: /src_root/src_ndt_double */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_double */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_float */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_float */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_int */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_int */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_short */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* open attribute; get its dtype; get dtype's address: /src_root/src_ndt_double/dst_attr */
+ if((aid = H5Aopen_by_name(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the files */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the object copy property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(ocpypl_id);
+ H5Tclose(tid);
+ H5Tclose(tid1);
+ H5Tclose(tid2);
+ H5Tclose(tid3);
+ H5Tclose(tid4);
+ H5Tclose(tid5);
+ H5Aclose(aid);
+ H5Sclose(sid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_cdt */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_suggs
+ *
+ * Purpose: Tests the suggested searching paths feature (H5Padd_merge_committed_dtype_path)
+ * is correctly applied in merging the committed datatypes.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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();
+
+ /*
+ * Populate source file
+ */
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/src_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/dst_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Create a group /uncopied */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/uncopied/src_ndt_int" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/uncopied/src_ndt_int" */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/uncopied/src_ndt_int" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/src_ndt_int" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, SRC_NDT_INT, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/uncopied/src_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/src_ndt_int" */
+ if((tid = H5Topen2(fid_dst, SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* remove "/uncopied/src_ndt_int" from DST file */
+ if(H5Ldelete(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/uncopied/src_ndt_int" at DST file */
+ /* use default ocpypl_id -- without merging and suggestion */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/src_ndt_int2" at DST file */
+ /* copy with merging and search suggestion: "/uncopied/src_ndt_int" */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, SRC_NDT_INT2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/uncopied/src_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/src_ndt_int2" */
+ if((tid = H5Topen2(fid_dst, SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, DST_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_int" from SRC file to "/uncopied/src_ndt_int2" at DST file */
+ /* copy with merging and search suggestion: "/dst_ndt_int, /uncopied/src_ndt_int" */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/dst_dt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/uncopied/src_ndt_int2" */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_dset_suggs
+ *
+ * Purpose: Tests the suggested searching paths feature (H5Padd_merge_committed_dtype_path)
+ * is correctly applied in merging the committed datatypes of datasets.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; Dec 12, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes of datasets with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes of datasets with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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();
+
+ /*
+ * Populate source file
+ */
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/src_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0] = DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid_src, SRC_NDT_DSET, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/dst_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Create a group "/uncopied" */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_dset" from SRC file to "/uncopied/src_ndt_dset" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/dst_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/uncopied/src_ndt_dset" */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/uncopied/src_ndt_dset" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_dset" from SRC file to "/src_ndt_dset" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, SRC_NDT_DSET, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype dataset "/uncopied/src_ndt_dset", get its datatype address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/src_ndt_dset" */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* remove "/uncopied/src_ndt_dset" */
+ if(H5Ldelete(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_dset" from SRC file to "/uncopied/src_ndt_dset" at DST file */
+ /* use default ocpypl_id -- without merging and suggestion */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_dset" from SRC file to "/src_ndt_dset2" at DST file */
+ /* use merging and suggested searching path: "/uncopied/src_ndt_dset" */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the copied dataset: /uncopied/src_ndt_dset", get its address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/src_ndt_dset2" */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/src_ndt_dset" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, SRC_NDT_DSET) < 0) TEST_ERROR
+
+ /* copy /src_ndt_dset from SRC file to /uncopied/src_ndt_dset2 at DST */
+ /* use merging and suggested search paths: "/src_ndt_dset, /uncopied/src_ndt_dset" */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the copied dataset: "/src_ndt_dset", get its datatype address */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: /uncopied/src_ndt_dset2 */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_dset_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_all_suggs
+ *
+ * Purpose: Tests the merging committed datatype + search suggestion feature.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t gid = -1; /* Group ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t exp_did = -1; /* Dataset ID */
+ hid_t tid_short = -1; /* Datatype ID */
+ hid_t exp_tid; /* Expected datatype ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging different committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging different committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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();
+
+ /*
+ * Populate source file
+ */
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* set dataspace dimension, create dataspace */
+ dim1d[0] = DIM_SIZE_1;
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_src, SRC_GRP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, SRC_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create first dataset in group */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create second dataset in group */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET2, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create third dataset in group */
+ if((did = H5Dcreate2(gid, SRC_DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* get datatype */
+ if((tid_short = H5Topen2(fid_src, "/" SRC_GRP "/" SRC_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to the dataset */
+ if((aid = H5Acreate2(did, SRC_ATTR, tid_short, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid_short) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate DST file
+ */
+
+ /* create DST file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* set dataspace dimension, create dataspace */
+ dim1d[0] = DIM_SIZE_2;
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_FLOAT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_FLOAT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if((tid = H5Topen2(fid_dst, DST_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_dst, DST_GRP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create a committed datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(gid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create an attribute attached to group */
+ if((aid = H5Acreate2(gid, DST_ATTR2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_dst, DST_GRP2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create a committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to group */
+ if((aid = H5Acreate2(gid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create a committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0)TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* create a committed datatype at root group */
+ if((tid = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_DOUBLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* MSC - workaround committed datatypes */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if((tid = H5Topen2(fid_dst, DST_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* get datatype */
+ if((tid_short = H5Topen2(fid_dst, "/" DST_GRP2 "/" DST_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, tid_short, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid_short) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "A_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* get datatype for attribute attached to the group */
+ if((aid = H5Aopen_by_name(fid_dst, DST_GRP, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "A_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_GRP2) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "B_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* get datatype for attribute attached to the group */
+ if((aid = H5Aopen_by_name(fid_dst, DST_GRP2, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "B_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add another committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_GRP "/" DST_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "C_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_grp/dst_dt_int", get its address */
+ if((exp_tid = H5Topen2(fid_dst, "/" DST_GRP "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "C_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* delete the group */
+ if(H5Ldelete(fid_dst, "/" DST_GRP, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* free the search suggestion paths */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "D_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open datatype of dataset */
+ if((exp_did = H5Dopen2(fid_dst, "A_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Dget_type(exp_did)) < 0) TEST_ERROR
+
+ /* Open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "C_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "D_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Dclose(exp_did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 5
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_NDT_DOUBLE) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET, fid_dst, "A_src_dset", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open attribute's dtype attached to committed datatype /dst_ndt_double */
+ if((aid = H5Aopen_by_name(fid_dst, DST_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* Open datatype of dataset, check address */
+ if((did = H5Dopen2(fid_dst, "A_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 6
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_NDT_SHORT) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET, fid_dst, "B_src_dset", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_ndt_short" */
+ if((exp_tid = H5Topen2(fid_dst, "/" DST_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open datatype of dataset, check address */
+ if((did = H5Dopen2(fid_dst, "B_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Tclose(tid_short);
+ H5Tclose(exp_tid);
+ H5Dclose(did);
+ H5Dclose(exp_did);
+ H5Aclose(aid);
+ H5Sclose(sid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_all_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_set_mcdt_search_cb
+ *
+ * Purpose: Tests the "H5Pset_mcdt_search_cb" feature of H5Ocopy to
+ * stop or continue the search of global list
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+/* User data struct for the callback */
+typedef struct mcdt_search_cb_ud {
+ H5O_mcdt_search_ret_t search_action; /* Return value for callback */
+ unsigned called; /* # of times callback has been called */
+} mcdt_search_cb_ud;
+
+/* The user callback function */
+static H5O_mcdt_search_ret_t
+mcdt_search_cb(void *_udata)
+{
+ mcdt_search_cb_ud *udata = (mcdt_search_cb_ud *)_udata;
+
+ udata->called++;
+ return(udata->search_action);
+} /* mcdt_search_cb() */
+
+static int
+test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ mcdt_search_cb_ud cb_udata; /* User data for callback */
+
+ if(reopen)
+ TESTING("H5Ocopy(): H5Pset_mcdt_search_cb and reopen")
+ else
+ TESTING("H5Ocopy(): H5Pset_mcdt_search_cb")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* named data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 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 group in destination file */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Set callback to continue the search
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_CONT;
+ cb_udata.called = 0;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* Add datatype suggestion to group "/uncopied" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED) < 0) TEST_ERROR
+
+ /* Continue the global search */
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cb, &cb_udata) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open copied dataset and its dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_STOP;
+ cb_udata.called = 0;
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype.
+ * Disable suggestion list.
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_STOP;
+ cb_udata.called = 0;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete dataset */
+ if(H5Ldelete(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_set_mcdt_search_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_set_get_mcdt_cb
+ *
+ * Purpose: Tests for the "H5Pset/get_mcdt_search_cb" feature of H5Ocopy.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* The user callback functions */
+static H5O_mcdt_search_ret_t
+mcdt_search_cbA(void *_udata)
+{
+ H5O_mcdt_search_ret_t *action = (H5O_mcdt_search_ret_t *)_udata;
+
+ return(*action);
+} /* mcdt_search_cb() */
+
+static H5O_mcdt_search_ret_t
+mcdt_search_cbB(void *_udata)
+{
+ H5O_mcdt_search_ret_t *action = (H5O_mcdt_search_ret_t *)_udata;
+
+ return(*action);
+} /* mnt_search_cb() */
+
+/* The main test function */
+static int
+test_copy_set_get_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ H5O_mcdt_search_cb_t mcdt_cb = NULL; /* The callback function */
+ H5O_mcdt_search_ret_t mcdt_udataA; /* User data for callback */
+ H5O_mcdt_search_ret_t mcdt_udataB; /* User data for callback */
+ H5O_mcdt_search_ret_t *mcdt_udata_p = NULL; /* Pointer to user data for callback */
+
+ if(reopen)
+ TESTING("H5Ocopy(): H5Pset/get_mcdt_search_cb and reopen")
+ else
+ TESTING("H5Ocopy(): H5Pset/get_mcdt_search_cb")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* 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
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 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 group in destination file */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != NULL) TEST_ERROR
+ if(mcdt_udata_p != NULL) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Set callback to continue the search
+ */
+ mcdt_udataA = H5O_MCDT_SEARCH_CONT;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* Add datatype suggestion to group "/uncopied" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED) < 0) TEST_ERROR
+
+ /* Continue the global search */
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbA, &mcdt_udataA) < 0)
+ TEST_ERROR
+
+ /* open the destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbA) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataA) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype
+ */
+ mcdt_udataB = H5O_MCDT_SEARCH_STOP;
+
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbA, &mcdt_udataB) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbA) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataB) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbB, &mcdt_udataB) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete dataset */
+ if(H5Ldelete(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbB) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataB) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_set_get_mcdt_search_cb */
+
+
+/*-------------------------------------------------------------------------
* Function: test_copy_option
*
* Purpose: Create a group in SRC file and copy it to DST file
@@ -8393,6 +11776,319 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_dataset_open
+ *
+ * Purpose: To ensure that H5Ocopy() copies data of opened dataset correctly.
+ * This is for bug fix HDFFV-7853.
+ *
+ * Test Case 1:
+ * Create a dataset with attributes in SRC file
+ * Copy the opened dataset to another location in the same file
+ * Copy the opened dataset to DST file
+ * Close the dataset
+ *
+ * Test Case 2:
+ * Reopen the dataset, write new data to the dataset
+ * Copy the opened dataset to another location in the same file
+ * Copy the opened dataset to to DST file
+ * Close the dataset
+ *
+ * Test Case 3:
+ * Create a committed datatype
+ * Create a dataset with the committed datatype in SRC file
+ * Open the committed datatype
+ * Copy the opened dataset (with the opened committed datatype) to another location in the same file
+ * Copy the opened dataset (with the opened committed datatype) to DST file
+ * Close the dataset and the committed datatype
+ *
+ * Test Case 4:
+ * Create a group with attributes, create a dataset in the group
+ * Copy the opened group (together with the opened dataset) to another location in the same file
+ * Copy the opened group (together with the opened dataset) to DST file
+ * Close the group and the dataset
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi
+ * Feb 7, 2012
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_dataset_open(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ int buf[DIM_SIZE_1][DIM_SIZE_2]; /* Buffer for writing data */
+ int newbuf[DIM_SIZE_1][DIM_SIZE_2]; /* Buffer for writing data */
+ hsize_t dim2d[2]; /* Dataset dimensions */
+ int i, j; /* local index variables */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): copying objects while opened");
+
+ /* Initialize write buffer */
+ for (i=0; i<DIM_SIZE_1; i++)
+ for (j=0; j<DIM_SIZE_2; j++)
+ buf[i][j] = 10000 + 100*i+j;
+
+ /* Initialize another write buffer */
+ for (i=0; i<DIM_SIZE_1; i++)
+ for (j=0; j<DIM_SIZE_2; j++)
+ newbuf[i][j] = 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 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
+
+ /* Set dataspace dimensions */
+ dim2d[0] = DIM_SIZE_1;
+ dim2d[1] = DIM_SIZE_2;
+
+ /* create 2D dataspace */
+ if((sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR
+
+ /* create 2D int dataset in SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to the dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* attach attributes to the dataset */
+ if(test_copy_attach_attributes(did, H5T_NATIVE_INT) < 0) TEST_ERROR
+
+ /*
+ * Test case 1
+ */
+
+ /*
+ * Copy within the same file
+ */
+ /* copy the opened dataset to another location in SRC file */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_src, NAME_DATASET_SIMPLE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset */
+ if((did2 = H5Dopen2(fid_src, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /*
+ * Copy to another file
+ */
+ /* copy the opened dataset from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset in DST file */
+ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset in DST file */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the dataset in SRC file */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test case 2
+ */
+ /* reopen the dataset in SRC file */
+ if((did = H5Dopen2(fid_src, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write another set of data to the dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, newbuf) < 0) TEST_ERROR
+
+ /*
+ * Copy within the same file
+ */
+ /* copy the opened dataset to another location in SRC file */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_src, "NEW_DATASET", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset */
+ if((did2 = H5Dopen2(fid_src, "NEW_DATASET", H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, newbuf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset in SRC file */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+ /*
+ * Copy to another file
+ */
+ /* copy the opened dataset from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, "NEW_DATASET", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset in DST file */
+ if((did2 = H5Dopen2(fid_dst, "NEW_DATASET", H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, newbuf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset in DST file */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the dataset at SRC file */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test case 3
+ */
+
+ /* make a copy of the datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* commit the datatype */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* open the committed datatype */
+ tid = H5Topen2(fid_src, NAME_DATATYPE_SIMPLE, H5P_DEFAULT);
+
+ /* create 2D dataset with the opened committed datatype in SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_NAMED_DTYPE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to the dataset */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /*
+ * Copy within the same file
+ */
+ /* copy the opened dataset (with the opened committed datatype) to another location in SRC file */
+ if(H5Ocopy(fid_src, NAME_DATASET_NAMED_DTYPE, fid_src, NAME_DATASET_NAMED_DTYPE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset */
+ if((did2 = H5Dopen2(fid_src, NAME_DATASET_NAMED_DTYPE2, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset in SRC file */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /*
+ * Copy to another file
+ */
+ /* copy the opened dataset (with the opened committed datatype) from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_NAMED_DTYPE, fid_dst, NAME_DATASET_NAMED_DTYPE2, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied dataset in DST file */
+ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_NAMED_DTYPE2, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the copied dataset in DST file */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the dataset at SRC file */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the committed datatype at SRC file */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /*
+ * Test case 4
+ */
+ /* create a group in 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
+
+ /* create 2D int dataset in the group at SRC file */
+ if((did = H5Dcreate2(gid, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to the dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+ /*
+ * Copy within the same file
+ */
+ /* copy the opened group (together with opened dataset) to another location in SRC file */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_src, "COPIED_GROUP", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied group at SRC */
+ if((gid2 = H5Gopen2(fid_src, "COPIED_GROUP", H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the groups are equal */
+ if(compare_groups(gid, gid2, H5P_DEFAULT, -1, 0) != TRUE) TEST_ERROR
+
+ /* close the DST dataset */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /*
+ * Copy to another file
+ */
+ /* copy the opened group (together with opened dataset) to DST file */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, "COPIED_GROUP", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the copied group at DST */
+ if((gid2 = H5Gopen2(fid_dst, "COPIED_GROUP", H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the groups are equal */
+ if(compare_groups(gid, gid2, H5P_DEFAULT, -1, 0) != TRUE) TEST_ERROR
+
+ /* close the group in DST file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* close the group in SRC file */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the dataset in SRC file */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 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
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Dclose(did);
+ H5Dclose(did2);
+ H5Sclose(sid);
+ H5Gclose(gid);
+ H5Gclose(gid2);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_dataset_open */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test H5Ocopy()
@@ -8419,6 +12115,7 @@ main(void)
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();
@@ -8451,6 +12148,11 @@ main(void)
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;
@@ -8467,6 +12169,7 @@ main(void)
if(configuration & CONFIG_SHARE_DST) {
puts("Testing with shared dst messages:");
fcpl_dst = fcpl_shared;
+ same_file = FALSE;
}
else {
puts("Testing without shared dst messages:");
@@ -8489,7 +12192,7 @@ main(void)
}
} /* end if */
else {
- puts("Testing with oldest file format for source file:");
+ puts("Testing with oldest file format for source file:");
src_fapl = fapl;
num_attributes_g = 4;
} /* end else */
@@ -8498,6 +12201,7 @@ main(void)
if(configuration & CONFIG_DST_NEW_FORMAT) {
puts("Testing with latest format for destination file:");
dst_fapl = fapl2;
+ same_file = FALSE;
} /* end if */
else {
puts("Testing with oldest file format for destination file:");
@@ -8533,6 +12237,8 @@ main(void)
nerrors += test_copy_named_datatype_attr_self(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
+ nerrors += test_copy_attr_crt_order(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
+
nerrors += test_copy_option(fcpl_src, fcpl_dst, src_fapl, dst_fapl,
H5O_COPY_WITHOUT_ATTR_FLAG,
FALSE, "H5Ocopy(): without attributes");
@@ -8560,14 +12266,37 @@ main(void)
nerrors += test_copy_option(fcpl_src, fcpl_dst, src_fapl, dst_fapl,
H5O_COPY_WITHOUT_ATTR_FLAG | H5O_COPY_PRESERVE_NULL_FLAG,
TRUE, "H5Ocopy(): preserve NULL messages");
+ nerrors += test_copy_dataset_open(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
/* Tests that do not use attributes and do not need to be tested
* multiple times for different attribute configurations */
if(configuration < CONFIG_DENSE) {
+ hbool_t reopen;
+
nerrors += test_copy_named_datatype(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_named_datatype_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_named_datatype_vl_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
+ /* Loop over reopening the file */
+ for(reopen = FALSE; reopen <= TRUE; reopen++) {
+ nerrors += test_copy_committed_datatype_merge(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+
+ if(same_file)
+ nerrors += test_copy_committed_datatype_merge_same_file(fcpl_src, src_fapl, reopen);
+
+ nerrors += test_copy_committed_dt_merge_sugg(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_committed_dt_merge_attr(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+
+ /* tests added for merging committed datatypes + suggestions + callback */
+ nerrors += test_copy_cdt_hier_merge(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_cdt(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_dset_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_all_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_set_mcdt_search_cb(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_set_get_mcdt_search_cb(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ } /* end for */
+
nerrors += test_copy_dataset_external(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_named_dtype(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_named_dtype_hier(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt
index d60aea5..f42af9f 100644
--- a/testpar/CMakeLists.txt
+++ b/testpar/CMakeLists.txt
@@ -11,6 +11,7 @@ SET (testphdf5_SRCS
${HDF5_TEST_PAR_SOURCE_DIR}/testphdf5.c
${HDF5_TEST_PAR_SOURCE_DIR}/t_dset.c
${HDF5_TEST_PAR_SOURCE_DIR}/t_file.c
+ ${HDF5_TEST_PAR_SOURCE_DIR}/t_file_image.c
${HDF5_TEST_PAR_SOURCE_DIR}/t_mdset.c
${HDF5_TEST_PAR_SOURCE_DIR}/t_ph5basic.c
${HDF5_TEST_PAR_SOURCE_DIR}/t_coll_chunk.c
diff --git a/testpar/COPYING b/testpar/COPYING
index 6903daf..6903daf 100755..100644
--- a/testpar/COPYING
+++ b/testpar/COPYING
diff --git a/testpar/Makefile.am b/testpar/Makefile.am
index 5a7a3f3..b2fb97c 100644
--- a/testpar/Makefile.am
+++ b/testpar/Makefile.am
@@ -31,8 +31,8 @@ TEST_SCRIPT_PARA=testph5.sh
check_PROGRAMS = $(TEST_PROG_PARA)
check_SCRIPTS= $(TEST_SCRIPT)
-testphdf5_SOURCES=testphdf5.c t_dset.c t_file.c t_mdset.c t_ph5basic.c \
- t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
+testphdf5_SOURCES=testphdf5.c t_dset.c t_file.c t_file_image.c t_mdset.c \
+ t_ph5basic.c t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
# The tests all depend on the hdf5 library and the test library
LDADD = $(LIBH5TEST) $(LIBHDF5)
diff --git a/testpar/Makefile.in b/testpar/Makefile.in
index ae0c7d0..a9a4135 100644
--- a/testpar/Makefile.in
+++ b/testpar/Makefile.in
@@ -95,9 +95,10 @@ t_shapesame_OBJECTS = t_shapesame.$(OBJEXT)
t_shapesame_LDADD = $(LDADD)
t_shapesame_DEPENDENCIES = $(LIBH5TEST) $(LIBHDF5)
am_testphdf5_OBJECTS = testphdf5.$(OBJEXT) t_dset.$(OBJEXT) \
- t_file.$(OBJEXT) t_mdset.$(OBJEXT) t_ph5basic.$(OBJEXT) \
- t_coll_chunk.$(OBJEXT) t_span_tree.$(OBJEXT) \
- t_chunk_alloc.$(OBJEXT) t_filter_read.$(OBJEXT)
+ t_file.$(OBJEXT) t_file_image.$(OBJEXT) t_mdset.$(OBJEXT) \
+ t_ph5basic.$(OBJEXT) t_coll_chunk.$(OBJEXT) \
+ t_span_tree.$(OBJEXT) t_chunk_alloc.$(OBJEXT) \
+ t_filter_read.$(OBJEXT)
testphdf5_OBJECTS = $(am_testphdf5_OBJECTS)
testphdf5_LDADD = $(LDADD)
testphdf5_DEPENDENCIES = $(LIBH5TEST) $(LIBHDF5)
@@ -431,8 +432,8 @@ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/test
TEST_PROG_PARA = t_mpi t_posix_compliant testphdf5 t_cache t_pflush1 t_pflush2 t_shapesame
TEST_SCRIPT_PARA = testph5.sh
check_SCRIPTS = $(TEST_SCRIPT)
-testphdf5_SOURCES = testphdf5.c t_dset.c t_file.c t_mdset.c t_ph5basic.c \
- t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
+testphdf5_SOURCES = testphdf5.c t_dset.c t_file.c t_file_image.c t_mdset.c \
+ t_ph5basic.c t_coll_chunk.c t_span_tree.c t_chunk_alloc.c t_filter_read.c
# The tests all depend on the hdf5 library and the test library
@@ -532,6 +533,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_coll_chunk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_dset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_file_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_filter_read.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_mdset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_mpi.Po@am__quote@
diff --git a/testpar/t_file_image.c b/testpar/t_file_image.c
new file mode 100644
index 0000000..544ba32
--- /dev/null
+++ b/testpar/t_file_image.c
@@ -0,0 +1,395 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Parallel tests for file image operations
+ */
+
+#include "testphdf5.h"
+
+/* file_image_daisy_chain_test
+ *
+ * Process zero:
+ *
+ * 1) Creates a core file with an integer vector data set of
+ * length n (= mpi_size),
+ *
+ * 2) Initializes the vector to zero in * location 0, and to -1
+ * everywhere else.
+ *
+ * 3) Flushes the core file, and gets an image of it. Closes
+ * the core file.
+ *
+ * 4) Sends the image to process 1.
+ *
+ * 5) Awaits receipt on a file image from process n-1.
+ *
+ * 6) opens the image received from process n-1, verifies that
+ * it contains a vector of length equal to mpi_size, and
+ * that the vector contains (0, 1, 2, ... n-1)
+ *
+ * 7) closes the core file and exits.
+ *
+ * Process i (0 < i < n)
+ *
+ * 1) Await receipt of file image from process (i - 1).
+ *
+ * 2) Open the image with the core file driver, verify that i
+ * contains a vector v of length, and that v[j] = j for
+ * 0 <= j < i, and that v[j] == -1 for i <= j < n
+ *
+ * 3) Set v[i] = i in the core file.
+ *
+ * 4) Flush the core file and send it to process (i + 1) % n.
+ *
+ * 5) close the core file and exit.
+ *
+ * Test fails on a hang (if an image is not received), or on invalid data.
+ *
+ * JRM -- 11/28/11
+ */
+void
+file_image_daisy_chain_test(void)
+{
+ char file_name[1024] = "\0";
+ int mpi_size, mpi_rank;
+ int mpi_result;
+ int i;
+ int space_ndims;
+ MPI_Status rcvstat;
+ int * vector_ptr = NULL;
+ hid_t fapl_id = -1;
+ hid_t file_id; /* file IDs */
+ hid_t dset_id = -1;
+ hid_t dset_type_id = -1;
+ hid_t space_id = -1;
+ herr_t err;
+ hsize_t dims[1];
+ void * image_ptr = NULL;
+ ssize_t bytes_read;
+ ssize_t image_len;
+ hbool_t vector_ok = TRUE;
+ htri_t tri_result;
+
+
+ /* set up MPI parameters */
+ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+
+ /* setup file name */
+ HDsnprintf(file_name, 1024, "file_image_daisy_chain_test_%05d.h5",
+ (int)mpi_rank);
+
+ if(mpi_rank == 0) {
+
+ /* 1) Creates a core file with an integer vector data set
+ * of length mpi_size,
+ */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VRFY((fapl_id >= 0), "creating fapl");
+
+ err = H5Pset_fapl_core(fapl_id, (size_t)(64 *1024), FALSE);
+ VRFY((err >= 0), "setting core file driver in fapl.");
+
+ file_id = H5Fcreate(file_name, 0, H5P_DEFAULT, fapl_id);
+ VRFY((file_id >= 0), "created core file");
+
+ dims[0] = (hsize_t)mpi_size;
+ space_id = H5Screate_simple(1, dims, dims);
+ VRFY((space_id >= 0), "created data space");
+
+ dset_id = H5Dcreate2(file_id, "v", H5T_NATIVE_INT, space_id,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dset_id >= 0), "created data set");
+
+
+ /* 2) Initialize the vector to zero in location 0, and
+ * to -1 everywhere else.
+ */
+
+ vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
+ VRFY((vector_ptr != NULL), "allocated in memory representation of vector");
+
+ vector_ptr[0] = 0;
+ for(i = 1; i < mpi_size; i++)
+ vector_ptr[i] = -1;
+
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)vector_ptr);
+ VRFY((err >= 0), "wrote initial data to vector.");
+
+ HDfree(vector_ptr);
+ vector_ptr = NULL;
+
+
+ /* 3) Flush the core file, and get an image of it. Close
+ * the core file.
+ */
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VRFY((err >= 0), "flushed core file.");
+
+ image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
+ VRFY((image_len > 0), "got image file size");
+
+ image_ptr = (void *)HDmalloc((size_t)image_len);
+ VRFY(image_ptr != NULL, "allocated file image buffer.");
+
+ bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
+ VRFY(bytes_read == image_len, "wrote file into image buffer");
+
+ err = H5Sclose(space_id);
+ VRFY((err >= 0), "closed data space.");
+
+ err = H5Dclose(dset_id);
+ VRFY((err >= 0), "closed data set.");
+
+ err = H5Fclose(file_id);
+ VRFY((err >= 0), "closed core file(1).");
+
+ err = H5Pclose(fapl_id);
+ VRFY((err >= 0), "closed fapl(1).");
+
+
+ /* 4) Send the image to process 1. */
+
+ mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t),
+ MPI_BYTE, 1, 0, MPI_COMM_WORLD);
+ VRFY((mpi_result == MPI_SUCCESS), "sent image size to process 1");
+
+ mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len,
+ MPI_BYTE, 1, 0, MPI_COMM_WORLD);
+ VRFY((mpi_result == MPI_SUCCESS), "sent image to process 1");
+
+ HDfree(image_ptr);
+ image_ptr = NULL;
+ image_len = 0;
+
+
+ /* 5) Await receipt on a file image from process n-1. */
+
+ mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t),
+ MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD,
+ &rcvstat);
+ VRFY((mpi_result == MPI_SUCCESS), "received image len from process n-1");
+
+ image_ptr = (void *)HDmalloc((size_t)image_len);
+ VRFY(image_ptr != NULL, "allocated file image receive buffer.");
+
+ mpi_result = MPI_Recv((void *)image_ptr, (int)image_len,
+ MPI_BYTE, mpi_size - 1, 0, MPI_COMM_WORLD,
+ &rcvstat);
+ VRFY((mpi_result == MPI_SUCCESS), \
+ "received file image from process n-1");
+
+ /* 6) open the image received from process n-1, verify that
+ * it contains a vector of length equal to mpi_size, and
+ * that the vector contains (0, 1, 2, ... n-1).
+ */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VRFY((fapl_id >= 0), "creating fapl");
+
+ err = H5Pset_fapl_core(fapl_id, (size_t)(64 *1024), FALSE);
+ VRFY((err >= 0), "setting core file driver in fapl.");
+
+ err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
+ VRFY((err >= 0), "set file image in fapl.");
+
+ file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
+ VRFY((file_id >= 0), "opened received file image file");
+
+ dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
+ VRFY((dset_id >= 0), "opened data set");
+
+ dset_type_id = H5Dget_type(dset_id);
+ VRFY((dset_type_id >= 0), "obtained data set type");
+
+ tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
+ VRFY((tri_result == TRUE), "verified data set type");
+
+ space_id = H5Dget_space(dset_id);
+ VRFY((space_id >= 0), "opened data space");
+
+ space_ndims = H5Sget_simple_extent_ndims(space_id);
+ VRFY((space_ndims == 1), "verified data space num dims(1)");
+
+ space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
+ VRFY((space_ndims == 1), "verified data space num dims(2)");
+ VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
+
+ vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
+ VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
+
+ err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)vector_ptr);
+ VRFY((err >= 0), "read received vector.");
+
+ vector_ok = TRUE;
+ for(i = 0; i < mpi_size; i++)
+ if(vector_ptr[i] != i)
+ vector_ok = FALSE;
+ VRFY((vector_ok), "verified received vector.");
+
+ /* 7) closes the core file and exit. */
+
+ err = H5Sclose(space_id);
+ VRFY((err >= 0), "closed data space.");
+
+ err = H5Dclose(dset_id);
+ VRFY((err >= 0), "closed data set.");
+
+ err = H5Fclose(file_id);
+ VRFY((err >= 0), "closed core file(1).");
+
+ err = H5Pclose(fapl_id);
+ VRFY((err >= 0), "closed fapl(1).");
+
+ HDfree(image_ptr);
+ image_ptr = NULL;
+ image_len = 0;
+ } else {
+ /* 1) Await receipt of file image from process (i - 1). */
+
+ mpi_result = MPI_Recv((void *)(&image_len), (int)sizeof(ssize_t),
+ MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD,
+ &rcvstat);
+ VRFY((mpi_result == MPI_SUCCESS), \
+ "received image size from process mpi_rank-1");
+
+ image_ptr = (void *)HDmalloc((size_t)image_len);
+ VRFY(image_ptr != NULL, "allocated file image receive buffer.");
+
+ mpi_result = MPI_Recv((void *)image_ptr, (int)image_len,
+ MPI_BYTE, mpi_rank - 1, 0, MPI_COMM_WORLD,
+ &rcvstat);
+ VRFY((mpi_result == MPI_SUCCESS), \
+ "received file image from process mpi_rank-1");
+
+ /* 2) Open the image with the core file driver, verify that it
+ * contains a vector v of length, and that v[j] = j for
+ * 0 <= j < i, and that v[j] == -1 for i <= j < n
+ */
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ VRFY((fapl_id >= 0), "creating fapl");
+
+ err = H5Pset_fapl_core(fapl_id, (size_t)(64 * 1024), FALSE);
+ VRFY((err >= 0), "setting core file driver in fapl.");
+
+ err = H5Pset_file_image(fapl_id, image_ptr, (size_t)image_len);
+ VRFY((err >= 0), "set file image in fapl.");
+
+ file_id = H5Fopen(file_name, H5F_ACC_RDWR, fapl_id);
+ H5Eprint2(H5P_DEFAULT, stderr);
+ VRFY((file_id >= 0), "opened received file image file");
+
+ dset_id = H5Dopen2(file_id, "v", H5P_DEFAULT);
+ VRFY((dset_id >= 0), "opened data set");
+
+ dset_type_id = H5Dget_type(dset_id);
+ VRFY((dset_type_id >= 0), "obtained data set type");
+
+ tri_result = H5Tequal(dset_type_id, H5T_NATIVE_INT);
+ VRFY((tri_result == TRUE), "verified data set type");
+
+ space_id = H5Dget_space(dset_id);
+ VRFY((space_id >= 0), "opened data space");
+
+ space_ndims = H5Sget_simple_extent_ndims(space_id);
+ VRFY((space_ndims == 1), "verified data space num dims(1)");
+
+ space_ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
+ VRFY((space_ndims == 1), "verified data space num dims(2)");
+ VRFY((dims[0] == (hsize_t)mpi_size), "verified data space dims");
+
+ vector_ptr = (int *)HDmalloc((size_t)(mpi_size) * sizeof(int));
+ VRFY((vector_ptr != NULL), "allocated in memory rep of vector");
+
+ err = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)vector_ptr);
+ VRFY((err >= 0), "read received vector.");
+
+ vector_ok = TRUE;
+ for(i = 0; i < mpi_size; i++){
+ if(i < mpi_rank) {
+ if(vector_ptr[i] != i)
+ vector_ok = FALSE;
+ } else {
+ if(vector_ptr[i] != -1)
+ vector_ok = FALSE;
+ }
+ }
+ VRFY((vector_ok), "verified received vector.");
+
+
+ /* 3) Set v[i] = i in the core file. */
+
+ vector_ptr[mpi_rank] = mpi_rank;
+
+ err = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+ H5P_DEFAULT, (void *)vector_ptr);
+ VRFY((err >= 0), "wrote modified data to vector.");
+
+ HDfree(vector_ptr);
+ vector_ptr = NULL;
+
+
+ /* 4) Flush the core file and send it to process (mpi_rank + 1) % n. */
+
+ err = H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ VRFY((err >= 0), "flushed core file.");
+
+ image_len = H5Fget_file_image(file_id, NULL, (size_t)0);
+ VRFY((image_len > 0), "got (possibly modified) image file len");
+
+ image_ptr = (void *)HDrealloc((void *)image_ptr, (size_t)image_len);
+ VRFY(image_ptr != NULL, "re-allocated file image buffer.");
+
+ bytes_read = H5Fget_file_image(file_id, image_ptr, (size_t)image_len);
+ VRFY(bytes_read == image_len, "wrote file into image buffer");
+
+ mpi_result = MPI_Ssend((void *)(&image_len), (int)sizeof(ssize_t),
+ MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
+ MPI_COMM_WORLD);
+ VRFY((mpi_result == MPI_SUCCESS), \
+ "sent image size to process (mpi_rank + 1) % mpi_size");
+
+ mpi_result = MPI_Ssend((void *)image_ptr, (int)image_len,
+ MPI_BYTE, (mpi_rank + 1) % mpi_size, 0,
+ MPI_COMM_WORLD);
+ VRFY((mpi_result == MPI_SUCCESS), \
+ "sent image to process (mpi_rank + 1) % mpi_size");
+
+ HDfree(image_ptr);
+ image_ptr = NULL;
+ image_len = 0;
+
+ /* 5) close the core file and exit. */
+
+ err = H5Sclose(space_id);
+ VRFY((err >= 0), "closed data space.");
+
+ err = H5Dclose(dset_id);
+ VRFY((err >= 0), "closed data set.");
+
+ err = H5Fclose(file_id);
+ VRFY((err >= 0), "closed core file(1).");
+
+ err = H5Pclose(fapl_id);
+ VRFY((err >= 0), "closed fapl(1).");
+ }
+
+ return;
+
+} /* file_image_daisy_chain_test() */
+
diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c
index 4ec05ca..3a86642 100644
--- a/testpar/testphdf5.c
+++ b/testpar/testphdf5.c
@@ -502,6 +502,13 @@ int main(int argc, char **argv)
"test actual io mode proprerty",
PARATESTFILE);
+ if((mpi_size < 2) && MAINPROCESS) {
+ printf("File Image Ops daisy chain test needs at least 2 processes.\n");
+ printf("File Image Ops daisy chain test will be skipped \n");
+ }
+ AddTest((mpi_size < 2)? "-fiodc" : "fiodc", file_image_daisy_chain_test, NULL,
+ "file image ops daisy chain", NULL);
+
/* Display testing information */
TestInfo(argv[0]);
diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h
index 15ef75f..da11c62 100644
--- a/testpar/testphdf5.h
+++ b/testpar/testphdf5.h
@@ -269,6 +269,7 @@ void lower_dim_size_comp_test(void);
void link_chunk_collective_io_test(void);
void contig_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
void checker_board_hyperslab_dr_pio_test(ShapeSameTestMethods sstest_type);
+void file_image_daisy_chain_test(void);
#ifdef H5_HAVE_FILTER_DEFLATE
void compress_readAll(void);
#endif /* H5_HAVE_FILTER_DEFLATE */
diff --git a/tools/COPYING b/tools/COPYING
index 6903daf..6903daf 100755..100644
--- a/tools/COPYING
+++ b/tools/COPYING
diff --git a/tools/h5diff/CMakeLists.txt b/tools/h5diff/CMakeLists.txt
index dfd1800..da2aaf9 100644
--- a/tools/h5diff/CMakeLists.txt
+++ b/tools/h5diff/CMakeLists.txt
@@ -84,6 +84,8 @@ IF (BUILD_TESTING)
h5diff_220.txt
h5diff_221.txt
h5diff_222.txt
+ h5diff_223.txt
+ h5diff_224.txt
h5diff_21.txt
h5diff_22.txt
h5diff_23.txt
@@ -577,6 +579,10 @@ IF (BUILD_TESTING)
h5diff_221.out.err
h5diff_222.out
h5diff_222.out.err
+ h5diff_223.out
+ h5diff_223.out.err
+ h5diff_224.out
+ h5diff_224.out.err
h5diff_21.out
h5diff_21.out.err
h5diff_22.out
@@ -1164,6 +1170,12 @@ ADD_H5_TEST (h5diff_221 1 -c non_comparables1.h5 non_comparables2.h5 /g2)
# All the rest comparables should display differences
ADD_H5_TEST (h5diff_222 1 -c non_comparables1.h5 non_comparables2.h5)
+# non-comparable test for common objects (same name) with different object types
+# (HDFFV-7644)
+ADD_H5_TEST (h5diff_223 0 -c non_comparables1.h5 non_comparables2.h5 /diffobjtypes)
+# swap files
+ADD_H5_TEST (h5diff_224 0 -c non_comparables2.h5 non_comparables1.h5 /diffobjtypes)
+
# ##############################################################################
# # Links compare without --follow-symlinks nor --no-dangling-links
# ##############################################################################
diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c
index b57c98a..0b8b4cf 100644
--- a/tools/h5diff/h5diffgentest.c
+++ b/tools/h5diff/h5diffgentest.c
@@ -155,7 +155,8 @@ static void test_comps_array (const char *fname, const char *dset, const char *a
static void test_comps_vlen (const char *fname, const char *dset,const char *attr, int diff, int is_file_new);
static void test_comps_array_vlen (const char *fname, const char *dset, const char *attr, int diff, int is_file_new);
static void test_comps_vlen_arry (const char *fname, const char *dset,const char *attr, int diff, int is_file_new);
-static void test_non_comparables (const char *fname, int diff);
+static void test_data_nocomparables (const char *fname, int diff);
+static void test_objs_nocomparables (const char *fname1, const char *fname2);
/* called by test_attributes() and test_datasets() */
static void write_attr_in(hid_t loc_id,const char* dset_name,hid_t fid,int make_diffs);
@@ -250,8 +251,11 @@ int main(void)
* comparable datasets and attributes. All the comparables should display
* differences.
*/
- test_non_comparables(NON_COMPARBLES1,0);
- test_non_comparables(NON_COMPARBLES2,5);
+ test_data_nocomparables(NON_COMPARBLES1,0);
+ test_data_nocomparables(NON_COMPARBLES2,5);
+
+ /* common objects (same name) with different object types. HDFFV-7644 */
+ test_objs_nocomparables(NON_COMPARBLES1, NON_COMPARBLES2);
return 0;
}
@@ -4787,7 +4791,7 @@ static void test_comps_vlen_arry (const char * fname, const char *dset, const ch
/*-------------------------------------------------------------------------
-* Function: test_non_comparables
+* Function: test_data_nocomparables
*
* Purpose:
* Create test files with non-comparable dataset and attributes with
@@ -4796,7 +4800,7 @@ static void test_comps_vlen_arry (const char * fname, const char *dset, const ch
*
*-------------------------------------------------------------------------*/
#define DIM_ARRY 3
-static void test_non_comparables (const char * fname, int make_diffs)
+static void test_data_nocomparables (const char * fname, int make_diffs)
{
hid_t fid=0;
hid_t gid1=0;
@@ -4998,6 +5002,155 @@ out:
}
/*-------------------------------------------------------------------------
+* Function: test_objs_nocomparables
+*
+* Purpose:
+* Create test files with common objects (same name) but different object
+* types.
+* h5diff should show non-comparable output from these common objects.
+*-------------------------------------------------------------------------*/
+static void test_objs_nocomparables(const char *fname1, const char *fname2)
+{
+ herr_t status = SUCCEED;
+ hid_t fid1=0;
+ hid_t fid2=0;
+ hid_t topgid1=0;
+ hid_t topgid2=0;
+ hid_t gid1=0;
+ hid_t did1=0;
+ hid_t tid1=0;
+ hid_t gid2=0;
+ hid_t did2=0;
+ hid_t tid2=0;
+ hsize_t dims[1] = {DIM_ARRY};
+ int data1[DIM_ARRY] = {1,1,1};
+ int data2[DIM_ARRY] = {2,2,2};
+
+ /*-----------------------------------------------------------------------
+ * Open file(s) to add objects
+ *------------------------------------------------------------------------*/
+ /* file1 */
+ fid1 = H5Fopen (fname1, H5F_ACC_RDWR, H5P_DEFAULT);
+ if (fid1 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Fopen failed.\n", fname1);
+ status = FAIL;
+ goto out;
+ }
+
+ /* file2 */
+ fid2 = H5Fopen (fname2, H5F_ACC_RDWR, H5P_DEFAULT);
+ if (fid2 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Fopen failed.\n", fname2);
+ status = FAIL;
+ goto out;
+ }
+
+ /*-----------------------------------------------------------------------
+ * in file1 : add member objects
+ *------------------------------------------------------------------------*/
+ /* parent group */
+ topgid1 = H5Gcreate2(fid1, "diffobjtypes", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (topgid1 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1);
+ status = FAIL;
+ goto out;
+ }
+
+ /* dataset */
+ status = write_dset(topgid1, 1, dims,"obj1", H5T_NATIVE_INT, data1);
+ if (status == FAIL)
+ {
+ fprintf(stderr, "Error: %s> write_dset failed\n", fname1);
+ goto out;
+ }
+
+ /* group */
+ gid1 = H5Gcreate2(topgid1, "obj2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (gid1 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1);
+ status = FAIL;
+ goto out;
+ }
+
+ /* committed type */
+ tid1 = H5Tcopy(H5T_NATIVE_INT);
+ status = H5Tcommit2(topgid1, "obj3", tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (status < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Tcommit2 failed.\n", fname1);
+ goto out;
+ }
+
+ /*-----------------------------------------------------------------------
+ * in file2 : add member objects
+ *------------------------------------------------------------------------*/
+ /* parent group */
+ topgid2 = H5Gcreate2(fid2, "diffobjtypes", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (topgid2 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2);
+ status = FAIL;
+ goto out;
+ }
+
+ /* group */
+ gid2 = H5Gcreate2(topgid2, "obj1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (gid2 < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2);
+ status = FAIL;
+ goto out;
+ }
+
+ /* committed type */
+ tid2 = H5Tcopy(H5T_NATIVE_INT);
+ status = H5Tcommit2(topgid2, "obj2", tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ if (status < 0)
+ {
+ fprintf(stderr, "Error: %s> H5Tcommit2 failed.\n", fname2);
+ goto out;
+ }
+
+ /* dataset */
+ status = write_dset(topgid2, 1, dims,"obj3", H5T_NATIVE_INT, data2);
+ if (status == FAIL)
+ {
+ fprintf(stderr, "Error: %s> write_dset failed\n", fname2);
+ goto out;
+ }
+
+out:
+ /*-----------------------------------------------------------------------
+ * Close IDs
+ *-----------------------------------------------------------------------*/
+ if(fid1)
+ H5Fclose(fid1);
+ if(fid2)
+ H5Fclose(fid2);
+ if(topgid1)
+ H5Gclose(topgid1);
+ if(topgid2)
+ H5Gclose(topgid2);
+ if(did1)
+ H5Dclose(did1);
+ if(did2)
+ H5Dclose(did2);
+ if(gid1)
+ H5Gclose(gid1);
+ if(gid2)
+ H5Gclose(gid2);
+ if(tid1)
+ H5Tclose(tid1);
+ if(tid2)
+ H5Tclose(tid2);
+
+}
+
+/*-------------------------------------------------------------------------
* Function: write_attr_in
*
* Purpose: write attributes in LOC_ID (dataset, group, named datatype)
diff --git a/tools/h5diff/testfiles/h5diff_101w.txt b/tools/h5diff/testfiles/h5diff_101w.txt
index d1f49da..d1f49da 100755..100644
--- a/tools/h5diff/testfiles/h5diff_101w.txt
+++ b/tools/h5diff/testfiles/h5diff_101w.txt
diff --git a/tools/h5diff/testfiles/h5diff_102w.txt b/tools/h5diff/testfiles/h5diff_102w.txt
index dda3581..dda3581 100755..100644
--- a/tools/h5diff/testfiles/h5diff_102w.txt
+++ b/tools/h5diff/testfiles/h5diff_102w.txt
diff --git a/tools/h5diff/testfiles/h5diff_20.txt b/tools/h5diff/testfiles/h5diff_20.txt
index 3edb543..09c20cb 100644
--- a/tools/h5diff/testfiles/h5diff_20.txt
+++ b/tools/h5diff/testfiles/h5diff_20.txt
@@ -1,4 +1,4 @@
-</dset> is of type H5G_DATASET and </g1> is of type H5G_GROUP
+Not comparable: </dset> is of type H5G_DATASET and </g1> is of type H5G_GROUP
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_21.txt b/tools/h5diff/testfiles/h5diff_21.txt
index 1479457..1c625fe 100644
--- a/tools/h5diff/testfiles/h5diff_21.txt
+++ b/tools/h5diff/testfiles/h5diff_21.txt
@@ -1,4 +1,4 @@
-</dset> is of type H5G_DATASET and </l1> is of type H5G_LINK
+Not comparable: </dset> is of type H5G_DATASET and </l1> is of type H5G_LINK
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_22.txt b/tools/h5diff/testfiles/h5diff_22.txt
index 3ccb06b..2ef22d0 100644
--- a/tools/h5diff/testfiles/h5diff_22.txt
+++ b/tools/h5diff/testfiles/h5diff_22.txt
@@ -1,4 +1,4 @@
-</dset> is of type H5G_DATASET and </t1> is of type H5G_TYPE
+Not comparable: </dset> is of type H5G_DATASET and </t1> is of type H5G_TYPE
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_222.txt b/tools/h5diff/testfiles/h5diff_222.txt
index bdecb8a..53c9464 100644
--- a/tools/h5diff/testfiles/h5diff_222.txt
+++ b/tools/h5diff/testfiles/h5diff_222.txt
@@ -1,3 +1,6 @@
+Not comparable: </diffobjtypes/obj1> is of type H5G_DATASET and </diffobjtypes/obj1> is of type H5G_GROUP
+Not comparable: </diffobjtypes/obj2> is of type H5G_GROUP and </diffobjtypes/obj2> is of type H5G_TYPE
+Not comparable: </diffobjtypes/obj3> is of type H5G_TYPE and </diffobjtypes/obj3> is of type H5G_DATASET
Not comparable: </g1/dset1> is of class H5T_INTEGER and </g1/dset1> is of class H5T_STRING
attribute: <attr of </g1/dset1>> and <attr of </g1/dset1>>
3 differences found
diff --git a/tools/h5diff/testfiles/h5diff_223.txt b/tools/h5diff/testfiles/h5diff_223.txt
new file mode 100644
index 0000000..c8e0f65
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_223.txt
@@ -0,0 +1,4 @@
+Not comparable: </diffobjtypes/obj1> is of type H5G_DATASET and </diffobjtypes/obj1> is of type H5G_GROUP
+Not comparable: </diffobjtypes/obj2> is of type H5G_GROUP and </diffobjtypes/obj2> is of type H5G_TYPE
+Not comparable: </diffobjtypes/obj3> is of type H5G_TYPE and </diffobjtypes/obj3> is of type H5G_DATASET
+EXIT CODE: 0
diff --git a/tools/h5diff/testfiles/h5diff_224.txt b/tools/h5diff/testfiles/h5diff_224.txt
new file mode 100644
index 0000000..a4ebedb
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_224.txt
@@ -0,0 +1,4 @@
+Not comparable: </diffobjtypes/obj1> is of type H5G_GROUP and </diffobjtypes/obj1> is of type H5G_DATASET
+Not comparable: </diffobjtypes/obj2> is of type H5G_TYPE and </diffobjtypes/obj2> is of type H5G_GROUP
+Not comparable: </diffobjtypes/obj3> is of type H5G_DATASET and </diffobjtypes/obj3> is of type H5G_TYPE
+EXIT CODE: 0
diff --git a/tools/h5diff/testfiles/h5diff_300.txt b/tools/h5diff/testfiles/h5diff_300.txt
index e51643f..e51643f 100755..100644
--- a/tools/h5diff/testfiles/h5diff_300.txt
+++ b/tools/h5diff/testfiles/h5diff_300.txt
diff --git a/tools/h5diff/testfiles/h5diff_505.txt b/tools/h5diff/testfiles/h5diff_505.txt
index a220730..607b99b 100644
--- a/tools/h5diff/testfiles/h5diff_505.txt
+++ b/tools/h5diff/testfiles/h5diff_505.txt
@@ -1,4 +1,4 @@
-</grp1> is of type H5G_GROUP and </slink_grp1> is of type H5G_LINK
+Not comparable: </grp1> is of type H5G_GROUP and </slink_grp1> is of type H5G_LINK
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_507.txt b/tools/h5diff/testfiles/h5diff_507.txt
index 6176f3f..06b7fe6 100644
--- a/tools/h5diff/testfiles/h5diff_507.txt
+++ b/tools/h5diff/testfiles/h5diff_507.txt
@@ -1,4 +1,4 @@
-</grp1> is of type H5G_GROUP and </elink_grp1> is of type H5G_UDLINK
+Not comparable: </grp1> is of type H5G_GROUP and </elink_grp1> is of type H5G_UDLINK
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_509.txt b/tools/h5diff/testfiles/h5diff_509.txt
index a51ab35..2e3e87a 100644
--- a/tools/h5diff/testfiles/h5diff_509.txt
+++ b/tools/h5diff/testfiles/h5diff_509.txt
@@ -1,4 +1,4 @@
-</slink_grp1> is of type H5G_LINK and </elink_grp1> is of type H5G_UDLINK
+Not comparable: </slink_grp1> is of type H5G_LINK and </elink_grp1> is of type H5G_UDLINK
--------------------------------
Some objects are not comparable
--------------------------------
diff --git a/tools/h5diff/testfiles/h5diff_515.txt b/tools/h5diff/testfiles/h5diff_515.txt
index 077d463..263441d 100644
--- a/tools/h5diff/testfiles/h5diff_515.txt
+++ b/tools/h5diff/testfiles/h5diff_515.txt
@@ -17,8 +17,11 @@ dataset: </dset1> and </dset1>
0 differences found
group : </g1> and </g1>
0 differences found
-group : </g1/g2> and </g1/g2>
-0 differences found
+Not comparable: </g1/g2> is of type H5G_GROUP and </g1/g2> is of type H5G_UDLINK
link : </soft_dset1> and </soft_dset1>
0 differences found
+--------------------------------
+Some objects are not comparable
+--------------------------------
+Use -c for a list of objects without details of differences.
EXIT CODE: 1
diff --git a/tools/h5diff/testfiles/h5diff_517.txt b/tools/h5diff/testfiles/h5diff_517.txt
index 1b6e24f..91c69fb 100644
--- a/tools/h5diff/testfiles/h5diff_517.txt
+++ b/tools/h5diff/testfiles/h5diff_517.txt
@@ -10,6 +10,9 @@ group1 group2
group : </g1> and </g1>
0 differences found
-group : </g1/g2> and </g1/g2>
-0 differences found
+Not comparable: </g1/g2> is of type H5G_GROUP and </g1/g2> is of type H5G_UDLINK
+--------------------------------
+Some objects are not comparable
+--------------------------------
+Use -c for a list of objects without details of differences.
EXIT CODE: 1
diff --git a/tools/h5diff/testfiles/h5diff_enum_invalid_values.h5 b/tools/h5diff/testfiles/h5diff_enum_invalid_values.h5
index dd02db9..dd02db9 100755..100644
--- a/tools/h5diff/testfiles/h5diff_enum_invalid_values.h5
+++ b/tools/h5diff/testfiles/h5diff_enum_invalid_values.h5
Binary files differ
diff --git a/tools/h5diff/testfiles/h5diff_links.h5 b/tools/h5diff/testfiles/h5diff_links.h5
index 8af66a6..8af66a6 100755..100644
--- a/tools/h5diff/testfiles/h5diff_links.h5
+++ b/tools/h5diff/testfiles/h5diff_links.h5
Binary files differ
diff --git a/tools/h5diff/testfiles/non_comparables1.h5 b/tools/h5diff/testfiles/non_comparables1.h5
index 71b65c8..7dbb45d 100644
--- a/tools/h5diff/testfiles/non_comparables1.h5
+++ b/tools/h5diff/testfiles/non_comparables1.h5
Binary files differ
diff --git a/tools/h5diff/testfiles/non_comparables2.h5 b/tools/h5diff/testfiles/non_comparables2.h5
index 188ceb9..a5e7014 100644
--- a/tools/h5diff/testfiles/non_comparables2.h5
+++ b/tools/h5diff/testfiles/non_comparables2.h5
Binary files differ
diff --git a/tools/h5diff/testh5diff.sh b/tools/h5diff/testh5diff.sh
index 27fb253..dfea6f7 100755
--- a/tools/h5diff/testh5diff.sh
+++ b/tools/h5diff/testh5diff.sh
@@ -156,6 +156,8 @@ $SRC_H5DIFF_TESTFILES/h5diff_208.txt
$SRC_H5DIFF_TESTFILES/h5diff_220.txt
$SRC_H5DIFF_TESTFILES/h5diff_221.txt
$SRC_H5DIFF_TESTFILES/h5diff_222.txt
+$SRC_H5DIFF_TESTFILES/h5diff_223.txt
+$SRC_H5DIFF_TESTFILES/h5diff_224.txt
$SRC_H5DIFF_TESTFILES/h5diff_21.txt
$SRC_H5DIFF_TESTFILES/h5diff_22.txt
$SRC_H5DIFF_TESTFILES/h5diff_23.txt
@@ -212,6 +214,9 @@ $SRC_H5DIFF_TESTFILES/h5diff_481.txt
$SRC_H5DIFF_TESTFILES/h5diff_482.txt
$SRC_H5DIFF_TESTFILES/h5diff_483.txt
$SRC_H5DIFF_TESTFILES/h5diff_484.txt
+$SRC_H5DIFF_TESTFILES/h5diff_485.txt
+$SRC_H5DIFF_TESTFILES/h5diff_486.txt
+$SRC_H5DIFF_TESTFILES/h5diff_487.txt
$SRC_H5DIFF_TESTFILES/h5diff_50.txt
$SRC_H5DIFF_TESTFILES/h5diff_51.txt
$SRC_H5DIFF_TESTFILES/h5diff_52.txt
@@ -824,6 +829,12 @@ if test -n "$pmode" -a "$mydomainname" = hdfgroup.uiuc.edu; then
else
TOOLTEST h5diff_222.txt -c non_comparables1.h5 non_comparables2.h5
fi
+
+# non-comparable test for common objects (same name) with different object types
+# (HDFFV-7644)
+TOOLTEST h5diff_223.txt -c non_comparables1.h5 non_comparables2.h5 /diffobjtypes
+# swap files
+TOOLTEST h5diff_224.txt -c non_comparables2.h5 non_comparables1.h5 /diffobjtypes
# ##############################################################################
# # Links compare without --follow-symlinks nor --no-dangling-links
diff --git a/tools/h5dump/testh5dumpxml.sh.in b/tools/h5dump/testh5dumpxml.sh.in
index 1bbf232..1bbf232 100755..100644
--- a/tools/h5dump/testh5dumpxml.sh.in
+++ b/tools/h5dump/testh5dumpxml.sh.in
diff --git a/tools/h5import/Makefile.in b/tools/h5import/Makefile.in
index b2a90ff..b2a90ff 100755..100644
--- a/tools/h5import/Makefile.in
+++ b/tools/h5import/Makefile.in
diff --git a/tools/h5import/h5import.c b/tools/h5import/h5import.c
index 56dc5ab..56dc5ab 100755..100644
--- a/tools/h5import/h5import.c
+++ b/tools/h5import/h5import.c
diff --git a/tools/h5import/h5import.h b/tools/h5import/h5import.h
index dbc6844..dbc6844 100755..100644
--- a/tools/h5import/h5import.h
+++ b/tools/h5import/h5import.h
diff --git a/tools/h5import/h5importtest.c b/tools/h5import/h5importtest.c
index 434cba7..434cba7 100755..100644
--- a/tools/h5import/h5importtest.c
+++ b/tools/h5import/h5importtest.c
diff --git a/tools/h5import/testfiles/binfp64.conf b/tools/h5import/testfiles/binfp64.conf
index 6b4c361..6b4c361 100755..100644
--- a/tools/h5import/testfiles/binfp64.conf
+++ b/tools/h5import/testfiles/binfp64.conf
diff --git a/tools/h5import/testfiles/binin16.conf b/tools/h5import/testfiles/binin16.conf
index 06869cb..06869cb 100755..100644
--- a/tools/h5import/testfiles/binin16.conf
+++ b/tools/h5import/testfiles/binin16.conf
diff --git a/tools/h5import/testfiles/binin32.conf b/tools/h5import/testfiles/binin32.conf
index 11996ef..11996ef 100755..100644
--- a/tools/h5import/testfiles/binin32.conf
+++ b/tools/h5import/testfiles/binin32.conf
diff --git a/tools/h5import/testfiles/binin8.conf b/tools/h5import/testfiles/binin8.conf
index 1edd80a..1edd80a 100755..100644
--- a/tools/h5import/testfiles/binin8.conf
+++ b/tools/h5import/testfiles/binin8.conf
diff --git a/tools/h5import/testfiles/binuin16.conf b/tools/h5import/testfiles/binuin16.conf
index a4603df..a4603df 100755..100644
--- a/tools/h5import/testfiles/binuin16.conf
+++ b/tools/h5import/testfiles/binuin16.conf
diff --git a/tools/h5import/testfiles/binuin32.conf b/tools/h5import/testfiles/binuin32.conf
index a649e97..a649e97 100755..100644
--- a/tools/h5import/testfiles/binuin32.conf
+++ b/tools/h5import/testfiles/binuin32.conf
diff --git a/tools/h5import/testfiles/txtfp32.conf b/tools/h5import/testfiles/txtfp32.conf
index 9696a7f..9696a7f 100755..100644
--- a/tools/h5import/testfiles/txtfp32.conf
+++ b/tools/h5import/testfiles/txtfp32.conf
diff --git a/tools/h5import/testfiles/txtfp32.txt b/tools/h5import/testfiles/txtfp32.txt
index 142c94f..142c94f 100755..100644
--- a/tools/h5import/testfiles/txtfp32.txt
+++ b/tools/h5import/testfiles/txtfp32.txt
diff --git a/tools/h5import/testfiles/txtfp64.conf b/tools/h5import/testfiles/txtfp64.conf
index fbab6a6..fbab6a6 100755..100644
--- a/tools/h5import/testfiles/txtfp64.conf
+++ b/tools/h5import/testfiles/txtfp64.conf
diff --git a/tools/h5import/testfiles/txtfp64.txt b/tools/h5import/testfiles/txtfp64.txt
index 6c83dc3..6c83dc3 100755..100644
--- a/tools/h5import/testfiles/txtfp64.txt
+++ b/tools/h5import/testfiles/txtfp64.txt
diff --git a/tools/h5import/testfiles/txtin16.conf b/tools/h5import/testfiles/txtin16.conf
index d2d11c3..d2d11c3 100755..100644
--- a/tools/h5import/testfiles/txtin16.conf
+++ b/tools/h5import/testfiles/txtin16.conf
diff --git a/tools/h5import/testfiles/txtin32.conf b/tools/h5import/testfiles/txtin32.conf
index ca4802a..ca4802a 100755..100644
--- a/tools/h5import/testfiles/txtin32.conf
+++ b/tools/h5import/testfiles/txtin32.conf
diff --git a/tools/h5import/testfiles/txtin8.conf b/tools/h5import/testfiles/txtin8.conf
index 9dbfd2b..9dbfd2b 100755..100644
--- a/tools/h5import/testfiles/txtin8.conf
+++ b/tools/h5import/testfiles/txtin8.conf
diff --git a/tools/h5import/testfiles/txtuin16.conf b/tools/h5import/testfiles/txtuin16.conf
index 753e6e8..753e6e8 100755..100644
--- a/tools/h5import/testfiles/txtuin16.conf
+++ b/tools/h5import/testfiles/txtuin16.conf
diff --git a/tools/h5import/testfiles/txtuin32.conf b/tools/h5import/testfiles/txtuin32.conf
index d61e1a1..d61e1a1 100755..100644
--- a/tools/h5import/testfiles/txtuin32.conf
+++ b/tools/h5import/testfiles/txtuin32.conf
diff --git a/tools/h5import/testfiles/txtuin32.txt b/tools/h5import/testfiles/txtuin32.txt
index 0688e9b..0688e9b 100755..100644
--- a/tools/h5import/testfiles/txtuin32.txt
+++ b/tools/h5import/testfiles/txtuin32.txt
diff --git a/tools/h5jam/testfiles/u10.txt b/tools/h5jam/testfiles/u10.txt
index c76a964..c76a964 100755..100644
--- a/tools/h5jam/testfiles/u10.txt
+++ b/tools/h5jam/testfiles/u10.txt
diff --git a/tools/h5jam/testfiles/u511.txt b/tools/h5jam/testfiles/u511.txt
index bff1736..bff1736 100755..100644
--- a/tools/h5jam/testfiles/u511.txt
+++ b/tools/h5jam/testfiles/u511.txt
diff --git a/tools/h5jam/testfiles/u512.txt b/tools/h5jam/testfiles/u512.txt
index 33a36c9..33a36c9 100755..100644
--- a/tools/h5jam/testfiles/u512.txt
+++ b/tools/h5jam/testfiles/u512.txt
diff --git a/tools/h5jam/testfiles/u513.txt b/tools/h5jam/testfiles/u513.txt
index 6b46ebf..6b46ebf 100755..100644
--- a/tools/h5jam/testfiles/u513.txt
+++ b/tools/h5jam/testfiles/u513.txt
diff --git a/tools/h5repack/CMakeLists.txt b/tools/h5repack/CMakeLists.txt
index 6460375..ae7a658 100644
--- a/tools/h5repack/CMakeLists.txt
+++ b/tools/h5repack/CMakeLists.txt
@@ -145,6 +145,31 @@ IF (BUILD_TESTING)
##############################################################################
##############################################################################
+ MACRO (ADD_H5_TEST_OLD testname testtype testfile)
+ IF (${testtype} STREQUAL "SKIP")
+ IF (NOT HDF5_ENABLE_USING_MEMCHECKER)
+ ADD_TEST (
+ NAME H5REPACK-${testname}-SKIPPED
+ COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${ARGN} -i ${PROJECT_BINARY_DIR}/testfiles/${testfile} -o ${PROJECT_BINARY_DIR}/testfiles/out.${testfile}"
+ )
+ ENDIF (NOT HDF5_ENABLE_USING_MEMCHECKER)
+ ELSE (${testtype} STREQUAL "SKIP")
+ ADD_TEST (
+ NAME H5REPACK-${testname}
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} -i ${PROJECT_BINARY_DIR}/testfiles/${testfile} -o ${PROJECT_BINARY_DIR}/testfiles/out.${testfile}
+ )
+ IF (NOT "${last_test}" STREQUAL "")
+ SET_TESTS_PROPERTIES (H5REPACK-${testname} PROPERTIES DEPENDS ${last_test})
+ ENDIF (NOT "${last_test}" STREQUAL "")
+ ADD_TEST (
+ NAME H5REPACK-DIFF_${testname}
+ COMMAND $<TARGET_FILE:h5diff> ${PROJECT_BINARY_DIR}/testfiles/${testfile} ${PROJECT_BINARY_DIR}/testfiles/out.${testfile}
+ )
+ SET_TESTS_PROPERTIES (H5REPACK-DIFF_${testname} PROPERTIES DEPENDS H5REPACK-${testname})
+ SET (last_test "H5REPACK-DIFF_${testname}")
+ ENDIF (${testtype} STREQUAL "SKIP")
+ ENDMACRO (ADD_H5_TEST_OLD)
+
MACRO (ADD_H5_TEST testname testtype testfile)
IF (${testtype} STREQUAL "SKIP")
IF (NOT HDF5_ENABLE_USING_MEMCHECKER)
@@ -261,6 +286,29 @@ IF (BUILD_TESTING)
ENDIF (${testtype} STREQUAL "SKIP")
ENDMACRO (ADD_H5_VERIFY_TEST)
+ MACRO (ADD_H5_TEST_META testname testfile)
+ ADD_TEST (
+ NAME H5REPACK-${testname}_N
+ COMMAND $<TARGET_FILE:h5repack> ${PROJECT_BINARY_DIR}/testfiles/${testfile} ${PROJECT_BINARY_DIR}/testfiles/out_N.${testname}.h5
+ )
+ IF (NOT "${last_test}" STREQUAL "")
+ SET_TESTS_PROPERTIES (H5REPACK-${testname}_N PROPERTIES DEPENDS ${last_test})
+ ENDIF (NOT "${last_test}" STREQUAL "")
+ ADD_TEST (
+ NAME H5REPACK-${testname}_M
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${testfile} ${PROJECT_BINARY_DIR}/testfiles/out_M.${testname}.h5
+ )
+ IF (NOT "${last_test}" STREQUAL "")
+ SET_TESTS_PROPERTIES (H5REPACK-${testname}_M PROPERTIES DEPENDS ${last_test})
+ ENDIF (NOT "${last_test}" STREQUAL "")
+ ADD_TEST (NAME H5REPACK-${testname} COMMAND ${CMAKE_COMMAND} -E compare_files ${PROJECT_BINARY_DIR}/testfiles/out_N.${testname}.h5 ${PROJECT_BINARY_DIR}/testfiles/out_M.${testname}.h5)
+ SET_TESTS_PROPERTIES (H5REPACK-${testname} PROPERTIES WILL_FAIL "true")
+ IF (NOT "${last_test}" STREQUAL "")
+ SET_TESTS_PROPERTIES (H5REPACK-${testname} PROPERTIES DEPENDS ${last_test})
+ ENDIF (NOT "${last_test}" STREQUAL "")
+ SET (last_test "H5REPACK-${testname}")
+ ENDMACRO (ADD_H5_TEST_META)
+
##############################################################################
##############################################################################
### T H E T E S T S ###
@@ -278,8 +326,10 @@ IF (BUILD_TESTING)
./testfiles/h5repack_layout2.h5-v.out.err
./testfiles/h5repack_layout.h5-v.out
./testfiles/h5repack_layout.h5-v.out.err
+ ./testfiles/out.tfamily%05d.h5
./testfiles/out.h5diff_attr1.h5
./testfiles/out.h5repack_attr.h5
+ ./testfiles/out.h5repack_attr_refs.h5
./testfiles/out.h5repack_deflate.h5
./testfiles/out.h5repack_early.h5
./testfiles/out.h5repack_fill.h5
@@ -295,6 +345,10 @@ IF (BUILD_TESTING)
./testfiles/out.h5repack_refs.h5
./testfiles/out.h5repack_shuffle.h5
./testfiles/out.h5repack_soffset.h5
+ ./testfiles/out_M.meta_short.h5
+ ./testfiles/out_N.meta_short.h5
+ ./testfiles/out_M.meta_long.h5
+ ./testfiles/out_N.meta_long.h5
# from the h5repacktst
h5repack_attr.h5
h5repack_attr_out.h5
@@ -762,7 +816,7 @@ IF (BUILD_TESTING)
IF (NOT USE_FILTER_DEFLATE)
SET (TESTTYPE "SKIP")
ENDIF (NOT USE_FILTER_DEFLATE)
-# ADD_H5_TEST (old_style_layout_short_switches ${TESTTYPE} ${arg})
+ ADD_H5_TEST_OLD (old_style_layout_short_switches ${TESTTYPE} ${arg})
# add a userblock to file
SET (arg ${FILE1} -u ${PROJECT_BINARY_DIR}/testfiles/ublock.bin -b 2048)
@@ -783,16 +837,14 @@ IF (BUILD_TESTING)
ADD_H5_TEST (committed_dt "TEST" ${FILE15})
# tests family driver (file is located in common testfiles folder, uses TOOLTEST1
-# ADD_H5_TEST ( family "FAMILY" ${FILE16})
+ ADD_H5_TEST (family "TEST" ${FILE16})
# test various references (bug 1814 and 1726)
ADD_H5_TEST (bug1814 "TEST" ${FILE_REF})
-# test attribute with various references in attribute of compund
-# or vlen datatype
-# (HDFFV-2605, 7513)
-# TODO: include this test when code portion is completed.
- ADD_H5_TEST (HDFFV-2605 "SKIP" ${FILE_ATTR_REF})
+# test attribute with various references (bug1797 / HDFFV-5932)
+# the references in attribute of compund or vlen datatype
+ ADD_H5_TEST (HDFFV-5932 "TEST" ${FILE_ATTR_REF})
# Add test for memory leak in attirbute. This test is verified by CTEST.
# 1. leak from vlen string
@@ -801,6 +853,10 @@ IF (BUILD_TESTING)
# Note: this test is experimental for sharing test file among tools
ADD_H5_TEST (HDFFV-7840 "TEST" h5diff_attr1.h5)
+# tests for metadata block size option ('-M')
+ ADD_H5_TEST_META (meta_short h5repack_layout.h5 -M 8192)
+ ADD_H5_TEST_META (meta_long h5repack_layout.h5 --metadata_block_size=8192)
+
IF (HDF5_TEST_VFD)
# Run test with different Virtual File Driver
FOREACH (vfd ${VFD_LIST})
diff --git a/tools/h5repack/h5repack.c b/tools/h5repack/h5repack.c
index 28d66c5..9778fdd 100644
--- a/tools/h5repack/h5repack.c
+++ b/tools/h5repack/h5repack.c
@@ -87,10 +87,12 @@ int h5repack(const char* infile,
*/
int
-h5repack_init(pack_opt_t *options, int verbose, H5F_file_space_type_t strategy, hsize_t threshold)
+h5repack_init(pack_opt_t *options, int verbose, H5F_file_space_type_t strategy,
+ hsize_t threshold)
{
int k, n;
- HDmemset(options,0,sizeof(pack_opt_t));
+
+ HDmemset(options, 0, sizeof(pack_opt_t));
options->min_comp = 1024;
options->verbose = verbose;
diff --git a/tools/h5repack/h5repack.h b/tools/h5repack/h5repack.h
index 6415d3a..3907178 100644
--- a/tools/h5repack/h5repack.h
+++ b/tools/h5repack/h5repack.h
@@ -111,6 +111,7 @@ typedef struct {
datatype, fill value, filter pipleline, attribute */
const char *ublock_filename; /* user block file name */
hsize_t ublock_size; /* user block size */
+ hsize_t meta_block_size; /* metadata aggregation block size (for H5Pset_meta_block_size) */
hsize_t threshold; /* alignment threshold for H5Pset_alignment */
hsize_t alignment ; /* alignment for H5Pset_alignment */
H5F_file_space_type_t fs_strategy; /* File space handling strategy */
diff --git a/tools/h5repack/h5repack.sh.in b/tools/h5repack/h5repack.sh.in
index c1cbba1..236c555 100755..100644
--- a/tools/h5repack/h5repack.sh.in
+++ b/tools/h5repack/h5repack.sh.in
@@ -147,20 +147,25 @@ COPY_TESTFILES_TO_TESTDIR()
done
}
+# Print a $* message left justified in a field of 70 characters
+#
+MESSAGE() {
+ SPACES=" "
+ echo "$* $SPACES" | cut -c1-70 | tr -d '\012'
+}
+
# Print a line-line message left justified in a field of 70 characters
# beginning with the word "Testing".
#
TESTING() {
- SPACES=" "
- echo "Testing $* $SPACES" | cut -c1-70 | tr -d '\012'
+ MESSAGE "Testing $*"
}
# Print a line-line message left justified in a field of 70 characters
# beginning with the word "Verifying".
#
VERIFY() {
- SPACES=" "
- echo "Verifying h5diff output $* $SPACES" | cut -c1-70 | tr -d '\012'
+ MESSAGE "Verifying h5diff output $*"
}
# Print a message that a test has been skipped (because a required filter
@@ -385,6 +390,49 @@ TOOLTESTV()
rm -f $actual $actual_err $actual_sav
}
+# TOOLTEST_META:
+# Test metadata block size option.
+# Reason to create a function here is to localize all special steps related to
+# metadata block size option in one place. This is a quick solution. More
+# thought out solution needed when there is more time.
+#
+# $1: test input file
+# $2:$: metadata options (either "-M size" or "--metadata_block_size=size")
+#
+# Algorithm:
+# Run it once without the metadata option ($2-$);
+# Save the result output file;
+# Run it second time with the metadata option;
+# Verify the output file of second run is larger than the one of 1st run.
+TOOLTEST_META()
+{
+ input_file=$1
+ outfile="$TESTDIR/out.$1"
+
+ # Use TOOLTEST_MAIN to run because it does not remove the output file.
+ # 1st run, without metadata option
+ TOOLTEST_MAIN $1
+ # get the size of the first output file
+ size1=`wc -c $outfile | cut -d' ' -f1`
+
+ # 2nd run with metadata option
+ TOOLTEST_MAIN $*
+ # get the size of the second output file
+ size2=`wc -c $outfile | cut -d' ' -f1`
+
+ # verify sizes.
+ MESSAGE "Verify the sizes of both output files ($size1 vs $size2)"
+ if [ $size1 -lt $size2 ]; then
+ # pass
+ echo " PASSED"
+ else
+ #fail
+ echo "*FAILED*"
+ fi
+
+ rm -f $outfile
+}
+
# This is different from $srcdir/../../bin/output_filter.sh
STDOUT_FILTER() {
result_file=$1
@@ -801,7 +849,6 @@ TOOLTEST h5repack_refs.h5
# the references in attribute of compund or vlen datatype
TOOLTEST h5repack_attr_refs.h5
-
# Add test for memory leak in attirbute. This test is verified by CTEST.
# 1. leak from vlen string
# 2. leak from compound type without reference member
@@ -809,6 +856,10 @@ TOOLTEST h5repack_attr_refs.h5
# Note: this test is experimental for sharing test file among tools
TOOLTEST h5diff_attr1.h5
+# tests for metadata block size option ('-M')
+TOOLTEST_META h5repack_layout.h5 -M 8192
+TOOLTEST_META h5repack_layout.h5 --metadata_block_size=8192
+
if test $nerrors -eq 0 ; then
echo "All $TESTNAME tests passed."
exit $EXIT_SUCCESS
diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c
index 55cf932..d38a15c 100644
--- a/tools/h5repack/h5repack_copy.c
+++ b/tools/h5repack/h5repack_copy.c
@@ -42,7 +42,7 @@
int _err_num = 0; \
char _msg[80]; \
H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, walk_error_callback, &_err_num); \
- H5Eget_msg(_err_num, NULL, _msg, 80); \
+ H5Eget_msg(_err_num, NULL, _msg, (size_t)80); \
error_msg("%s %s -- %s\n", #_fun, "failed", _msg); \
goto error; \
} \
@@ -132,23 +132,23 @@ int copy_objects(const char* fnamein,
goto out;
}
- if(!options->fs_strategy)
- {
- if(H5Pget_file_space(fcpl_in, &options->fs_strategy, NULL) < 0)
- {
- error_msg("failed to retrieve file space strategy\n");
- goto out;
- }
- }
-
- if(!options->fs_threshold)
- {
- if(H5Pget_file_space(fcpl_in, NULL, &options->fs_threshold) < 0)
- {
- error_msg("failed to retrieve file space threshold\n");
- goto out;
- }
- }
+ if(!options->fs_strategy)
+ {
+ if(H5Pget_file_space(fcpl_in, &options->fs_strategy, NULL) < 0)
+ {
+ error_msg("failed to retrieve file space strategy\n");
+ goto out;
+ }
+ }
+
+ if(!options->fs_threshold)
+ {
+ if(H5Pget_file_space(fcpl_in, NULL, &options->fs_threshold) < 0)
+ {
+ error_msg("failed to retrieve file space threshold\n");
+ goto out;
+ }
+ }
if(H5Pclose(fcpl_in) < 0)
{
@@ -254,135 +254,113 @@ int copy_objects(const char* fnamein,
} /* end if */
} /* end if */
} /* end if */
-
-
-
-
#if defined (H5REPACK_DEBUG_USER_BLOCK)
- print_user_block(fnamein,fidin);
+ print_user_block(fnamein, fidin);
#endif
-
/*-------------------------------------------------------------------------
* set the new user userblock options in the FCPL (before H5Fcreate )
*-------------------------------------------------------------------------
*/
-
if ( options->ublock_size > 0 )
{
/* either use the FCPL already created or create a new one */
- if(fcpl != H5P_DEFAULT)
+ if(fcpl == H5P_DEFAULT)
{
- /* set user block size */
- if(H5Pset_userblock(fcpl, options->ublock_size) < 0)
- {
- error_msg("failed to set userblock size\n");
- goto out;
- }
-
- }
-
- else
- {
-
/* create a file creation property list */
if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
{
error_msg("fail to create a file creation property list\n");
goto out;
}
-
- /* set user block size */
- if(H5Pset_userblock(fcpl, options->ublock_size) < 0)
- {
- error_msg("failed to set userblock size\n");
- goto out;
- }
-
}
-
-
+ /* set user block size */
+ if(H5Pset_userblock(fcpl, options->ublock_size) < 0)
+ {
+ error_msg("failed to set userblock size\n");
+ goto out;
+ }
}
-
/*-------------------------------------------------------------------------
* set alignment options
*-------------------------------------------------------------------------
*/
-
-
if ( options->alignment > 0 )
{
/* either use the FAPL already created or create a new one */
- if (fapl != H5P_DEFAULT)
+ if (fapl == H5P_DEFAULT)
{
-
- if (H5Pset_alignment(fapl, options->threshold, options->alignment) < 0)
+ /* create a file access property list */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
{
- error_msg("failed to set alignment\n");
+ error_msg("Could not create file access property list\n");
goto out;
}
-
}
- else
+ if (H5Pset_alignment(fapl, options->threshold, options->alignment) < 0)
{
+ error_msg("failed to set alignment\n");
+ goto out;
+ }
+ }
+ /*-------------------------------------------------------------------------
+ * set metadata block size option
+ *-------------------------------------------------------------------------
+ */
+ if ( options->meta_block_size > 0 )
+ {
+ /* either use the FAPL already created or create a new one */
+ if (fapl == H5P_DEFAULT)
+ {
/* create a file access property list */
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
{
error_msg("Could not create file access property list\n");
goto out;
}
-
- if (H5Pset_alignment(fapl, options->threshold, options->alignment) < 0)
- {
- error_msg("failed to set alignment\n");
- goto out;
- }
-
}
+ if (H5Pset_meta_block_size(fapl, options->meta_block_size) < 0)
+ {
+ error_msg("failed to set metadata block size\n");
+ goto out;
+ }
}
+ /*-------------------------------------------------------------------------
+ * set free-space strategy options
+ *-------------------------------------------------------------------------
+ */
+
/* either use the FCPL already created or create a new one */
- if(fcpl != H5P_DEFAULT)
+ if(fcpl == H5P_DEFAULT)
{
- /* set file space strategy and free space threshold */
- if(H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0)
- {
- error_msg("failed to set file space strategy & threshold\n");
- goto out;
- }
+ /* create a file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ {
+ error_msg("fail to create a file creation property list\n");
+ goto out;
+ }
}
- else
+
+ /* set file space strategy and free space threshold */
+ if(H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0)
{
- /* create a file creation property list */
- if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
- {
- error_msg("fail to create a file creation property list\n");
- goto out;
- }
-
- /* set file space strategy and free space threshold */
- if(H5Pset_file_space(fcpl, options->fs_strategy, options->fs_threshold) < 0)
- {
- error_msg("failed to set file space strategy & threshold \n");
- goto out;
- }
+ error_msg("failed to set file space strategy & threshold \n");
+ goto out;
}
/*-------------------------------------------------------------------------
* create the output file
*-------------------------------------------------------------------------
*/
-
-
if(options->verbose)
printf("Making file <%s>...\n",fnameout);
-
if((fidout = H5Fcreate(fnameout,H5F_ACC_TRUNC, fcpl, fapl)) < 0)
{
error_msg("<%s>: Could not create file\n", fnameout );
diff --git a/tools/h5repack/h5repack_main.c b/tools/h5repack/h5repack_main.c
index e1697ab..6004084 100644
--- a/tools/h5repack/h5repack_main.c
+++ b/tools/h5repack/h5repack_main.c
@@ -35,7 +35,7 @@ const char *outfile = NULL;
* Command-line options: The user can specify short or long-named
* parameters.
*/
-static const char *s_opts = "hVvf:l:m:e:nLc:d:s:u:b:t:a:i:o:S:T:";
+static const char *s_opts = "hVvf:l:m:e:nLc:d:s:u:b:M:t:a:i:o:S:T:";
static struct long_options l_opts[] = {
{ "help", no_arg, 'h' },
{ "version", no_arg, 'V' },
@@ -51,6 +51,7 @@ static struct long_options l_opts[] = {
{ "ssize", require_arg, 's' },
{ "ublock", require_arg, 'u' },
{ "block", require_arg, 'b' },
+ { "metadata_block_size", require_arg, 'M' },
{ "threshold", require_arg, 't' },
{ "alignment", require_arg, 'a' },
{ "infile", require_arg, 'i' }, /* -i for backward compability */
@@ -78,24 +79,6 @@ static struct long_options l_opts[] = {
*
* Comments:
*
- * Modifications:
- * July 2004: Introduced the extra EC or NN option for SZIP
- * October 2006: Added a new switch -n, that allows to write the dataset
- * using a native type. The default to write is the file type.
- *
- * Modification:
- * Peter Cao, June 13, 2007
- * Add "-L, --latest" option to pack a file with the latest file format
- * PVN, November 19, 2007
- * adopted the syntax h5repack [OPTIONS] file1 file2
- * PVN, November 28, 2007
- * added support for multiple global filters
- * PVN, May 16, 2008
- * added backward compatibility for -i infile -o outfile
- * PVN, August 20, 2008
- * add a user block to repacked file (switches -u -b)
- * PVN, August 28, 2008
- * add options to set alignment (H5Pset_alignment) (switches -t -a)
*-------------------------------------------------------------------------
*/
int main(int argc, const char **argv)
@@ -115,7 +98,7 @@ int main(int argc, const char **argv)
HDexit(EXIT_FAILURE);
/* initialize options */
- h5repack_init(&options, 0, 0, (hsize_t)0);
+ h5repack_init(&options, 0, H5F_FILE_SPACE_DEFAULT, (hsize_t)0);
parse_command_line(argc, argv, &options);
@@ -187,6 +170,7 @@ static void usage(const char *prog)
printf(" -e E, --file=E Name of file E with the -f and -l options\n");
printf(" -u U, --ublock=U Name of file U with user block data to be added\n");
printf(" -b B, --block=B Size of user block to be added\n");
+ printf(" -M A, --metadata_block_size=A Metadata block size for H5Pset_meta_block_size\n");
printf(" -t T, --threshold=T Threshold value for H5Pset_alignment\n");
printf(" -a A, --alignment=A Alignment value for H5Pset_alignment\n");
printf(" -f FILT, --filter=FILT Filter type\n");
@@ -428,7 +412,6 @@ void parse_command_line(int argc, const char **argv, pack_opt_t* options)
break;
-
case 'u':
options->ublock_filename = opt_arg;
@@ -439,6 +422,11 @@ void parse_command_line(int argc, const char **argv, pack_opt_t* options)
options->ublock_size = (hsize_t)HDatol( opt_arg );
break;
+ case 'M':
+
+ options->meta_block_size = (hsize_t)HDatol( opt_arg );
+ break;
+
case 't':
options->threshold = (hsize_t)HDatol( opt_arg );
@@ -455,7 +443,7 @@ void parse_command_line(int argc, const char **argv, pack_opt_t* options)
break;
case 'S':
- {
+ {
char strategy[MAX_NC_NAME];
HDstrcpy(strategy, opt_arg);
@@ -472,7 +460,7 @@ void parse_command_line(int argc, const char **argv, pack_opt_t* options)
HDexit(EXIT_FAILURE);
}
break;
- }
+ }
case 'T':
diff --git a/tools/h5repack/h5repacktst.c b/tools/h5repack/h5repacktst.c
index 17a6190..6b15f0a 100644
--- a/tools/h5repack/h5repacktst.c
+++ b/tools/h5repack/h5repacktst.c
@@ -78,7 +78,6 @@
#define FNAME17OUT "h5repack_named_dtypes_out.h5"
#define FNAME18 "h5repack_layout2.h5"
-#define FNAME18OUT "h5repack_layout2_out.h5"
#define FNAME_UB "ublock.bin"
@@ -172,6 +171,8 @@ int main (void)
diff_opt_t diff_options;
hsize_t fs_size = 0; /* free space section threshold */
H5F_file_space_type_t fs_type = H5F_FILE_SPACE_DEFAULT; /* file space handling strategy */
+ h5_stat_t file_stat;
+ h5_stat_size_t fsize1, fsize2; /* file sizes */
#if defined (H5_HAVE_FILTER_SZIP)
int szip_can_encode = 0;
#endif
@@ -1561,6 +1562,50 @@ int main (void)
PASSED();
/*-------------------------------------------------------------------------
+ * test --metadata_block_size option
+ * Also verify that output file using the metadata_block_size option is
+ * larger than the output file one not using it.
+ * FNAME4 is used because it is the same as the test file used for the
+ * shell script version of this test (h5repack.sh).
+ *-------------------------------------------------------------------------
+ */
+ TESTING(" metadata block size option");
+ /* First run without metadata option. No need to verify the correctness */
+ /* since this has been verified by earlier tests. Just record the file */
+ /* size of the output file. */
+ if(h5repack_init(&pack_options, 0, H5F_FILE_SPACE_DEFAULT, (hsize_t)0) < 0)
+ GOERROR;
+ if(h5repack(FNAME4, FNAME4OUT, &pack_options) < 0)
+ GOERROR;
+ if(HDstat(FNAME4OUT, &file_stat) < 0)
+ GOERROR;
+ fsize1 = file_stat.st_size;
+ if(h5repack_end(&pack_options) < 0)
+ GOERROR;
+
+ /* run it again with metadata option */
+ if(h5repack_init(&pack_options, 0, H5F_FILE_SPACE_DEFAULT, (hsize_t)0) < 0)
+ GOERROR;
+ pack_options.meta_block_size = 8192;
+ if(h5repack(FNAME4, FNAME4OUT, &pack_options) < 0)
+ GOERROR;
+ if(h5diff(FNAME4, FNAME4OUT, NULL, NULL, &diff_options) > 0)
+ GOERROR;
+ if(h5repack_verify(FNAME4, FNAME4OUT, &pack_options) <= 0)
+ GOERROR;
+ /* record the file size of the output file */
+ if(HDstat(FNAME4OUT, &file_stat) < 0)
+ GOERROR;
+ fsize2 = file_stat.st_size;
+ /* verify second file size is larger than the first one */
+ if(fsize2 <= fsize1)
+ GOERROR;
+ if(h5repack_end(&pack_options) < 0)
+ GOERROR;
+ PASSED();
+
+
+ /*-------------------------------------------------------------------------
* clean temporary test files
*-------------------------------------------------------------------------
*/
@@ -3253,7 +3298,7 @@ make_userblock(void)
/* Initialize userblock data */
for(u = 0; u < USERBLOCK_SIZE; u++)
- ub[u] = 'a' + (u % 26);
+ ub[u] = 'a' + (char)(u % 26);
/* Re-open HDF5 file, as "plain" file */
if((fd = HDopen(FNAME16, O_WRONLY, 0644)) < 0)
@@ -3366,7 +3411,7 @@ make_userblock_file(void)
/* initialize userblock data */
for(u = 0; u < USERBLOCK_SIZE; u++)
- ub[u] = 'a' + (u % 26);
+ ub[u] = 'a' + (char)(u % 26);
/* open file */
if((fd = HDopen(FNAME_UB,O_WRONLY|O_CREAT|O_TRUNC, 0644 )) < 0)
@@ -3842,7 +3887,7 @@ int write_dset_in(hid_t loc_id,
int l;
buf52[i][j].p = malloc((i + 1) * sizeof(int));
- buf52[i][j].len = i + 1;
+ buf52[i][j].len = (size_t)(i + 1);
for(l = 0; l < i + 1; l++)
{
if(make_diffs)
@@ -4063,7 +4108,7 @@ int write_dset_in(hid_t loc_id,
int l;
buf53[i][j][k].p = malloc((i + 1) * sizeof(int));
- buf53[i][j][k].len = i + 1;
+ buf53[i][j][k].len = (size_t)(i + 1);
for(l = 0; l < i + 1; l++)
{
if(make_diffs)
@@ -4854,7 +4899,7 @@ int write_attr_in(hid_t loc_id,
{
int l;
buf52[i][j].p = malloc((i + 1) * sizeof(int));
- buf52[i][j].len = i + 1;
+ buf52[i][j].len = (size_t)(i + 1);
for (l = 0; l < i + 1; l++)
if (make_diffs)((int *)buf52[i][j].p)[l] = 0;
else ((int *)buf52[i][j].p)[l] = n++;
@@ -5320,7 +5365,7 @@ int write_attr_in(hid_t loc_id,
{
int l;
buf53[i][j][k].p = malloc((i + 1) * sizeof(int));
- buf53[i][j][k].len = i + 1;
+ buf53[i][j][k].len = (size_t)i + 1;
for (l = 0; l < i + 1; l++)
if (make_diffs)
{
@@ -5819,7 +5864,7 @@ static herr_t add_attr_with_regref(hid_t file_id, hid_t obj_id)
}
/* select elements space for reference */
- status = H5Sselect_elements (sid_regrefed_dset, H5S_SELECT_SET, 3, coords_regrefed_dset[0]);
+ status = H5Sselect_elements (sid_regrefed_dset, H5S_SELECT_SET, (size_t)3, coords_regrefed_dset[0]);
if (status < 0)
{
fprintf(stderr, "Error: %s %d> H5Sselect_elements failed.\n", FUNC, __LINE__);
@@ -6141,7 +6186,7 @@ static herr_t gen_region_ref(hid_t loc_id)
}
/* select elements space for reference */
- status = H5Sselect_elements (sid_trg, H5S_SELECT_SET, 4, coords[0]);
+ status = H5Sselect_elements (sid_trg, H5S_SELECT_SET, (size_t)4, coords[0]);
if (status < 0)
{
fprintf(stderr, "Error: %s %d> H5Sselect_elements failed.\n", FUNC, __LINE__);
@@ -6508,7 +6553,7 @@ static herr_t make_complex_attr_references(hid_t loc_id)
/*
* create the region reference
*/
- status = H5Sselect_elements (objsid, H5S_SELECT_SET, 4, coords[0]);
+ status = H5Sselect_elements (objsid, H5S_SELECT_SET, (size_t)4, coords[0]);
if (status < 0)
{
fprintf(stderr, "Error: %s %d> H5Sselect_elements failed.\n", FUNC, __LINE__);
@@ -6619,7 +6664,7 @@ static herr_t make_complex_attr_references(hid_t loc_id)
/*
* create region reference
*/
- status = H5Sselect_elements(objsid, H5S_SELECT_SET, 4, coords[0]);
+ status = H5Sselect_elements(objsid, H5S_SELECT_SET, (size_t)4, coords[0]);
if (status < 0)
{
fprintf(stderr, "Error: %s %d> H5Sselect_elements failed.\n", FUNC, __LINE__);
diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c
index e206f4f..99ea688 100644
--- a/tools/h5stat/h5stat.c
+++ b/tools/h5stat/h5stat.c
@@ -99,17 +99,17 @@ typedef struct iter_t {
hsize_t attrs_heap_storage_size; /* fractal heap size for attributes (1.8) */
hsize_t SM_hdr_storage_size; /* header size for SOHM table (1.8) */
hsize_t SM_index_storage_size; /* index (btree & list) size for SOHM table (1.8) */
- hsize_t SM_heap_storage_size; /* fractal heap size for SOHM table (1.8) */
- hsize_t super_size; /* superblock size */
- hsize_t super_ext_size; /* superblock extension size */
- hsize_t ublk_size; /* user block size (if exists) */
- H5F_file_space_type_t fs_strategy; /* File space management strategy */
- hsize_t fs_threshold; /* Free-space section threshold */
- hsize_t free_space; /* amount of freespace in the file */
- hsize_t free_hdr; /* size of free space manager metadata in the file */
+ hsize_t SM_heap_storage_size; /* fractal heap size for SOHM table (1.8) */
+ hsize_t super_size; /* superblock size */
+ hsize_t super_ext_size; /* superblock extension size */
+ hsize_t ublk_size; /* user block size (if exists) */
+ H5F_file_space_type_t fs_strategy; /* File space management strategy */
+ hsize_t fs_threshold; /* Free-space section threshold */
+ hsize_t free_space; /* amount of freespace in the file */
+ hsize_t free_hdr; /* size of free space manager metadata in the file */
unsigned long num_small_sects[SIZE_SMALL_SECTS]; /* Size of small free-space sections */
- unsigned sect_nbins; /* Number of bins for free-space section sizes */
- unsigned long *sect_bins; /* Pointer to array of bins for free-space section sizes */
+ unsigned sect_nbins; /* Number of bins for free-space section sizes */
+ unsigned long *sect_bins; /* Pointer to array of bins for free-space section sizes */
hsize_t datasets_index_storage_size;/* meta size for chunked dataset's indexing type */
hsize_t datasets_heap_storage_size; /* heap size for dataset with external storage */
unsigned long nexternal; /* Number of external files for a dataset */
@@ -120,11 +120,11 @@ typedef struct iter_t {
static int display_all = TRUE;
/* Enable the printing of selected statistics */
-static int display_file = FALSE; /* display file information */
-static int display_group = FALSE; /* display groups information */
-static int display_dset = FALSE; /* display datasets information */
+static int display_file = FALSE; /* display file information */
+static int display_group = FALSE; /* display groups information */
+static int display_dset = FALSE; /* display datasets information */
static int display_dset_dtype_meta = FALSE; /* display datasets' datatype information */
-static int display_attr = FALSE; /* display attributes information */
+static int display_attr = FALSE; /* display attributes information */
static int display_free_sections = FALSE; /* display free space information */
static int display_summary = FALSE; /* display summary of file space information */
@@ -283,7 +283,7 @@ ceil_log10(unsigned long x)
} /* end while */
return(ret);
-}
+} /* ceil_log10() */
/*-------------------------------------------------------------------------
@@ -481,7 +481,7 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
/* Object header's total size for H5D_COMPACT layout includes raw data size */
/* "storage" also includes H5D_COMPACT raw data size */
if(lout == H5D_COMPACT)
- iter->dset_ohdr_info.total_size -= storage;
+ iter->dset_ohdr_info.total_size -= storage;
/* Track the layout type for dataset */
(iter->dset_layouts[lout])++;
@@ -495,7 +495,7 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
iter->nexternal += (unsigned long)num_ext;
iter->dset_external_storage_size += (unsigned long)storage;
} else
- iter->dset_storage_size += storage;
+ iter->dset_storage_size += storage;
/* Gather dataspace statistics */
sid = H5Dget_space(did);
@@ -602,6 +602,7 @@ dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
return 0;
} /* end dataset_stats() */
+
/*-------------------------------------------------------------------------
* Function: datatype_stats
*
@@ -791,11 +792,6 @@ freespace_stats(hid_t fid, iter_t *iter)
* Programmer: Elena Pourmal
* Saturday, August 12, 2006
*
- * Modifications:
- * Vailin Choi; October 2009
- * Turn on display_group_metadata, display_dset_metadata
- * Add 'S' & 's' for printing free space info (previous checkin)
- *
*-------------------------------------------------------------------------
*/
static struct handler_t *
@@ -812,103 +808,103 @@ parse_command_line(int argc, const char *argv[])
/* parse command line options */
while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
- switch ((char) opt) {
- case 'h':
- usage(h5tools_getprogname());
- h5tools_setstatus(EXIT_SUCCESS);
- if (hand) {
- for (i = 0; i < argc; i++)
- if(hand[i].obj) {
- free(hand[i].obj);
- hand[i].obj=NULL;
- }
-
- free(hand);
- hand = NULL;
- }
- goto done;
- break;
+ switch ((char)opt) {
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ if (hand) {
+ for (i = 0; i < argc; i++)
+ if(hand[i].obj) {
+ free(hand[i].obj);
+ hand[i].obj=NULL;
+ }
+
+ free(hand);
+ hand = NULL;
+ }
+ goto done;
+ break;
- case 'V':
- print_version(h5tools_getprogname());
- h5tools_setstatus(EXIT_SUCCESS);
- if (hand) {
- for (i = 0; i < argc; i++)
- if(hand[i].obj) {
- free(hand[i].obj);
- hand[i].obj=NULL;
- }
-
- free(hand);
- hand = NULL;
- }
- goto done;
- break;
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ if (hand) {
+ for (i = 0; i < argc; i++)
+ if(hand[i].obj) {
+ free(hand[i].obj);
+ hand[i].obj=NULL;
+ }
+
+ free(hand);
+ hand = NULL;
+ }
+ goto done;
+ break;
- case 'F':
- display_all = FALSE;
- display_file_metadata = TRUE;
- break;
+ case 'F':
+ display_all = FALSE;
+ display_file_metadata = TRUE;
+ break;
- case 'f':
- display_all = FALSE;
- display_file = TRUE;
- break;
+ case 'f':
+ display_all = FALSE;
+ display_file = TRUE;
+ break;
- case 'G':
- display_all = FALSE;
- display_group_metadata = TRUE;
- break;
+ case 'G':
+ display_all = FALSE;
+ display_group_metadata = TRUE;
+ break;
- case 'g':
- display_all = FALSE;
- display_group = TRUE;
- break;
+ case 'g':
+ display_all = FALSE;
+ display_group = TRUE;
+ break;
- case 'D':
- display_all = FALSE;
- display_dset_metadata = TRUE;
- break;
+ case 'D':
+ display_all = FALSE;
+ display_dset_metadata = TRUE;
+ break;
- case 'd':
- display_all = FALSE;
- display_dset = TRUE;
- break;
+ case 'd':
+ display_all = FALSE;
+ display_dset = TRUE;
+ break;
- case 'T':
- display_all = FALSE;
- display_dset_dtype_meta = TRUE;
- break;
+ case 'T':
+ display_all = FALSE;
+ display_dset_dtype_meta = TRUE;
+ break;
- case 'A':
- display_all = FALSE;
- display_attr = TRUE;
- break;
+ case 'A':
+ display_all = FALSE;
+ display_attr = TRUE;
+ break;
- case 's':
- display_all = FALSE;
- display_free_sections = TRUE;
- break;
+ case 's':
+ display_all = FALSE;
+ display_free_sections = TRUE;
+ break;
- case 'S':
- display_all = FALSE;
- display_summary = TRUE;
- break;
+ case 'S':
+ display_all = FALSE;
+ display_summary = TRUE;
+ break;
- case 'O':
- display_all = FALSE;
- display_object = TRUE;
- for (i = 0; i < argc; i++)
- if (!hand[i].obj) {
- hand[i].obj = HDstrdup(opt_arg);
- break;
- } /* end if */
- break;
+ case 'O':
+ display_all = FALSE;
+ display_object = TRUE;
+ for(i = 0; i < argc; i++)
+ if(!hand[i].obj) {
+ hand[i].obj = HDstrdup(opt_arg);
+ break;
+ } /* end if */
+ break;
- default:
- usage(h5tools_getprogname());
- h5tools_setstatus(EXIT_FAILURE);
- goto error;
+ default:
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
} /* end switch */
} /* end while */
@@ -964,7 +960,7 @@ iter_init(iter_t *iter, hid_t fid)
iter->fid = fid;
return 0;
-}
+} /* iter_init() */
/*-------------------------------------------------------------------------
@@ -1174,7 +1170,7 @@ print_group_metadata(const iter_t *iter)
printf("File space information for groups' metadata (in bytes):\n");
HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
- iter->group_ohdr_info.total_size, iter->group_ohdr_info.free_size);
+ iter->group_ohdr_info.total_size, iter->group_ohdr_info.free_size);
HDfprintf(stdout, "\tB-tree/List: %Hu\n", iter->groups_btree_storage_size);
HDfprintf(stdout, "\tHeap: %Hu\n", iter->groups_heap_storage_size);
@@ -1195,8 +1191,6 @@ print_group_metadata(const iter_t *iter)
* Programmer: Elena Pourmal
* Saturday, August 12, 2006
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1292,10 +1286,10 @@ print_dset_metadata(const iter_t *iter)
printf("File space information for datasets' metadata (in bytes):\n");
HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
- iter->dset_ohdr_info.total_size, iter->dset_ohdr_info.free_size);
+ iter->dset_ohdr_info.total_size, iter->dset_ohdr_info.free_size);
HDfprintf(stdout, "\tIndex for Chunked datasets: %Hu\n",
- iter->datasets_index_storage_size);
+ iter->datasets_index_storage_size);
HDfprintf(stdout, "\tHeap: %Hu\n", iter->datasets_heap_storage_size);
return 0;
@@ -1311,11 +1305,7 @@ print_dset_metadata(const iter_t *iter)
*
* Failure: Never fails
*
- * Programmer:
- *
- * Modifications:
- * Vailin Choi; October 2009
- * Moved from print_dataset_info()
+ * Programmer: Vailin Choi; October 2009
*
*-------------------------------------------------------------------------
*/
@@ -1327,21 +1317,21 @@ print_dset_dtype_meta(const iter_t *iter)
unsigned u; /* Local index variable */
if(iter->dset_ntypes) {
- printf("Dataset datatype information:\n");
- printf("\t# of unique datatypes used by datasets: %lu\n", iter->dset_ntypes);
- total = 0;
- for(u = 0; u < iter->dset_ntypes; u++) {
- H5Tencode(iter->dset_type_info[u].tid, NULL, &dtype_size);
- printf("\tDataset datatype #%u:\n", u);
- printf("\t\tCount (total/named) = (%lu/%lu)\n",
- iter->dset_type_info[u].count, iter->dset_type_info[u].named);
- printf("\t\tSize (desc./elmt) = (%lu/%lu)\n", (unsigned long)dtype_size,
- (unsigned long)H5Tget_size(iter->dset_type_info[u].tid));
- H5Tclose(iter->dset_type_info[u].tid);
- total += iter->dset_type_info[u].count;
- } /* end for */
- printf("\tTotal dataset datatype count: %lu\n", total);
- }
+ printf("Dataset datatype information:\n");
+ printf("\t# of unique datatypes used by datasets: %lu\n", iter->dset_ntypes);
+ total = 0;
+ for(u = 0; u < iter->dset_ntypes; u++) {
+ H5Tencode(iter->dset_type_info[u].tid, NULL, &dtype_size);
+ printf("\tDataset datatype #%u:\n", u);
+ printf("\t\tCount (total/named) = (%lu/%lu)\n",
+ iter->dset_type_info[u].count, iter->dset_type_info[u].named);
+ printf("\t\tSize (desc./elmt) = (%lu/%lu)\n", (unsigned long)dtype_size,
+ (unsigned long)H5Tget_size(iter->dset_type_info[u].tid));
+ H5Tclose(iter->dset_type_info[u].tid);
+ total += iter->dset_type_info[u].count;
+ } /* end for */
+ printf("\tTotal dataset datatype count: %lu\n", total);
+ } /* end if */
return 0;
} /* print_dset_dtype_meta() */
@@ -1446,7 +1436,7 @@ print_freespace_info(const iter_t *iter)
return 0;
} /* print_freespace_info() */
-
+
/*-------------------------------------------------------------------------
* Function: print_storage_summary
*
@@ -1492,7 +1482,7 @@ print_storage_summary(const iter_t *iter)
HDfprintf(stdout, " Amount/Percent of tracked free space: %Hu bytes/%3.1f%\n",
iter->free_space, percent);
- if(iter->filesize < (total_meta+iter->dset_storage_size+iter->free_space)) {
+ if(iter->filesize < (total_meta + iter->dset_storage_size + iter->free_space)) {
unaccount = (total_meta + iter->dset_storage_size + iter->free_space) - iter->filesize;
HDfprintf(stdout, " ??? File has %Hu more bytes accounted for than its size! ???\n", unaccount);
}
@@ -1501,12 +1491,11 @@ print_storage_summary(const iter_t *iter)
HDfprintf(stdout, " Unaccounted space: %Hu bytes\n", unaccount);
}
- HDfprintf(stdout, "Total space: %Hu bytes\n", total_meta+iter->dset_storage_size+iter->free_space+unaccount);
+ HDfprintf(stdout, "Total space: %Hu bytes\n", total_meta + iter->dset_storage_size + iter->free_space + unaccount);
if(iter->nexternal)
HDfprintf(stdout, "External raw data: %Hu bytes\n", iter->dset_external_storage_size);
-
return 0;
} /* print_storage_summary() */
@@ -1523,11 +1512,6 @@ print_storage_summary(const iter_t *iter)
* Programmer: Elena Pourmal
* Saturday, August 12, 2006
*
- * Modifications:
- * Vailin Choi; October 2009
- * Activate "display_group_metadata", "dislay_dset_metadata" and
- * "display_dset_dtype_info".
- *
*-------------------------------------------------------------------------
*/
static void
@@ -1560,7 +1544,7 @@ print_file_statistics(const iter_t *iter)
if(display_attr) print_attr_info(iter);
if(display_free_sections) print_freespace_info(iter);
if(display_summary) print_storage_summary(iter);
-}
+} /* print_file_statistics() */
/*-------------------------------------------------------------------------
@@ -1583,7 +1567,7 @@ static void
print_object_statistics(const char *name)
{
printf("Object name %s\n", name);
-}
+} /* print_object_statistics() */
/*-------------------------------------------------------------------------
@@ -1609,9 +1593,18 @@ print_statistics(const char *name, const iter_t *iter)
print_object_statistics(name);
else
print_file_statistics(iter);
-}
+} /* print_statistics() */
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Modifications:
+ * 2/2010; Vailin Choi
+ * Get the size of user block
+ *
+ *-------------------------------------------------------------------------
+ */
int
main(int argc, const char *argv[])
{
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c
index cef30dd..306f914 100644
--- a/tools/lib/h5diff.c
+++ b/tools/lib/h5diff.c
@@ -1121,6 +1121,8 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1,
char * obj2_fullpath = NULL;
h5trav_type_t objtype;
diff_args_t argdata;
+ size_t idx1 = 0;
+ size_t idx2 = 0;
/*
@@ -1160,17 +1162,6 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1,
}
}
- /* objects with the same name but different HDF5 types */
- for( i = 0; i < table->nobjs; i++)
- {
- if ( table->objs[i].flags[0] && table->objs[i].flags[1] )
- {
- if ( table->objs[i].type != table->objs[i].type )
- {
- options->contents = 0;
- }
- }
- }
/*-------------------------------------------------------------------------
* do the diff for common objects
@@ -1205,8 +1196,18 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1,
HDstrcpy(obj2_fullpath, grp2_path);
HDstrcat(obj2_fullpath, table->objs[i].name);
+ /* get index to figure out type of the object in file1 */
+ while ( info1->paths[idx1].path &&
+ (HDstrcmp (obj1_fullpath, info1->paths[idx1].path) != 0) )
+ idx1++;
+ /* get index to figure out type of the object in file2 */
+ while ( info2->paths[idx2].path &&
+ (HDstrcmp (obj2_fullpath, info2->paths[idx2].path) != 0) )
+ idx2++;
+
/* Set argdata to pass other args into diff() */
- argdata.type = objtype;
+ argdata.type[0] = info1->paths[idx1].type;
+ argdata.type[1] = info2->paths[idx2].type;
argdata.is_same_trgobj = table->objs[i].is_same_trgobj;
options->cmn_objs = 1;
@@ -1242,7 +1243,8 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1,
HDstrcpy(args.name1, obj1_fullpath);
HDstrcpy(args.name2, obj2_fullpath);
args.options = *options;
- args.argdata.type = objtype;
+ args.argdata.type[0] = info1->paths[idx1].type;
+ args.argdata.type[1] = info2->paths[idx2].type;
args.argdata.is_same_trgobj = table->objs[i].is_same_trgobj;
h5diffdebug2("busyTasks=%d\n", busyTasks);
@@ -1576,176 +1578,9 @@ hsize_t diff_compare(hid_t file1_id,
obj1type = info1->paths[i].type;
obj2type = info2->paths[j].type;
- /*-----------------------------------------------------------------
- * follow link option, compare with target object
- */
- if (options->follow_links)
- {
- /* pass how to handle printing warning to linkinfo option */
- if(print_warn(options))
- linkinfo1.opt.msg_mode = linkinfo2.opt.msg_mode = 1;
-
- /*------------------------------------------------------------
- * Soft links
- *------------------------------------------------------------*/
-
- /*--------------------------
- * if object1 soft link */
- if (obj1type == H5TRAV_TYPE_LINK)
- {
- /* get type of target object */
- l_ret = H5tools_get_symlink_info(file1_id, obj1name, &linkinfo1, TRUE);
- /* dangling link */
- if (l_ret == 0)
- {
- if (options->no_dangle_links)
- {
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", obj1name);
- options->err_stat = 1;
- goto out;
- }
- else
- is_dangle_link1 = 1;
- }
- /* fail */
- else if(l_ret < 0)
- {
- options->err_stat = 1;
- goto out;
- }
- else /* OK */
- {
- /* target type for diff() */
- obj1type = linkinfo1.trg_type;
- }
- }
-
- /*-----------------------------
- * if object2 is soft link */
- if (obj2type == H5TRAV_TYPE_LINK)
- {
- /* get type target object */
- l_ret = H5tools_get_symlink_info(file2_id, obj2name, &linkinfo2, TRUE);
- /* dangling link */
- if (l_ret == 0)
- {
- if (options->no_dangle_links)
- {
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", obj2name);
- options->err_stat = 1;
- goto out;
- }
- else
- is_dangle_link2=1;
- }
- /* fail */
- else if(l_ret < 0)
- {
- options->err_stat = 1;
- goto out;
- }
- else /* OK */
- {
- /* target type for diff() */
- obj2type = linkinfo2.trg_type;
- }
- }
-
- /*------------------------------------------------------------
- * External links
- *------------------------------------------------------------*/
-
- /*--------------------------------
- * if object1 is external link */
- if (obj1type == H5TRAV_TYPE_UDLINK)
- {
- /* get type and name of target object */
- l_ret = H5tools_get_symlink_info(file1_id, obj1name, &linkinfo1, TRUE);
- /* dangling link */
- if (l_ret == 0)
- {
- if (options->no_dangle_links)
- {
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", obj1name);
- options->err_stat = 1;
- goto out;
- }
- else
- is_dangle_link1 = 1;
- }
- /* fail */
- else if(l_ret < 0)
- {
- options->err_stat = 1;
- goto out;
- }
- else /* OK */
- {
- /* for external link */
- if(linkinfo1.linfo.type == H5L_TYPE_EXTERNAL)
- obj1type = linkinfo1.trg_type;
- }
- }
-
- /*--------------------------------
- * if object2 is external link */
- if (obj2type == H5TRAV_TYPE_UDLINK)
- {
- /* get type and name of target object */
- l_ret = H5tools_get_symlink_info(file2_id, obj2name, &linkinfo2, TRUE);
- /* dangling link */
- if (l_ret == 0)
- {
- if (options->no_dangle_links)
- {
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", obj2name);
- options->err_stat = 1;
- goto out;
- }
- else
- is_dangle_link2 = 1;
- }
- /* fail */
- else if(l_ret < 0)
- {
- options->err_stat = 1;
- goto out;
- }
- else /* OK */
- {
- /* for external link */
- if(linkinfo2.linfo.type == H5L_TYPE_EXTERNAL)
- obj2type = linkinfo2.trg_type;
- }
- }
- /* found dangling link */
- if (is_dangle_link1 || is_dangle_link2)
- goto out;
- } /* end of follow_links */
-
- /* objects are not the same type */
- if (obj1type != obj2type)
- {
- if (options->m_verbose||options->m_list_not_cmp)
- {
- parallel_print("<%s> is of type %s and <%s> is of type %s\n",
- obj1name, get_type(obj1type),
- obj2name, get_type(obj2type));
- }
- options->not_cmp=1;
- goto out;
- }
-
/* Set argdata to pass other args into diff() */
- argdata.type = obj1type;
+ argdata.type[0] = obj1type;
+ argdata.type[1] = obj2type;
argdata.is_same_trgobj = 0;
nfound = diff(file1_id, obj1name,
@@ -1806,7 +1641,8 @@ out:
* Return: Number of differences found
*
* Programmer: Jonathan Kim
- * - add following links feature (Feb 11,2010)
+ * - Move follow symlinks code toward top. (March 2812)
+ * - Add following symlinks feature (Feb 11,2010)
* - Change to use diff_args_t to pass the rest of args.
* Passing through it instead of individual args provides smoother
* extensibility through its members along with MPI code update for ph5diff
@@ -1834,6 +1670,7 @@ hsize_t diff(hid_t file1_id,
int is_dangle_link2 = 0;
int is_hard_link = 0;
hsize_t nfound = 0;
+ h5trav_type_t object_type;
/* to get link info */
@@ -1848,52 +1685,86 @@ hsize_t diff(hid_t file1_id,
if(print_warn(options))
linkinfo1.opt.msg_mode = linkinfo2.opt.msg_mode = 1;
- /*
- * Get target object info for obj1 and obj2 and check dangling links.
- * (for hard-linked-objects, because diff() only get the obj1's type,
- * so obj2's type should be check here when diff() is called from
- * diff_match() for same-named objects with dangling link only one side.)
- */
-
- /* target object1 - get type and name */
- ret = H5tools_get_symlink_info(file1_id, path1, &linkinfo1, TRUE);
- /* dangling link */
- if (ret == 0)
+ /* for symbolic links, take care follow symlink and no dangling link
+ * options */
+ if (argdata->type[0] == H5TRAV_TYPE_LINK ||
+ argdata->type[0] == H5TRAV_TYPE_UDLINK ||
+ argdata->type[1] == H5TRAV_TYPE_LINK ||
+ argdata->type[1] == H5TRAV_TYPE_UDLINK )
{
- if (options->no_dangle_links)
+ /*
+ * check dangling links for path1 and path2
+ */
+
+ /* target object1 - get type and name */
+ ret = H5tools_get_symlink_info(file1_id, path1, &linkinfo1, TRUE);
+ /* dangling link */
+ if (ret == 0)
{
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", path1);
- goto out;
+ if (options->no_dangle_links)
+ {
+ /* gangling link is error */
+ if(options->m_verbose)
+ parallel_print("Warning: <%s> is a dangling link.\n", path1);
+ goto out;
+ }
+ else
+ is_dangle_link1 = 1;
}
- else
- is_dangle_link1 = 1;
- }
- else if (ret < 0)
- goto out;
+ else if (ret < 0)
+ goto out;
- /* target object2 - get type and name */
- ret = H5tools_get_symlink_info(file2_id, path2, &linkinfo2, TRUE);
- /* dangling link */
- if (ret == 0)
- {
- if (options->no_dangle_links)
+ /* target object2 - get type and name */
+ ret = H5tools_get_symlink_info(file2_id, path2, &linkinfo2, TRUE);
+ /* dangling link */
+ if (ret == 0)
{
- /* gangling link is error */
- if(options->m_verbose)
- parallel_print("Warning: <%s> is a dangling link.\n", path2);
+ if (options->no_dangle_links)
+ {
+ /* gangling link is error */
+ if(options->m_verbose)
+ parallel_print("Warning: <%s> is a dangling link.\n", path2);
+ goto out;
+ }
+ else
+ is_dangle_link2 = 1;
+ }
+ else if (ret < 0)
goto out;
+
+ /* found dangling link */
+ if (is_dangle_link1 || is_dangle_link2)
+ goto out2;
+
+ /* follow symbolic link option */
+ if (options->follow_links)
+ {
+ if (linkinfo1.linfo.type == H5L_TYPE_SOFT ||
+ linkinfo1.linfo.type == H5L_TYPE_EXTERNAL)
+ argdata->type[0] = linkinfo1.trg_type;
+
+ if (linkinfo2.linfo.type == H5L_TYPE_SOFT ||
+ linkinfo2.linfo.type == H5L_TYPE_EXTERNAL)
+ argdata->type[1] = linkinfo2.trg_type;
}
- else
- is_dangle_link2 = 1;
}
- else if (ret < 0)
- goto out;
-
- /* found dangling link */
- if (is_dangle_link1 || is_dangle_link2)
+ /* if objects are not the same type */
+ if (argdata->type[0] != argdata->type[1])
+ {
+ if (options->m_verbose||options->m_list_not_cmp)
+ {
+ parallel_print("Not comparable: <%s> is of type %s and <%s> is of type %s\n",
+ path1, get_type(argdata->type[0]),
+ path2, get_type(argdata->type[1]));
+ }
+ options->not_cmp=1;
+ /* TODO: will need to update non-comparable is different
+ * options->contents = 0;
+ */
goto out2;
+ }
+ else /* now both object types are same */
+ object_type = argdata->type[0];
/*
* If both points to the same target object, skip comparing details inside
@@ -1903,17 +1774,17 @@ hsize_t diff(hid_t file1_id,
*
* Perform this to match the outputs as bypassing.
*/
- is_hard_link = (argdata->type == H5TRAV_TYPE_DATASET ||
- argdata->type == H5TRAV_TYPE_NAMED_DATATYPE ||
- argdata->type == H5TRAV_TYPE_GROUP);
- if (options->follow_links || is_hard_link)
+ if (argdata->is_same_trgobj)
{
- if (argdata->is_same_trgobj)
+ is_hard_link = (object_type == H5TRAV_TYPE_DATASET ||
+ object_type == H5TRAV_TYPE_NAMED_DATATYPE ||
+ object_type == H5TRAV_TYPE_GROUP);
+ if (options->follow_links || is_hard_link)
{
/* print information is only verbose option is used */
if(options->m_verbose || options->m_report)
{
- switch(argdata->type)
+ switch(object_type)
{
case H5TRAV_TYPE_DATASET:
do_print_objname("dataset", path1, path2, options);
@@ -1935,7 +1806,7 @@ hsize_t diff(hid_t file1_id,
break;
default:
parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n",
- path1, path2, get_type(argdata->type) );
+ path1, path2, get_type(object_type) );
options->not_cmp = 1;
break;
} /* switch(type)*/
@@ -1943,11 +1814,12 @@ hsize_t diff(hid_t file1_id,
print_found(nfound);
} /* if(options->m_verbose || options->m_report) */
+ /* exact same, so comparison is done */
goto out2;
}
}
- switch(argdata->type)
+ switch(object_type)
{
/*----------------------------------------------------------------------
* H5TRAV_TYPE_DATASET
@@ -2064,30 +1936,6 @@ hsize_t diff(hid_t file1_id,
if(print_objname(options, nfound))
do_print_objname("link", path1, path2, options);
- if (options->follow_links)
- {
- /* objects are not the same type */
- if (linkinfo1.trg_type != linkinfo2.trg_type)
- {
- if (options->m_verbose||options->m_list_not_cmp)
- {
- parallel_print("<%s> is of type %s and <%s> is of type %s\n", path1, get_type(linkinfo1.trg_type), path2, get_type(linkinfo2.trg_type));
- }
- options->not_cmp=1;
- goto out;
- }
-
- /* Renew type in argdata to pass into diff().
- * For recursive call, argdata.is_same_trgobj is already
- * set from initial call, so don't reset here */
- argdata->type = linkinfo1.trg_type;
-
- /* call self to compare target object */
- nfound += diff(file1_id, path1,
- file2_id, path2,
- options, argdata);
- }
-
/* always print the number of differences found in verbose mode */
if(options->m_verbose)
print_found(nfound);
@@ -2121,28 +1969,6 @@ hsize_t diff(hid_t file1_id,
if(print_objname(options, nfound))
do_print_objname("external link", path1, path2, options);
- if (options->follow_links)
- {
- /* objects are not the same type */
- if (linkinfo1.trg_type != linkinfo2.trg_type)
- {
- if (options->m_verbose||options->m_list_not_cmp)
- {
- parallel_print("<%s> is of type %s and <%s> is of type %s\n", path1, get_type(linkinfo1.trg_type), path2, get_type(linkinfo2.trg_type));
- }
- options->not_cmp=1;
- goto out;
- }
-
- /* Renew type in argdata to pass into diff().
- * For recursive call, argdata.is_same_trgobj is already
- * set from initial call, so don't reset here */
- argdata->type = linkinfo1.trg_type;
-
- nfound = diff(file1_id, path1,
- file2_id, path2,
- options, argdata);
- }
} /* end if */
else
{
@@ -2172,7 +1998,7 @@ hsize_t diff(hid_t file1_id,
default:
if(options->m_verbose)
parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n",
- path1, path2, get_type(argdata->type) );
+ path1, path2, get_type(object_type) );
options->not_cmp = 1;
break;
}
diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h
index 1ff4402..6985b68 100644
--- a/tools/lib/h5diff.h
+++ b/tools/lib/h5diff.h
@@ -28,7 +28,7 @@
* as it doesn't require interface change.
*------------------------------------------------------------------------*/
typedef struct {
- h5trav_type_t type;
+ h5trav_type_t type[2];
hbool_t is_same_trgobj;
} diff_args_t;
/*-------------------------------------------------------------------------
diff --git a/tools/misc/h5cc.in b/tools/misc/h5cc.in
index a1421a2..233c80a 100755..100644
--- a/tools/misc/h5cc.in
+++ b/tools/misc/h5cc.in
@@ -220,7 +220,7 @@ for arg in $@ ; do
get_output_file="yes"
fi
;;
- -E|-M)
+ -E|-M|-MT)
allargs="$allargs $arg"
compile_args="$compile_args $arg"
dash_c="yes"
diff --git a/tools/misc/h5redeploy.in b/tools/misc/h5redeploy.in
index ae79b70..ae79b70 100755..100644
--- a/tools/misc/h5redeploy.in
+++ b/tools/misc/h5redeploy.in
diff --git a/vms/COPYING b/vms/COPYING
index 6903daf..6903daf 100755..100644
--- a/vms/COPYING
+++ b/vms/COPYING
diff --git a/vms/src/h5pubconf.h b/vms/src/h5pubconf.h
index 2df95ef..b4f9d19 100644
--- a/vms/src/h5pubconf.h
+++ b/vms/src/h5pubconf.h
@@ -505,7 +505,7 @@
#define H5_PACKAGE_NAME "HDF5"
/* Define to the full name and version of this package. */
-#define H5_PACKAGE_STRING "HDF5 1.9.112"
+#define H5_PACKAGE_STRING "HDF5 1.9.114"
/* Define to the one symbol short name of this package. */
#define H5_PACKAGE_TARNAME "hdf5"
@@ -514,7 +514,7 @@
#define H5_PACKAGE_URL ""
/* Define to the version of this package. */
-#define H5_PACKAGE_VERSION "1.9.112"
+#define H5_PACKAGE_VERSION "1.9.114"
/* Width for printf() for type `long long' or `__int64', use `ll' */
#define H5_PRINTF_LL_WIDTH "ll"
@@ -677,7 +677,7 @@
/* #undef H5_USING_MEMCHECKER */
/* Version number of package */
-#define H5_VERSION "1.9.112"
+#define H5_VERSION "1.9.114"
/* Define if vsnprintf() returns the correct value for formatted strings that
don't fit into size allowed */
diff --git a/windows/COPYING b/windows/COPYING
index 6903daf..6903daf 100755..100644
--- a/windows/COPYING
+++ b/windows/COPYING
diff --git a/windows/examples/testExamples_exp_output.txt b/windows/examples/testExamples_exp_output.txt
index b57688f..b57688f 100755..100644
--- a/windows/examples/testExamples_exp_output.txt
+++ b/windows/examples/testExamples_exp_output.txt
diff --git a/windows/src/H5pubconf.h b/windows/src/H5pubconf.h
index 7a681fe..4936e3a 100644
--- a/windows/src/H5pubconf.h
+++ b/windows/src/H5pubconf.h
@@ -530,7 +530,7 @@
#define H5_PACKAGE_NAME "HDF5"
/* Define to the full name and version of this package. */
-#define H5_PACKAGE_STRING "HDF5 1.9.112"
+#define H5_PACKAGE_STRING "HDF5 1.9.114"
/* Define to the one symbol short name of this package. */
#define H5_PACKAGE_TARNAME "hdf5"
@@ -539,7 +539,7 @@
#define H5_PACKAGE_URL ""
/* Define to the version of this package. */
-#define H5_PACKAGE_VERSION "1.9.112"
+#define H5_PACKAGE_VERSION "1.9.114"
/* Width for printf() for type `long long' or `__int64', use `ll' */
#define H5_PRINTF_LL_WIDTH "I64"
@@ -710,7 +710,7 @@
/* #undef H5_USING_MEMCHECKER */
/* Version number of package */
-#define H5_VERSION "1.9.112"
+#define H5_VERSION "1.9.114"
/* Define if vsnprintf() returns the correct value for formatted strings that
don't fit into size allowed */